From 580edf18b9cd9ec8911ae8ccfb2c03efa2eb0a06 Mon Sep 17 00:00:00 2001 From: elsid Date: Fri, 21 Jan 2022 00:28:56 +0000 Subject: [PATCH] Use weak_ptr for Actor and Projectile simulations (#6515) --- apps/openmw/mwphysics/mtphysics.cpp | 25 ++++++++++++++++++++----- apps/openmw/mwphysics/physicssystem.hpp | 4 ++-- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index 2f7e3b5995..2bbd751f63 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -118,7 +118,10 @@ namespace const btCollisionWorld* mCollisionWorld; void operator()(MWPhysics::ActorSimulation& sim) const { - auto& [actor, frameData] = sim; + auto& [actorPtr, frameData] = sim; + const auto actor = actorPtr.lock(); + if (actor == nullptr) + return; actor->applyOffsetChange(); frameData.mPosition = actor->getPosition(); if (frameData.mWaterCollision && frameData.mPosition.z() < frameData.mWaterlevel && actor->canMoveToWaterSurface(frameData.mWaterlevel, mCollisionWorld)) @@ -157,7 +160,10 @@ namespace btCollisionWorld* mCollisionWorld; void operator()(MWPhysics::ActorSimulation& sim) const { - auto& [actor, frameData] = sim; + auto& [actorPtr, frameData] = sim; + const auto actor = actorPtr.lock(); + if (actor == nullptr) + return; if (actor->setPosition(frameData.mPosition)) { frameData.mPosition = actor->getPosition(); // account for potential position change made by script @@ -167,7 +173,10 @@ namespace } void operator()(MWPhysics::ProjectileSimulation& sim) const { - auto& [proj, frameData] = sim; + auto& [projPtr, frameData] = sim; + const auto proj = projPtr.lock(); + if (proj == nullptr) + return; proj->setPosition(frameData.mPosition); proj->updateCollisionObjectPosition(); mCollisionWorld->updateSingleAabb(proj->getCollisionObject()); @@ -197,7 +206,10 @@ namespace const MWPhysics::PhysicsTaskScheduler* scheduler; void operator()(MWPhysics::ActorSimulation& sim) const { - auto& [actor, frameData] = sim; + auto& [actorPtr, frameData] = sim; + const auto actor = actorPtr.lock(); + if (actor == nullptr) + return; auto ptr = actor->getPtr(); MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr); @@ -229,7 +241,10 @@ namespace } void operator()(MWPhysics::ProjectileSimulation& sim) const { - auto& [proj, frameData] = sim; + auto& [projPtr, frameData] = sim; + const auto proj = projPtr.lock(); + if (proj == nullptr) + return; proj->setSimulationPosition(::interpolateMovements(*proj, mTimeAccum, mPhysicsDt)); } }; diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index c31bbfbf65..d2b535c427 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -117,8 +117,8 @@ namespace MWPhysics osg::Vec3f mStormDirection; }; - using ActorSimulation = std::pair, ActorFrameData>; - using ProjectileSimulation = std::pair, ProjectileFrameData>; + using ActorSimulation = std::pair, ActorFrameData>; + using ProjectileSimulation = std::pair, ProjectileFrameData>; using Simulation = std::variant; class PhysicsSystem : public RayCastingInterface