mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-01 04:45:36 +00:00
Move the weak_ptr<Actor> outside of ActorFrameData.
This commit is contained in:
parent
f68273c3c0
commit
26d9052b8c
4 changed files with 51 additions and 45 deletions
|
@ -222,7 +222,7 @@ namespace MWPhysics
|
||||||
return std::make_tuple(numSteps, actualDelta);
|
return std::make_tuple(numSteps, actualDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsTaskScheduler::applyQueuedMovements(float & timeAccum, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
void PhysicsTaskScheduler::applyQueuedMovements(float & timeAccum, std::vector<std::weak_ptr<Actor>>&& actors, 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.
|
||||||
|
@ -234,12 +234,12 @@ namespace MWPhysics
|
||||||
// start by finishing previous background computation
|
// start by finishing previous background computation
|
||||||
if (mNumThreads != 0)
|
if (mNumThreads != 0)
|
||||||
{
|
{
|
||||||
for (auto& data : mActorsFrameData)
|
for (size_t i = 0; i < mActors.size(); ++i)
|
||||||
{
|
{
|
||||||
if (auto actor = data.mActor.lock())
|
if (auto actor = mActors[i].lock())
|
||||||
{
|
{
|
||||||
updateMechanics(*actor, data);
|
updateMechanics(*actor, mActorsFrameData[i]);
|
||||||
updateActor(*actor, data, mAdvanceSimulation, mTimeAccum, mPhysicsDt);
|
updateActor(*actor, mActorsFrameData[i], mAdvanceSimulation, mTimeAccum, mPhysicsDt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(mAdvanceSimulation)
|
if(mAdvanceSimulation)
|
||||||
|
@ -251,15 +251,16 @@ namespace MWPhysics
|
||||||
timeAccum -= numSteps*newDelta;
|
timeAccum -= numSteps*newDelta;
|
||||||
|
|
||||||
// init
|
// init
|
||||||
for (auto& data : actorsData)
|
for (size_t i = 0; i < actors.size(); ++i)
|
||||||
{
|
{
|
||||||
assert(data.mActor.lock());
|
assert(actors[i].lock());
|
||||||
data.updatePosition(*data.mActor.lock(), mCollisionWorld);
|
actorsData[i].updatePosition(*actors[i].lock(), mCollisionWorld);
|
||||||
}
|
}
|
||||||
mPrevStepCount = numSteps;
|
mPrevStepCount = numSteps;
|
||||||
mRemainingSteps = numSteps;
|
mRemainingSteps = numSteps;
|
||||||
mTimeAccum = timeAccum;
|
mTimeAccum = timeAccum;
|
||||||
mPhysicsDt = newDelta;
|
mPhysicsDt = newDelta;
|
||||||
|
mActors = std::move(actors);
|
||||||
mActorsFrameData = std::move(actorsData);
|
mActorsFrameData = std::move(actorsData);
|
||||||
mAdvanceSimulation = (mRemainingSteps != 0);
|
mAdvanceSimulation = (mRemainingSteps != 0);
|
||||||
mNewFrame = true;
|
mNewFrame = true;
|
||||||
|
@ -463,7 +464,7 @@ namespace MWPhysics
|
||||||
int job = 0;
|
int job = 0;
|
||||||
while (mRemainingSteps && (job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs)
|
while (mRemainingSteps && (job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs)
|
||||||
{
|
{
|
||||||
if(const auto actor = mActorsFrameData[job].mActor.lock())
|
if(const auto actor = mActors[job].lock())
|
||||||
{
|
{
|
||||||
MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet);
|
MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet);
|
||||||
MovementSolver::move(mActorsFrameData[job], mPhysicsDt, mCollisionWorld, *mWorldFrameData);
|
MovementSolver::move(mActorsFrameData[job], mPhysicsDt, mCollisionWorld, *mWorldFrameData);
|
||||||
|
@ -476,10 +477,9 @@ namespace MWPhysics
|
||||||
{
|
{
|
||||||
while ((job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs)
|
while ((job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs)
|
||||||
{
|
{
|
||||||
if(const auto actor = mActorsFrameData[job].mActor.lock())
|
if(const auto actor = mActors[job].lock())
|
||||||
{
|
{
|
||||||
auto& actorData = mActorsFrameData[job];
|
handleFall(mActorsFrameData[job], mAdvanceSimulation);
|
||||||
handleFall(actorData, mAdvanceSimulation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,14 +491,14 @@ namespace MWPhysics
|
||||||
|
|
||||||
void PhysicsTaskScheduler::updateActorsPositions()
|
void PhysicsTaskScheduler::updateActorsPositions()
|
||||||
{
|
{
|
||||||
for (auto& actorData : mActorsFrameData)
|
for (size_t i = 0; i < mActors.size(); ++i)
|
||||||
{
|
{
|
||||||
if(const auto actor = actorData.mActor.lock())
|
if(const auto actor = mActors[i].lock())
|
||||||
{
|
{
|
||||||
if (actor->setPosition(actorData.mPosition))
|
if (actor->setPosition(mActorsFrameData[i].mPosition))
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(mCollisionWorldMutex);
|
std::scoped_lock lock(mCollisionWorldMutex);
|
||||||
actorData.mPosition = actor->getPosition(); // account for potential position change made by script
|
mActorsFrameData[i].mPosition = actor->getPosition(); // account for potential position change made by script
|
||||||
actor->updateCollisionObjectPosition();
|
actor->updateCollisionObjectPosition();
|
||||||
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
||||||
}
|
}
|
||||||
|
@ -534,13 +534,13 @@ namespace MWPhysics
|
||||||
updateActorsPositions();
|
updateActorsPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& actorData : mActorsFrameData)
|
for (size_t i = 0; i < mActors.size(); ++i)
|
||||||
{
|
{
|
||||||
auto actor = actorData.mActor.lock();
|
auto actor = mActors[i].lock();
|
||||||
assert(actor);
|
assert(actor);
|
||||||
handleFall(actorData, mAdvanceSimulation);
|
handleFall(mActorsFrameData[i], mAdvanceSimulation);
|
||||||
updateMechanics(*actor, actorData);
|
updateMechanics(*actor, mActorsFrameData[i]);
|
||||||
updateActor(*actor, actorData, mAdvanceSimulation, mTimeAccum, mPhysicsDt);
|
updateActor(*actor, mActorsFrameData[i], mAdvanceSimulation, mTimeAccum, mPhysicsDt);
|
||||||
}
|
}
|
||||||
refreshLOSCache();
|
refreshLOSCache();
|
||||||
}
|
}
|
||||||
|
@ -571,11 +571,13 @@ namespace MWPhysics
|
||||||
updateAabbs();
|
updateAabbs();
|
||||||
if (!mRemainingSteps)
|
if (!mRemainingSteps)
|
||||||
return;
|
return;
|
||||||
for (auto& data : mActorsFrameData)
|
for (size_t i = 0; i < mActors.size(); ++i)
|
||||||
if (const auto actor = data.mActor.lock())
|
{
|
||||||
|
if (auto actor = mActors[i].lock())
|
||||||
{
|
{
|
||||||
std::unique_lock lock(mCollisionWorldMutex);
|
std::unique_lock lock(mCollisionWorldMutex);
|
||||||
MovementSolver::unstuck(data, mCollisionWorld);
|
MovementSolver::unstuck(mActorsFrameData[i], mCollisionWorld);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ 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
|
||||||
void applyQueuedMovements(float & timeAccum, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
void applyQueuedMovements(float & timeAccum, std::vector<std::weak_ptr<Actor>>&& actors, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
||||||
|
|
||||||
void resetSimulation(const ActorMap& actors);
|
void resetSimulation(const ActorMap& actors);
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ namespace MWPhysics
|
||||||
void afterPostSim();
|
void afterPostSim();
|
||||||
|
|
||||||
std::unique_ptr<WorldFrameData> mWorldFrameData;
|
std::unique_ptr<WorldFrameData> mWorldFrameData;
|
||||||
|
std::vector<std::weak_ptr<Actor>> mActors;
|
||||||
std::vector<ActorFrameData> mActorsFrameData;
|
std::vector<ActorFrameData> mActorsFrameData;
|
||||||
float mDefaultPhysicsDt;
|
float mDefaultPhysicsDt;
|
||||||
float mPhysicsDt;
|
float mPhysicsDt;
|
||||||
|
|
|
@ -781,10 +781,11 @@ namespace MWPhysics
|
||||||
actor->setVelocity(osg::Vec3f());
|
actor->setVelocity(osg::Vec3f());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ActorFrameData> PhysicsSystem::prepareFrameData(bool willSimulate)
|
std::pair<std::vector<std::weak_ptr<Actor>>, std::vector<ActorFrameData>> PhysicsSystem::prepareFrameData(bool willSimulate)
|
||||||
{
|
{
|
||||||
std::vector<ActorFrameData> actorsFrameData;
|
std::pair<std::vector<std::weak_ptr<Actor>>, std::vector<ActorFrameData>> framedata;
|
||||||
actorsFrameData.reserve(mActors.size());
|
framedata.first.reserve(mActors.size());
|
||||||
|
framedata.second.reserve(mActors.size());
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
for (const auto& [actor, physicActor] : mActors)
|
for (const auto& [actor, physicActor] : mActors)
|
||||||
{
|
{
|
||||||
|
@ -815,13 +816,14 @@ namespace MWPhysics
|
||||||
if (!willSimulate)
|
if (!willSimulate)
|
||||||
standingOn = physicActor->getStandingOnPtr();
|
standingOn = physicActor->getStandingOnPtr();
|
||||||
|
|
||||||
actorsFrameData.emplace_back(physicActor, standingOn, waterCollision, slowFall, waterlevel);
|
framedata.first.emplace_back(physicActor);
|
||||||
|
framedata.second.emplace_back(*physicActor, standingOn, waterCollision, slowFall, waterlevel);
|
||||||
|
|
||||||
// if the simulation will run, a jump request will be fulfilled. Update mechanics accordingly.
|
// if the simulation will run, a jump request will be fulfilled. Update mechanics accordingly.
|
||||||
if (willSimulate)
|
if (willSimulate)
|
||||||
handleJump(ptr);
|
handleJump(ptr);
|
||||||
}
|
}
|
||||||
return actorsFrameData;
|
return framedata;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::stepSimulation(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
void PhysicsSystem::stepSimulation(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
||||||
|
@ -846,8 +848,11 @@ namespace MWPhysics
|
||||||
if (skipSimulation)
|
if (skipSimulation)
|
||||||
mTaskScheduler->resetSimulation(mActors);
|
mTaskScheduler->resetSimulation(mActors);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
auto [actors, framedata] = prepareFrameData(mTimeAccum >= mPhysicsDt);
|
||||||
// modifies mTimeAccum
|
// modifies mTimeAccum
|
||||||
mTaskScheduler->applyQueuedMovements(mTimeAccum, prepareFrameData(mTimeAccum >= mPhysicsDt), frameStart, frameNumber, stats);
|
mTaskScheduler->applyQueuedMovements(mTimeAccum, std::move(actors), std::move(framedata), frameStart, frameNumber, stats);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::moveActors()
|
void PhysicsSystem::moveActors()
|
||||||
|
@ -984,36 +989,35 @@ namespace MWPhysics
|
||||||
mDebugDrawer->addCollision(position, normal);
|
mDebugDrawer->addCollision(position, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActorFrameData::ActorFrameData(const std::shared_ptr<Actor>& actor, const MWWorld::Ptr standingOn,
|
ActorFrameData::ActorFrameData(Actor& actor, const MWWorld::Ptr standingOn,
|
||||||
bool waterCollision, float slowFall, float waterlevel)
|
bool waterCollision, float slowFall, float waterlevel)
|
||||||
: mActor(actor)
|
: mCollisionObject(actor.getCollisionObject())
|
||||||
, mCollisionObject(actor->getCollisionObject())
|
|
||||||
, mStandingOn(standingOn)
|
, mStandingOn(standingOn)
|
||||||
, mWasOnGround(actor->getOnGround())
|
, mWasOnGround(actor.getOnGround())
|
||||||
, mIsOnGround(actor->getOnGround())
|
, mIsOnGround(actor.getOnGround())
|
||||||
, mIsOnSlope(actor->getOnSlope())
|
, mIsOnSlope(actor.getOnSlope())
|
||||||
, mNeedLand(false)
|
, mNeedLand(false)
|
||||||
, mWaterCollision(waterCollision)
|
, mWaterCollision(waterCollision)
|
||||||
, mWalkingOnWater(false)
|
, mWalkingOnWater(false)
|
||||||
, mSkipCollisionDetection(actor->skipCollisions() || !actor->getCollisionMode())
|
, mSkipCollisionDetection(actor.skipCollisions() || !actor.getCollisionMode())
|
||||||
, mWaterlevel(waterlevel)
|
, mWaterlevel(waterlevel)
|
||||||
, mSlowFall(slowFall)
|
, mSlowFall(slowFall)
|
||||||
, mOldHeight(0)
|
, mOldHeight(0)
|
||||||
, mFallHeight(0)
|
, mFallHeight(0)
|
||||||
, mHalfExtentsZ(actor->getHalfExtents().z())
|
, mHalfExtentsZ(actor.getHalfExtents().z())
|
||||||
, mMovement(actor->velocity())
|
, mMovement(actor.velocity())
|
||||||
, mPosition()
|
, mPosition()
|
||||||
, mRotation()
|
, mRotation()
|
||||||
{
|
{
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
const auto ptr = actor->getPtr();
|
const auto ptr = actor.getPtr();
|
||||||
mFlying = world->isFlying(ptr);
|
mFlying = world->isFlying(ptr);
|
||||||
mIsAquatic = ptr.getClass().isPureWaterCreature(ptr);
|
mIsAquatic = ptr.getClass().isPureWaterCreature(ptr);
|
||||||
const auto& stats = ptr.getClass().getCreatureStats(ptr);
|
const auto& stats = ptr.getClass().getCreatureStats(ptr);
|
||||||
const bool godmode = ptr == world->getPlayerConstPtr() && world->getGodModeState();
|
const bool godmode = ptr == world->getPlayerConstPtr() && world->getGodModeState();
|
||||||
mInert = stats.isDead() || (!godmode && stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0);
|
mInert = stats.isDead() || (!godmode && stats.getMagicEffects().get(ESM::MagicEffect::Paralyze).getModifier() > 0);
|
||||||
static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fSwimHeightScale")->mValue.getFloat();
|
static const float fSwimHeightScale = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>().find("fSwimHeightScale")->mValue.getFloat();
|
||||||
mSwimLevel = mWaterlevel - (actor->getRenderingHalfExtents().z() * 2 * fSwimHeightScale);
|
mSwimLevel = mWaterlevel - (actor.getRenderingHalfExtents().z() * 2 * fSwimHeightScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActorFrameData::updatePosition(Actor& actor, btCollisionWorld* world)
|
void ActorFrameData::updatePosition(Actor& actor, btCollisionWorld* world)
|
||||||
|
|
|
@ -78,9 +78,8 @@ namespace MWPhysics
|
||||||
|
|
||||||
struct ActorFrameData
|
struct ActorFrameData
|
||||||
{
|
{
|
||||||
ActorFrameData(const std::shared_ptr<Actor>& actor, const MWWorld::Ptr standingOn, bool moveToWaterSurface, float slowFall, float waterlevel);
|
ActorFrameData(Actor& actor, const MWWorld::Ptr standingOn, bool moveToWaterSurface, float slowFall, float waterlevel);
|
||||||
void updatePosition(Actor& actor, btCollisionWorld* world);
|
void updatePosition(Actor& actor, btCollisionWorld* world);
|
||||||
std::weak_ptr<Actor> mActor;
|
|
||||||
btCollisionObject* mCollisionObject;
|
btCollisionObject* mCollisionObject;
|
||||||
MWWorld::Ptr mStandingOn;
|
MWWorld::Ptr mStandingOn;
|
||||||
bool mFlying;
|
bool mFlying;
|
||||||
|
@ -260,7 +259,7 @@ namespace MWPhysics
|
||||||
|
|
||||||
void updateWater();
|
void updateWater();
|
||||||
|
|
||||||
std::vector<ActorFrameData> prepareFrameData(bool willSimulate);
|
std::pair<std::vector<std::weak_ptr<Actor>>, std::vector<ActorFrameData>> prepareFrameData(bool willSimulate);
|
||||||
|
|
||||||
osg::ref_ptr<SceneUtil::UnrefQueue> mUnrefQueue;
|
osg::ref_ptr<SceneUtil::UnrefQueue> mUnrefQueue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue