mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-10 12:39:53 +00:00
Merge branch 'simulationresultinactor' into 'master'
Embed physics simulation results inside of actor class. See merge request OpenMW/openmw!478
This commit is contained in:
commit
327df7457b
@ -76,6 +76,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic
|
|||||||
updateScale();
|
updateScale();
|
||||||
resetPosition();
|
resetPosition();
|
||||||
addCollisionMask(getCollisionMask());
|
addCollisionMask(getCollisionMask());
|
||||||
|
updateCollisionObjectPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
Actor::~Actor()
|
Actor::~Actor()
|
||||||
@ -139,7 +140,9 @@ osg::Vec3f Actor::getWorldPosition() const
|
|||||||
|
|
||||||
void Actor::setSimulationPosition(const osg::Vec3f& position)
|
void Actor::setSimulationPosition(const osg::Vec3f& position)
|
||||||
{
|
{
|
||||||
mSimulationPosition = position;
|
if (!mResetSimulation)
|
||||||
|
mSimulationPosition = position;
|
||||||
|
mResetSimulation = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f Actor::getSimulationPosition() const
|
osg::Vec3f Actor::getSimulationPosition() const
|
||||||
@ -193,9 +196,9 @@ void Actor::resetPosition()
|
|||||||
mPreviousPosition = mWorldPosition;
|
mPreviousPosition = mWorldPosition;
|
||||||
mPosition = mWorldPosition;
|
mPosition = mWorldPosition;
|
||||||
mSimulationPosition = mWorldPosition;
|
mSimulationPosition = mWorldPosition;
|
||||||
updateCollisionObjectPositionUnsafe();
|
|
||||||
mStandingOnPtr = nullptr;
|
mStandingOnPtr = nullptr;
|
||||||
mWorldPositionChanged = false;
|
mWorldPositionChanged = false;
|
||||||
|
mResetSimulation = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f Actor::getPosition() const
|
osg::Vec3f Actor::getPosition() const
|
||||||
|
@ -180,6 +180,7 @@ namespace MWPhysics
|
|||||||
osg::Vec3f mPreviousPosition;
|
osg::Vec3f mPreviousPosition;
|
||||||
osg::Vec3f mPositionOffset;
|
osg::Vec3f mPositionOffset;
|
||||||
bool mWorldPositionChanged;
|
bool mWorldPositionChanged;
|
||||||
|
bool mResetSimulation;
|
||||||
btTransform mLocalTransform;
|
btTransform mLocalTransform;
|
||||||
mutable std::mutex mPositionMutex;
|
mutable std::mutex mPositionMutex;
|
||||||
|
|
||||||
|
@ -204,31 +204,31 @@ namespace MWPhysics
|
|||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
const std::vector<MWWorld::Ptr>& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
||||||
{
|
{
|
||||||
// This function run in the main thread.
|
// This function run in the main thread.
|
||||||
// While the mSimulationMutex is held, background physics threads can't run.
|
// While the mSimulationMutex is held, background physics threads can't run.
|
||||||
|
|
||||||
std::unique_lock lock(mSimulationMutex);
|
std::unique_lock lock(mSimulationMutex);
|
||||||
|
|
||||||
for (auto& data : actorsData)
|
mMovedActors.clear();
|
||||||
data.updatePosition();
|
|
||||||
|
|
||||||
// start by finishing previous background computation
|
// start by finishing previous background computation
|
||||||
if (mNumThreads != 0)
|
if (mNumThreads != 0)
|
||||||
{
|
{
|
||||||
for (auto& data : mActorsFrameData)
|
for (auto& data : mActorsFrameData)
|
||||||
{
|
{
|
||||||
// Ignore actors that were deleted while the background thread was running
|
// Only return actors that are still part of the scene
|
||||||
if (!data.mActor.lock())
|
if (std::any_of(actorsData.begin(), actorsData.end(), [&data](const auto& newFrameData) { return data.mActorRaw->getPtr() == newFrameData.mActorRaw->getPtr(); }))
|
||||||
continue;
|
{
|
||||||
|
updateMechanics(data);
|
||||||
|
|
||||||
updateMechanics(data);
|
// these variables are accessed directly from the main thread, update them here to prevent accessing "too new" values
|
||||||
if (mAdvanceSimulation)
|
if (mAdvanceSimulation)
|
||||||
data.mActorRaw->setStandingOnPtr(data.mStandingOn);
|
data.mActorRaw->setStandingOnPtr(data.mStandingOn);
|
||||||
|
data.mActorRaw->setSimulationPosition(interpolateMovements(data, mTimeAccum, mPhysicsDt));
|
||||||
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
mMovedActors.emplace_back(data.mActorRaw->getPtr());
|
||||||
data.mActorRaw->setSimulationPosition(mMovementResults[data.mPtr]);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mFrameNumber == frameNumber - 1)
|
if (mFrameNumber == frameNumber - 1)
|
||||||
@ -243,6 +243,8 @@ namespace MWPhysics
|
|||||||
}
|
}
|
||||||
|
|
||||||
// init
|
// init
|
||||||
|
for (auto& data : actorsData)
|
||||||
|
data.updatePosition();
|
||||||
mRemainingSteps = numSteps;
|
mRemainingSteps = numSteps;
|
||||||
mTimeAccum = timeAccum;
|
mTimeAccum = timeAccum;
|
||||||
mActorsFrameData = std::move(actorsData);
|
mActorsFrameData = std::move(actorsData);
|
||||||
@ -257,52 +259,28 @@ namespace MWPhysics
|
|||||||
|
|
||||||
if (mNumThreads == 0)
|
if (mNumThreads == 0)
|
||||||
{
|
{
|
||||||
mMovementResults.clear();
|
|
||||||
syncComputation();
|
syncComputation();
|
||||||
|
return mMovedActors;
|
||||||
for (auto& data : mActorsFrameData)
|
|
||||||
{
|
|
||||||
if (mAdvanceSimulation)
|
|
||||||
data.mActorRaw->setStandingOnPtr(data.mStandingOn);
|
|
||||||
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
|
||||||
data.mActorRaw->setSimulationPosition(mMovementResults[data.mPtr]);
|
|
||||||
}
|
|
||||||
return mMovementResults;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove actors that were deleted while the background thread was running
|
|
||||||
for (auto& data : mActorsFrameData)
|
|
||||||
{
|
|
||||||
if (!data.mActor.lock())
|
|
||||||
mMovementResults.erase(data.mPtr);
|
|
||||||
}
|
|
||||||
std::swap(mMovementResults, mPreviousMovementResults);
|
|
||||||
|
|
||||||
// mMovementResults is shared between all workers instance
|
|
||||||
// pre-allocate all nodes so that we don't need synchronization
|
|
||||||
mMovementResults.clear();
|
|
||||||
for (const auto& m : mActorsFrameData)
|
|
||||||
mMovementResults[m.mPtr] = m.mPosition;
|
|
||||||
|
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
mHasJob.notify_all();
|
mHasJob.notify_all();
|
||||||
return mPreviousMovementResults;
|
return mMovedActors;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PtrPositionList& PhysicsTaskScheduler::resetSimulation(const ActorMap& actors)
|
const std::vector<MWWorld::Ptr>& PhysicsTaskScheduler::resetSimulation(const ActorMap& actors)
|
||||||
{
|
{
|
||||||
std::unique_lock lock(mSimulationMutex);
|
std::unique_lock lock(mSimulationMutex);
|
||||||
mMovementResults.clear();
|
mMovedActors.clear();
|
||||||
mPreviousMovementResults.clear();
|
|
||||||
mActorsFrameData.clear();
|
mActorsFrameData.clear();
|
||||||
|
|
||||||
for (const auto& [_, actor] : actors)
|
for (const auto& [_, actor] : actors)
|
||||||
{
|
{
|
||||||
actor->resetPosition();
|
actor->resetPosition();
|
||||||
actor->setStandingOnPtr(nullptr);
|
actor->setSimulationPosition(actor->getWorldPosition()); // resetPosition skip next simulation, now we need to "consume" it
|
||||||
mMovementResults[actor->getPtr()] = actor->getWorldPosition();
|
actor->updateCollisionObjectPosition();
|
||||||
|
mMovedActors.emplace_back(actor->getPtr());
|
||||||
}
|
}
|
||||||
return mMovementResults;
|
return mMovedActors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsTaskScheduler::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
|
void PhysicsTaskScheduler::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
|
||||||
@ -370,18 +348,18 @@ namespace MWPhysics
|
|||||||
mCollisionWorld->removeCollisionObject(collisionObject);
|
mCollisionWorld->removeCollisionObject(collisionObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsTaskScheduler::updateSingleAabb(std::weak_ptr<PtrHolder> ptr)
|
void PhysicsTaskScheduler::updateSingleAabb(std::weak_ptr<PtrHolder> ptr, bool immediate)
|
||||||
{
|
{
|
||||||
if (mDeferAabbUpdate)
|
if (!mDeferAabbUpdate || immediate)
|
||||||
{
|
|
||||||
std::unique_lock lock(mUpdateAabbMutex);
|
|
||||||
mUpdateAabb.insert(std::move(ptr));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
std::unique_lock lock(mCollisionWorldMutex);
|
std::unique_lock lock(mCollisionWorldMutex);
|
||||||
updatePtrAabb(ptr);
|
updatePtrAabb(ptr);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::unique_lock lock(mUpdateAabbMutex);
|
||||||
|
mUpdateAabb.insert(std::move(ptr));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhysicsTaskScheduler::getLineOfSight(const std::weak_ptr<Actor>& actor1, const std::weak_ptr<Actor>& actor2)
|
bool PhysicsTaskScheduler::getLineOfSight(const std::weak_ptr<Actor>& actor1, const std::weak_ptr<Actor>& actor2)
|
||||||
@ -484,7 +462,6 @@ namespace MWPhysics
|
|||||||
{
|
{
|
||||||
auto& actorData = mActorsFrameData[job];
|
auto& actorData = mActorsFrameData[job];
|
||||||
handleFall(actorData, mAdvanceSimulation);
|
handleFall(actorData, mAdvanceSimulation);
|
||||||
mMovementResults[actorData.mPtr] = interpolateMovements(actorData, mTimeAccum, mPhysicsDt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,8 +516,11 @@ namespace MWPhysics
|
|||||||
for (auto& actorData : mActorsFrameData)
|
for (auto& actorData : mActorsFrameData)
|
||||||
{
|
{
|
||||||
handleFall(actorData, mAdvanceSimulation);
|
handleFall(actorData, mAdvanceSimulation);
|
||||||
mMovementResults[actorData.mPtr] = interpolateMovements(actorData, mTimeAccum, mPhysicsDt);
|
actorData.mActorRaw->setSimulationPosition(interpolateMovements(actorData, mTimeAccum, mPhysicsDt));
|
||||||
updateMechanics(actorData);
|
updateMechanics(actorData);
|
||||||
|
mMovedActors.emplace_back(actorData.mActorRaw->getPtr());
|
||||||
|
if (mAdvanceSimulation)
|
||||||
|
actorData.mActorRaw->setStandingOnPtr(actorData.mStandingOn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,9 @@ namespace MWPhysics
|
|||||||
/// @param timeAccum accumulated time from previous run to interpolate movements
|
/// @param timeAccum accumulated time from previous run to interpolate movements
|
||||||
/// @param actorsData per actor data needed to compute new positions
|
/// @param actorsData per actor data needed to compute new positions
|
||||||
/// @return new position of each actor
|
/// @return new position of each actor
|
||||||
const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
const std::vector<MWWorld::Ptr>& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
||||||
|
|
||||||
const PtrPositionList& resetSimulation(const ActorMap& actors);
|
const std::vector<MWWorld::Ptr>& resetSimulation(const ActorMap& actors);
|
||||||
|
|
||||||
// Thread safe wrappers
|
// Thread safe wrappers
|
||||||
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const;
|
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const;
|
||||||
@ -46,7 +46,7 @@ namespace MWPhysics
|
|||||||
void setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask);
|
void setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask);
|
||||||
void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask);
|
void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask);
|
||||||
void removeCollisionObject(btCollisionObject* collisionObject);
|
void removeCollisionObject(btCollisionObject* collisionObject);
|
||||||
void updateSingleAabb(std::weak_ptr<PtrHolder> ptr);
|
void updateSingleAabb(std::weak_ptr<PtrHolder> ptr, bool immediate=false);
|
||||||
bool getLineOfSight(const std::weak_ptr<Actor>& actor1, const std::weak_ptr<Actor>& actor2);
|
bool getLineOfSight(const std::weak_ptr<Actor>& actor1, const std::weak_ptr<Actor>& actor2);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -60,8 +60,7 @@ namespace MWPhysics
|
|||||||
|
|
||||||
std::unique_ptr<WorldFrameData> mWorldFrameData;
|
std::unique_ptr<WorldFrameData> mWorldFrameData;
|
||||||
std::vector<ActorFrameData> mActorsFrameData;
|
std::vector<ActorFrameData> mActorsFrameData;
|
||||||
PtrPositionList mMovementResults;
|
std::vector<MWWorld::Ptr> mMovedActors;
|
||||||
PtrPositionList mPreviousMovementResults;
|
|
||||||
const float mPhysicsDt;
|
const float mPhysicsDt;
|
||||||
float mTimeAccum;
|
float mTimeAccum;
|
||||||
std::shared_ptr<btCollisionWorld> mCollisionWorld;
|
std::shared_ptr<btCollisionWorld> mCollisionWorld;
|
||||||
|
@ -437,7 +437,7 @@ namespace MWPhysics
|
|||||||
ActorMap::iterator found = mActors.find(ptr);
|
ActorMap::iterator found = mActors.find(ptr);
|
||||||
if (found == mActors.end())
|
if (found == mActors.end())
|
||||||
return ptr.getRefData().getPosition().asVec3();
|
return ptr.getRefData().getPosition().asVec3();
|
||||||
found->second->resetPosition();
|
resetPosition(ptr);
|
||||||
return MovementSolver::traceDown(ptr, position, found->second.get(), mCollisionWorld.get(), maxHeight);
|
return MovementSolver::traceDown(ptr, position, found->second.get(), mCollisionWorld.get(), maxHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,6 +647,17 @@ namespace MWPhysics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PhysicsSystem::resetPosition(const MWWorld::ConstPtr &ptr)
|
||||||
|
{
|
||||||
|
ActorMap::iterator foundActor = mActors.find(ptr);
|
||||||
|
if (foundActor != mActors.end())
|
||||||
|
{
|
||||||
|
foundActor->second->resetPosition();
|
||||||
|
mTaskScheduler->updateSingleAabb(foundActor->second, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PhysicsSystem::addActor (const MWWorld::Ptr& ptr, const std::string& mesh)
|
void PhysicsSystem::addActor (const MWWorld::Ptr& ptr, const std::string& mesh)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<const Resource::BulletShape> shape = mShapeManager->getShape(mesh);
|
osg::ref_ptr<const Resource::BulletShape> shape = mShapeManager->getShape(mesh);
|
||||||
@ -683,6 +694,8 @@ namespace MWPhysics
|
|||||||
if (found != mActors.end())
|
if (found != mActors.end())
|
||||||
{
|
{
|
||||||
bool cmode = found->second->getCollisionMode();
|
bool cmode = found->second->getCollisionMode();
|
||||||
|
if (cmode)
|
||||||
|
resetPosition(found->first);
|
||||||
cmode = !cmode;
|
cmode = !cmode;
|
||||||
found->second->enableCollisionMode(cmode);
|
found->second->enableCollisionMode(cmode);
|
||||||
// NB: Collision body isn't disabled for vanilla TCL compatibility
|
// NB: Collision body isn't disabled for vanilla TCL compatibility
|
||||||
@ -711,7 +724,7 @@ namespace MWPhysics
|
|||||||
mMovementQueue.clear();
|
mMovementQueue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
const std::vector<MWWorld::Ptr>& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
||||||
{
|
{
|
||||||
mTimeAccum += dt;
|
mTimeAccum += dt;
|
||||||
|
|
||||||
@ -930,7 +943,6 @@ namespace MWPhysics
|
|||||||
void ActorFrameData::updatePosition()
|
void ActorFrameData::updatePosition()
|
||||||
{
|
{
|
||||||
mActorRaw->updatePosition();
|
mActorRaw->updatePosition();
|
||||||
mOrigin = mActorRaw->getSimulationPosition();
|
|
||||||
mPosition = mActorRaw->getPosition();
|
mPosition = mActorRaw->getPosition();
|
||||||
if (mMoveToWaterSurface)
|
if (mMoveToWaterSurface)
|
||||||
{
|
{
|
||||||
|
@ -50,8 +50,6 @@ class btVector3;
|
|||||||
|
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
using PtrPositionList = std::map<MWWorld::Ptr, osg::Vec3f>;
|
|
||||||
|
|
||||||
class HeightField;
|
class HeightField;
|
||||||
class Object;
|
class Object;
|
||||||
class Actor;
|
class Actor;
|
||||||
@ -99,7 +97,6 @@ namespace MWPhysics
|
|||||||
float mOldHeight;
|
float mOldHeight;
|
||||||
float mFallHeight;
|
float mFallHeight;
|
||||||
osg::Vec3f mMovement;
|
osg::Vec3f mMovement;
|
||||||
osg::Vec3f mOrigin;
|
|
||||||
osg::Vec3f mPosition;
|
osg::Vec3f mPosition;
|
||||||
ESM::Position mRefpos;
|
ESM::Position mRefpos;
|
||||||
};
|
};
|
||||||
@ -147,6 +144,7 @@ namespace MWPhysics
|
|||||||
void updateScale (const MWWorld::Ptr& ptr);
|
void updateScale (const MWWorld::Ptr& ptr);
|
||||||
void updateRotation (const MWWorld::Ptr& ptr);
|
void updateRotation (const MWWorld::Ptr& ptr);
|
||||||
void updatePosition (const MWWorld::Ptr& ptr);
|
void updatePosition (const MWWorld::Ptr& ptr);
|
||||||
|
void resetPosition(const MWWorld::ConstPtr &ptr);
|
||||||
|
|
||||||
void addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject);
|
void addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject);
|
||||||
|
|
||||||
@ -210,7 +208,7 @@ namespace MWPhysics
|
|||||||
void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity);
|
void queueObjectMovement(const MWWorld::Ptr &ptr, const osg::Vec3f &velocity);
|
||||||
|
|
||||||
/// Apply all queued movements, then clear the list.
|
/// Apply all queued movements, then clear the list.
|
||||||
const PtrPositionList& applyQueuedMovement(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
const std::vector<MWWorld::Ptr>& applyQueuedMovement(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
||||||
|
|
||||||
/// Clear the queued movements list without applying.
|
/// Clear the queued movements list without applying.
|
||||||
void clearQueuedMovement();
|
void clearQueuedMovement();
|
||||||
|
@ -1356,12 +1356,7 @@ namespace MWWorld
|
|||||||
}
|
}
|
||||||
|
|
||||||
moveObject(ptr, ptr.getCell(), pos.x(), pos.y(), pos.z());
|
moveObject(ptr, ptr.getCell(), pos.x(), pos.y(), pos.z());
|
||||||
if (ptr.getClass().isActor())
|
mPhysics->resetPosition(ptr);
|
||||||
{
|
|
||||||
MWPhysics::Actor* actor = mPhysics->getActor(ptr);
|
|
||||||
if (actor)
|
|
||||||
actor->resetPosition();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::fixPosition()
|
void World::fixPosition()
|
||||||
@ -1512,16 +1507,26 @@ namespace MWWorld
|
|||||||
mProjectileManager->processHits();
|
mProjectileManager->processHits();
|
||||||
mDiscardMovements = false;
|
mDiscardMovements = false;
|
||||||
|
|
||||||
for(const auto& [actor, position]: results)
|
for(const auto& actor : results)
|
||||||
{
|
{
|
||||||
// Handle player last, in case a cell transition occurs
|
// Handle player last, in case a cell transition occurs
|
||||||
if(actor != getPlayerPtr())
|
if(actor != getPlayerPtr())
|
||||||
|
{
|
||||||
|
auto* physactor = mPhysics->getActor(actor);
|
||||||
|
assert(physactor);
|
||||||
|
const auto position = physactor->getSimulationPosition();
|
||||||
moveObjectImp(actor, position.x(), position.y(), position.z(), false);
|
moveObjectImp(actor, position.x(), position.y(), position.z(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto player = results.find(getPlayerPtr());
|
const auto player = std::find(results.begin(), results.end(), getPlayerPtr());
|
||||||
if (player != results.end())
|
if (player != results.end())
|
||||||
moveObjectImp(player->first, player->second.x(), player->second.y(), player->second.z(), false);
|
{
|
||||||
|
auto* physactor = mPhysics->getActor(*player);
|
||||||
|
assert(physactor);
|
||||||
|
const auto position = physactor->getSimulationPosition();
|
||||||
|
moveObjectImp(*player, position.x(), position.y(), position.z(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::updateNavigator()
|
void World::updateNavigator()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user