mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-29 16:06:44 +00:00
Merge branch 'simplifystanding' into 'master'
Get rid of the StandingActorsMap. See merge request OpenMW/openmw!409
This commit is contained in:
commit
0a566dbce7
6 changed files with 40 additions and 64 deletions
|
@ -19,7 +19,7 @@ namespace MWPhysics
|
||||||
|
|
||||||
|
|
||||||
Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler)
|
Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler)
|
||||||
: mCanWaterWalk(false), mWalkingOnWater(false)
|
: mStandingOnPtr(nullptr), mCanWaterWalk(false), mWalkingOnWater(false)
|
||||||
, mCollisionObject(nullptr), mMeshTranslation(shape->mCollisionBoxTranslate), mHalfExtents(shape->mCollisionBoxHalfExtents)
|
, mCollisionObject(nullptr), mMeshTranslation(shape->mCollisionBoxTranslate), mHalfExtents(shape->mCollisionBoxHalfExtents)
|
||||||
, mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false)
|
, mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false)
|
||||||
, mInternalCollisionMode(true)
|
, mInternalCollisionMode(true)
|
||||||
|
@ -268,4 +268,16 @@ void Actor::setCanWaterWalk(bool waterWalk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MWWorld::Ptr Actor::getStandingOnPtr() const
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(mPositionMutex);
|
||||||
|
return mStandingOnPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Actor::setStandingOnPtr(const MWWorld::Ptr& ptr)
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(mPositionMutex);
|
||||||
|
mStandingOnPtr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,7 +144,11 @@ namespace MWPhysics
|
||||||
void setWalkingOnWater(bool walkingOnWater);
|
void setWalkingOnWater(bool walkingOnWater);
|
||||||
bool isWalkingOnWater() const;
|
bool isWalkingOnWater() const;
|
||||||
|
|
||||||
|
MWWorld::Ptr getStandingOnPtr() const;
|
||||||
|
void setStandingOnPtr(const MWWorld::Ptr& ptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
MWWorld::Ptr mStandingOnPtr;
|
||||||
/// Removes then re-adds the collision object to the dynamics world
|
/// Removes then re-adds the collision object to the dynamics world
|
||||||
void updateCollisionMask();
|
void updateCollisionMask();
|
||||||
void addCollisionMask(int collisionMask);
|
void addCollisionMask(int collisionMask);
|
||||||
|
|
|
@ -82,14 +82,6 @@ namespace
|
||||||
ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0;
|
ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateStandingCollision(MWPhysics::ActorFrameData& actorData, MWPhysics::CollisionMap& standingCollisions)
|
|
||||||
{
|
|
||||||
if (!actorData.mStandingOn.isEmpty())
|
|
||||||
standingCollisions[actorData.mPtr] = actorData.mStandingOn;
|
|
||||||
else
|
|
||||||
standingCollisions.erase(actorData.mPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateMechanics(MWPhysics::ActorFrameData& actorData)
|
void updateMechanics(MWPhysics::ActorFrameData& actorData)
|
||||||
{
|
{
|
||||||
if (actorData.mDidJump)
|
if (actorData.mDidJump)
|
||||||
|
@ -215,7 +207,7 @@ namespace MWPhysics
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, CollisionMap& standingCollisions, bool skipSimulation)
|
const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, bool skipSimulation)
|
||||||
{
|
{
|
||||||
// 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.
|
||||||
|
@ -225,9 +217,6 @@ namespace MWPhysics
|
||||||
// start by finishing previous background computation
|
// start by finishing previous background computation
|
||||||
if (mNumThreads != 0)
|
if (mNumThreads != 0)
|
||||||
{
|
{
|
||||||
if (mAdvanceSimulation)
|
|
||||||
standingCollisions.clear();
|
|
||||||
|
|
||||||
for (auto& data : mActorsFrameData)
|
for (auto& data : mActorsFrameData)
|
||||||
{
|
{
|
||||||
// Ignore actors that were deleted while the background thread was running
|
// Ignore actors that were deleted while the background thread was running
|
||||||
|
@ -236,7 +225,7 @@ namespace MWPhysics
|
||||||
|
|
||||||
updateMechanics(data);
|
updateMechanics(data);
|
||||||
if (mAdvanceSimulation)
|
if (mAdvanceSimulation)
|
||||||
updateStandingCollision(data, standingCollisions);
|
data.mActorRaw->setStandingOnPtr(data.mStandingOn);
|
||||||
|
|
||||||
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
||||||
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
||||||
|
@ -260,10 +249,10 @@ namespace MWPhysics
|
||||||
// just return the actors' reference position without applying the movements
|
// just return the actors' reference position without applying the movements
|
||||||
if (skipSimulation)
|
if (skipSimulation)
|
||||||
{
|
{
|
||||||
standingCollisions.clear();
|
|
||||||
mMovementResults.clear();
|
mMovementResults.clear();
|
||||||
for (const auto& m : mActorsFrameData)
|
for (const auto& m : mActorsFrameData)
|
||||||
{
|
{
|
||||||
|
m.mActorRaw->setStandingOnPtr(nullptr);
|
||||||
m.mActorRaw->setPosition(m.mActorRaw->getWorldPosition(), true);
|
m.mActorRaw->setPosition(m.mActorRaw->getWorldPosition(), true);
|
||||||
mMovementResults[m.mPtr] = m.mActorRaw->getWorldPosition();
|
mMovementResults[m.mPtr] = m.mActorRaw->getWorldPosition();
|
||||||
}
|
}
|
||||||
|
@ -275,14 +264,10 @@ namespace MWPhysics
|
||||||
mMovementResults.clear();
|
mMovementResults.clear();
|
||||||
syncComputation();
|
syncComputation();
|
||||||
|
|
||||||
if (mAdvanceSimulation)
|
|
||||||
{
|
|
||||||
standingCollisions.clear();
|
|
||||||
for (auto& data : mActorsFrameData)
|
|
||||||
updateStandingCollision(data, standingCollisions);
|
|
||||||
}
|
|
||||||
for (auto& data : mActorsFrameData)
|
for (auto& data : mActorsFrameData)
|
||||||
{
|
{
|
||||||
|
if (mAdvanceSimulation)
|
||||||
|
data.mActorRaw->setStandingOnPtr(data.mStandingOn);
|
||||||
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
||||||
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,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
|
||||||
const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, CollisionMap& standingCollisions, bool skip);
|
const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, bool skip);
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
|
@ -148,11 +148,11 @@ namespace MWPhysics
|
||||||
if (!physactor || !physactor->getOnGround())
|
if (!physactor || !physactor->getOnGround())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
CollisionMap::const_iterator found = mStandingCollisions.find(actor);
|
const auto obj = physactor->getStandingOnPtr();
|
||||||
if (found == mStandingCollisions.end())
|
if (obj.isEmpty())
|
||||||
return true; // assume standing on terrain (which is a non-object, so not collision tracked)
|
return true; // assume standing on terrain (which is a non-object, so not collision tracked)
|
||||||
|
|
||||||
ObjectMap::const_iterator foundObj = mObjects.find(found->second);
|
ObjectMap::const_iterator foundObj = mObjects.find(obj);
|
||||||
if (foundObj == mObjects.end())
|
if (foundObj == mObjects.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -501,22 +501,6 @@ namespace MWPhysics
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated)
|
|
||||||
{
|
|
||||||
CollisionMap::iterator found = map.find(old);
|
|
||||||
if (found != map.end())
|
|
||||||
{
|
|
||||||
map[updated] = found->second;
|
|
||||||
map.erase(found);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& collision : map)
|
|
||||||
{
|
|
||||||
if (collision.second == old)
|
|
||||||
collision.second = updated;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhysicsSystem::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated)
|
void PhysicsSystem::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated)
|
||||||
{
|
{
|
||||||
ObjectMap::iterator found = mObjects.find(old);
|
ObjectMap::iterator found = mObjects.find(old);
|
||||||
|
@ -537,7 +521,11 @@ namespace MWPhysics
|
||||||
mActors.emplace(updated, std::move(actor));
|
mActors.emplace(updated, std::move(actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCollisionMapPtr(mStandingCollisions, old, updated);
|
for (auto& [_, actor] : mActors)
|
||||||
|
{
|
||||||
|
if (actor->getStandingOnPtr() == old)
|
||||||
|
actor->setStandingOnPtr(updated);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Actor *PhysicsSystem::getActor(const MWWorld::Ptr &ptr)
|
Actor *PhysicsSystem::getActor(const MWWorld::Ptr &ptr)
|
||||||
|
@ -675,7 +663,6 @@ namespace MWPhysics
|
||||||
void PhysicsSystem::clearQueuedMovement()
|
void PhysicsSystem::clearQueuedMovement()
|
||||||
{
|
{
|
||||||
mMovementQueue.clear();
|
mMovementQueue.clear();
|
||||||
mStandingCollisions.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation)
|
const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation)
|
||||||
|
@ -688,7 +675,7 @@ namespace MWPhysics
|
||||||
|
|
||||||
mTimeAccum -= numSteps * mPhysicsDt;
|
mTimeAccum -= numSteps * mPhysicsDt;
|
||||||
|
|
||||||
return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), mStandingCollisions, skipSimulation);
|
return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), skipSimulation);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ActorFrameData> PhysicsSystem::prepareFrameData(int numSteps)
|
std::vector<ActorFrameData> PhysicsSystem::prepareFrameData(int numSteps)
|
||||||
|
@ -700,10 +687,8 @@ namespace MWPhysics
|
||||||
{
|
{
|
||||||
const auto foundActor = mActors.find(character);
|
const auto foundActor = mActors.find(character);
|
||||||
if (foundActor == mActors.end()) // actor was already removed from the scene
|
if (foundActor == mActors.end()) // actor was already removed from the scene
|
||||||
{
|
|
||||||
mStandingCollisions.erase(character);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
auto physicActor = foundActor->second;
|
auto physicActor = foundActor->second;
|
||||||
|
|
||||||
float waterlevel = -std::numeric_limits<float>::max();
|
float waterlevel = -std::numeric_limits<float>::max();
|
||||||
|
@ -734,7 +719,7 @@ namespace MWPhysics
|
||||||
// Ue current value only if we don't advance the simulation. Otherwise we might get a stale value.
|
// Ue current value only if we don't advance the simulation. Otherwise we might get a stale value.
|
||||||
MWWorld::Ptr standingOn;
|
MWWorld::Ptr standingOn;
|
||||||
if (numSteps == 0)
|
if (numSteps == 0)
|
||||||
standingOn = mStandingCollisions[character];
|
standingOn = physicActor->getStandingOnPtr();
|
||||||
|
|
||||||
actorsFrameData.emplace_back(std::move(physicActor), character, standingOn, moveToWaterSurface, movement, slowFall, waterlevel);
|
actorsFrameData.emplace_back(std::move(physicActor), character, standingOn, moveToWaterSurface, movement, slowFall, waterlevel);
|
||||||
}
|
}
|
||||||
|
@ -774,20 +759,18 @@ namespace MWPhysics
|
||||||
|
|
||||||
bool PhysicsSystem::isActorStandingOn(const MWWorld::Ptr &actor, const MWWorld::ConstPtr &object) const
|
bool PhysicsSystem::isActorStandingOn(const MWWorld::Ptr &actor, const MWWorld::ConstPtr &object) const
|
||||||
{
|
{
|
||||||
for (const auto& standingActor : mStandingCollisions)
|
const auto physActor = mActors.find(actor);
|
||||||
{
|
if (physActor != mActors.end())
|
||||||
if (standingActor.first == actor && standingActor.second == object)
|
return physActor->second->getStandingOnPtr() == object;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::getActorsStandingOn(const MWWorld::ConstPtr &object, std::vector<MWWorld::Ptr> &out) const
|
void PhysicsSystem::getActorsStandingOn(const MWWorld::ConstPtr &object, std::vector<MWWorld::Ptr> &out) const
|
||||||
{
|
{
|
||||||
for (const auto& standingActor : mStandingCollisions)
|
for (const auto& [_, actor] : mActors)
|
||||||
{
|
{
|
||||||
if (standingActor.second == object)
|
if (actor->getStandingOnPtr() == object)
|
||||||
out.push_back(standingActor.first);
|
out.emplace_back(actor->getPtr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@ class btVector3;
|
||||||
namespace MWPhysics
|
namespace MWPhysics
|
||||||
{
|
{
|
||||||
using PtrPositionList = std::map<MWWorld::Ptr, osg::Vec3f>;
|
using PtrPositionList = std::map<MWWorld::Ptr, osg::Vec3f>;
|
||||||
using CollisionMap = std::map<MWWorld::Ptr, MWWorld::Ptr>;
|
|
||||||
|
|
||||||
class HeightField;
|
class HeightField;
|
||||||
class Object;
|
class Object;
|
||||||
|
@ -272,13 +271,6 @@ namespace MWPhysics
|
||||||
|
|
||||||
bool mDebugDrawEnabled;
|
bool mDebugDrawEnabled;
|
||||||
|
|
||||||
// Tracks standing collisions happening during a single frame. <actor handle, collided handle>
|
|
||||||
// This will detect standing on an object, but won't detect running e.g. against a wall.
|
|
||||||
CollisionMap mStandingCollisions;
|
|
||||||
|
|
||||||
// replaces all occurrences of 'old' in the map by 'updated', no matter if it's a key or value
|
|
||||||
void updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated);
|
|
||||||
|
|
||||||
using PtrVelocityList = std::vector<std::pair<MWWorld::Ptr, osg::Vec3f>>;
|
using PtrVelocityList = std::vector<std::pair<MWWorld::Ptr, osg::Vec3f>>;
|
||||||
PtrVelocityList mMovementQueue;
|
PtrVelocityList mMovementQueue;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue