Use actor half extent for interior cells

pull/541/head
elsid 6 years ago
parent 346e9e3141
commit ff478aba6d
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40

@ -601,6 +601,8 @@ namespace MWBase
virtual void updateActorPath(const MWWorld::ConstPtr& actor, const std::deque<osg::Vec3f>& path,
const osg::Vec3f& halfExtents, const osg::Vec3f& start, const osg::Vec3f& end) const = 0;
virtual void setNavMeshNumberToRender(const std::size_t value) = 0;
};
}

@ -31,12 +31,13 @@ namespace MWRender
return mEnabled;
}
void NavMesh::update(const DetourNavigator::SharedNavMesh& sharedNavMesh, std::size_t generation,
std::size_t revision, const DetourNavigator::Settings& settings)
void NavMesh::update(const DetourNavigator::SharedNavMesh& sharedNavMesh, const std::size_t id,
const std::size_t generation, const std::size_t revision, const DetourNavigator::Settings& settings)
{
if (!mEnabled || (mGeneration >= generation && mRevision >= revision))
if (!mEnabled || (mId == id && mGeneration >= generation && mRevision >= revision))
return;
mId = id;
mGeneration = generation;
mRevision = revision;
if (mGroup)
@ -49,6 +50,12 @@ namespace MWRender
}
}
void NavMesh::reset()
{
if (mGroup)
mRootNode->removeChild(mGroup);
}
void NavMesh::enable()
{
if (mGroup)
@ -58,8 +65,7 @@ namespace MWRender
void NavMesh::disable()
{
if (mGroup)
mRootNode->removeChild(mGroup);
reset();
mEnabled = false;
}
}

@ -21,9 +21,12 @@ namespace MWRender
bool toggle();
void update(const DetourNavigator::SharedNavMesh& sharedNavMesh, std::size_t generation, std::size_t revision,
void update(const DetourNavigator::SharedNavMesh& sharedNavMesh,
const std::size_t number, const std::size_t generation, const std::size_t revision,
const DetourNavigator::Settings& settings);
void reset();
void enable();
void disable();
@ -31,6 +34,7 @@ namespace MWRender
private:
osg::ref_ptr<osg::Group> mRootNode;
bool mEnabled;
std::size_t mId = std::numeric_limits<std::size_t>::max();
std::size_t mGeneration;
std::size_t mRevision;
osg::ref_ptr<osg::Group> mGroup;

@ -600,12 +600,20 @@ namespace MWRender
}
const auto navMeshes = mNavigator.getNavMeshes();
if (!navMeshes.empty())
auto it = navMeshes.begin();
for (std::size_t i = 0; it != navMeshes.end() && i < mNavMeshNumber; ++i)
++it;
if (it == navMeshes.end())
{
mNavMesh->reset();
}
else
{
try
{
mNavMesh->update(navMeshes.begin()->second->mValue, navMeshes.begin()->second->mGeneration,
navMeshes.begin()->second->mNavMeshRevision, mNavigator.getSettings());
mNavMesh->update(it->second->mValue, mNavMeshNumber, it->second->mGeneration,
it->second->mNavMeshRevision, mNavigator.getSettings());
}
catch (const std::exception& e)
{
@ -1388,4 +1396,9 @@ namespace MWRender
{
mActorsPaths->remove(actor);
}
void RenderingManager::setNavMeshNumber(const std::size_t value)
{
mNavMeshNumber = value;
}
}

@ -228,6 +228,8 @@ namespace MWRender
void removeActorPath(const MWWorld::ConstPtr& actor) const;
void setNavMeshNumber(const std::size_t value);
private:
void updateProjectionMatrix();
void updateTextureFiltering();
@ -254,6 +256,7 @@ namespace MWRender
DetourNavigator::Navigator& mNavigator;
std::unique_ptr<NavMesh> mNavMesh;
std::size_t mNavMeshNumber = 0;
std::unique_ptr<ActorsPaths> mActorsPaths;
std::unique_ptr<Pathgrid> mPathgrid;
std::unique_ptr<Objects> mObjects;

@ -457,5 +457,6 @@ op 0x2000306: OnActivate, explicit
op 0x2000307: ToggleBorders, tb
op 0x2000308: ToggleNavMesh
op 0x2000309: ToggleActorsPaths
op 0x200030a: SetNavMeshNumber
opcodes 0x200030a-0x3ffffff unused
opcodes 0x200030b-0x3ffffff unused

@ -1345,6 +1345,25 @@ namespace MWScript
}
};
class OpSetNavMeshNumberToRender : public Interpreter::Opcode0
{
public:
virtual void execute (Interpreter::Runtime& runtime)
{
const auto navMeshNumber = runtime[0].mInteger;
runtime.pop();
if (navMeshNumber < 0)
{
runtime.getContext().report("Invalid navmesh number: use not less than zero values");
return;
}
MWBase::Environment::get().getWorld()->setNavMeshNumberToRender(static_cast<std::size_t>(navMeshNumber));
}
};
void installOpcodes (Interpreter::Interpreter& interpreter)
{
interpreter.installSegment5 (Compiler::Misc::opcodeXBox, new OpXBox);
@ -1447,6 +1466,7 @@ namespace MWScript
interpreter.installSegment5 (Compiler::Misc::opcodeToggleBorders, new OpToggleBorders);
interpreter.installSegment5 (Compiler::Misc::opcodeToggleNavMesh, new OpToggleNavMesh);
interpreter.installSegment5 (Compiler::Misc::opcodeToggleActorsPaths, new OpToggleActorsPaths);
interpreter.installSegment5 (Compiler::Misc::opcodeSetNavMeshNumberToRender, new OpSetNavMeshNumberToRender);
}
}
}

@ -175,8 +175,10 @@ namespace
}
else if (const auto actor = physics.getActor(ptr))
{
const auto playerHalfExtents = physics.getHalfExtents(MWBase::Environment::get().getWorld()->getPlayerPtr());
navigator.addAgent(playerHalfExtents);
const auto halfExtents = ptr.getCell()->isExterior()
? physics.getHalfExtents(MWBase::Environment::get().getWorld()->getPlayerPtr())
: actor->getHalfExtents();
navigator.addAgent(halfExtents);
}
}
@ -344,7 +346,7 @@ namespace MWWorld
navigator->removeObject(reinterpret_cast<std::size_t>(object));
else if (const auto actor = mPhysics->getActor(ptr))
{
navigator->removeAgent(playerHalfExtents);
navigator->removeAgent(ptr.getCell()->isExterior() ? playerHalfExtents : actor->getHalfExtents());
mRendering.removeActorPath(ptr);
}
mPhysics->remove(ptr);
@ -812,8 +814,10 @@ namespace MWWorld
}
else if (const auto actor = mPhysics->getActor(ptr))
{
const auto playerHalfExtents = mPhysics->getHalfExtents(MWBase::Environment::get().getWorld()->getPlayerPtr());
navigator->removeAgent(playerHalfExtents);
const auto& halfExtents = ptr.getCell()->isExterior()
? mPhysics->getHalfExtents(MWBase::Environment::get().getWorld()->getPlayerPtr())
: actor->getHalfExtents();
navigator->removeAgent(halfExtents);
}
mPhysics->remove(ptr);
mRendering.removeObject (ptr);

@ -3767,4 +3767,9 @@ namespace MWWorld
mRendering->updateActorPath(actor, path, halfExtents, start, end);
}
void World::setNavMeshNumberToRender(const std::size_t value)
{
mRendering->setNavMeshNumber(value);
}
}

@ -703,6 +703,8 @@ namespace MWWorld
void updateActorPath(const MWWorld::ConstPtr& actor, const std::deque<osg::Vec3f>& path,
const osg::Vec3f& halfExtents, const osg::Vec3f& start, const osg::Vec3f& end) const override;
void setNavMeshNumberToRender(const std::size_t value) override;
};
}

@ -322,6 +322,7 @@ namespace Compiler
extensions.registerInstruction ("toggleborders", "", opcodeToggleBorders);
extensions.registerInstruction ("togglenavmesh", "", opcodeToggleNavMesh);
extensions.registerInstruction ("toggleactorspaths", "", opcodeToggleActorsPaths);
extensions.registerInstruction ("setnavmeshnumber", "l", opcodeSetNavMeshNumberToRender);
}
}

@ -298,6 +298,7 @@ namespace Compiler
const int opcodeToggleBorders = 0x2000307;
const int opcodeToggleNavMesh = 0x2000308;
const int opcodeToggleActorsPaths = 0x2000309;
const int opcodeSetNavMeshNumberToRender = 0x200030a;
}
namespace Sky

@ -122,11 +122,16 @@ namespace DetourNavigator
void NavMeshManager::update(osg::Vec3f playerPosition, const osg::Vec3f& agentHalfExtents)
{
const auto playerTile = getTilePosition(mSettings, toNavMeshCoordinates(mSettings, playerPosition));
if (mLastRecastMeshManagerRevision >= mRecastMeshManager.getRevision() && mPlayerTile
&& *mPlayerTile == playerTile)
auto& lastRevision = mLastRecastMeshManagerRevision[agentHalfExtents];
auto lastPlayerTile = mPlayerTile.find(agentHalfExtents);
if (lastRevision >= mRecastMeshManager.getRevision() && lastPlayerTile != mPlayerTile.end()
&& lastPlayerTile->second == playerTile)
return;
mLastRecastMeshManagerRevision = mRecastMeshManager.getRevision();
mPlayerTile = playerTile;
lastRevision = mRecastMeshManager.getRevision();
if (lastPlayerTile == mPlayerTile.end())
lastPlayerTile = mPlayerTile.insert(std::make_pair(agentHalfExtents, playerTile)).first;
else
lastPlayerTile->second = playerTile;
std::map<TilePosition, ChangeType> tilesToPost;
const auto& cached = getCached(agentHalfExtents);
const auto changedTiles = mChangedTiles.find(agentHalfExtents);
@ -163,8 +168,8 @@ namespace DetourNavigator
}
mAsyncNavMeshUpdater.post(agentHalfExtents, cached, playerTile, tilesToPost);
log("cache update posted for agent=", agentHalfExtents,
" playerTile=", *mPlayerTile,
" recastMeshManagerRevision=", mLastRecastMeshManagerRevision,
" playerTile=", lastPlayerTile->second,
" recastMeshManagerRevision=", lastRevision,
" changedTiles=", changedTiles->second.size());
}

@ -58,8 +58,8 @@ namespace DetourNavigator
std::map<osg::Vec3f, std::map<TilePosition, ChangeType>> mChangedTiles;
AsyncNavMeshUpdater mAsyncNavMeshUpdater;
std::size_t mGenerationCounter = 0;
boost::optional<TilePosition> mPlayerTile;
std::size_t mLastRecastMeshManagerRevision = 0;
std::map<osg::Vec3f, TilePosition> mPlayerTile;
std::map<osg::Vec3f, std::size_t> mLastRecastMeshManagerRevision;
void addChangedTiles(const btCollisionShape& shape, const btTransform& transform, const ChangeType changeType);

Loading…
Cancel
Save