mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 23:23:52 +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)
|
||||
: mCanWaterWalk(false), mWalkingOnWater(false)
|
||||
: mStandingOnPtr(nullptr), mCanWaterWalk(false), mWalkingOnWater(false)
|
||||
, mCollisionObject(nullptr), mMeshTranslation(shape->mCollisionBoxTranslate), mHalfExtents(shape->mCollisionBoxHalfExtents)
|
||||
, mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false)
|
||||
, 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);
|
||||
bool isWalkingOnWater() const;
|
||||
|
||||
MWWorld::Ptr getStandingOnPtr() const;
|
||||
void setStandingOnPtr(const MWWorld::Ptr& ptr);
|
||||
|
||||
private:
|
||||
MWWorld::Ptr mStandingOnPtr;
|
||||
/// Removes then re-adds the collision object to the dynamics world
|
||||
void updateCollisionMask();
|
||||
void addCollisionMask(int collisionMask);
|
||||
|
|
|
@ -82,14 +82,6 @@ namespace
|
|||
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)
|
||||
{
|
||||
if (actorData.mDidJump)
|
||||
|
@ -215,7 +207,7 @@ namespace MWPhysics
|
|||
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.
|
||||
// While the mSimulationMutex is held, background physics threads can't run.
|
||||
|
@ -225,9 +217,6 @@ namespace MWPhysics
|
|||
// start by finishing previous background computation
|
||||
if (mNumThreads != 0)
|
||||
{
|
||||
if (mAdvanceSimulation)
|
||||
standingCollisions.clear();
|
||||
|
||||
for (auto& data : mActorsFrameData)
|
||||
{
|
||||
// Ignore actors that were deleted while the background thread was running
|
||||
|
@ -236,7 +225,7 @@ namespace MWPhysics
|
|||
|
||||
updateMechanics(data);
|
||||
if (mAdvanceSimulation)
|
||||
updateStandingCollision(data, standingCollisions);
|
||||
data.mActorRaw->setStandingOnPtr(data.mStandingOn);
|
||||
|
||||
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
||||
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
||||
|
@ -260,10 +249,10 @@ namespace MWPhysics
|
|||
// just return the actors' reference position without applying the movements
|
||||
if (skipSimulation)
|
||||
{
|
||||
standingCollisions.clear();
|
||||
mMovementResults.clear();
|
||||
for (const auto& m : mActorsFrameData)
|
||||
{
|
||||
m.mActorRaw->setStandingOnPtr(nullptr);
|
||||
m.mActorRaw->setPosition(m.mActorRaw->getWorldPosition(), true);
|
||||
mMovementResults[m.mPtr] = m.mActorRaw->getWorldPosition();
|
||||
}
|
||||
|
@ -275,14 +264,10 @@ namespace MWPhysics
|
|||
mMovementResults.clear();
|
||||
syncComputation();
|
||||
|
||||
for (auto& data : mActorsFrameData)
|
||||
{
|
||||
if (mAdvanceSimulation)
|
||||
{
|
||||
standingCollisions.clear();
|
||||
for (auto& data : mActorsFrameData)
|
||||
updateStandingCollision(data, standingCollisions);
|
||||
}
|
||||
for (auto& data : mActorsFrameData)
|
||||
{
|
||||
data.mActorRaw->setStandingOnPtr(data.mStandingOn);
|
||||
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
||||
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace MWPhysics
|
|||
/// @param timeAccum accumulated time from previous run to interpolate movements
|
||||
/// @param actorsData per actor data needed to compute new positions
|
||||
/// @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
|
||||
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const;
|
||||
|
|
|
@ -148,11 +148,11 @@ namespace MWPhysics
|
|||
if (!physactor || !physactor->getOnGround())
|
||||
return false;
|
||||
|
||||
CollisionMap::const_iterator found = mStandingCollisions.find(actor);
|
||||
if (found == mStandingCollisions.end())
|
||||
const auto obj = physactor->getStandingOnPtr();
|
||||
if (obj.isEmpty())
|
||||
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())
|
||||
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)
|
||||
{
|
||||
ObjectMap::iterator found = mObjects.find(old);
|
||||
|
@ -537,7 +521,11 @@ namespace MWPhysics
|
|||
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)
|
||||
|
@ -675,7 +663,6 @@ namespace MWPhysics
|
|||
void PhysicsSystem::clearQueuedMovement()
|
||||
{
|
||||
mMovementQueue.clear();
|
||||
mStandingCollisions.clear();
|
||||
}
|
||||
|
||||
const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation)
|
||||
|
@ -688,7 +675,7 @@ namespace MWPhysics
|
|||
|
||||
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)
|
||||
|
@ -700,10 +687,8 @@ namespace MWPhysics
|
|||
{
|
||||
const auto foundActor = mActors.find(character);
|
||||
if (foundActor == mActors.end()) // actor was already removed from the scene
|
||||
{
|
||||
mStandingCollisions.erase(character);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto physicActor = foundActor->second;
|
||||
|
||||
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.
|
||||
MWWorld::Ptr standingOn;
|
||||
if (numSteps == 0)
|
||||
standingOn = mStandingCollisions[character];
|
||||
standingOn = physicActor->getStandingOnPtr();
|
||||
|
||||
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
|
||||
{
|
||||
for (const auto& standingActor : mStandingCollisions)
|
||||
{
|
||||
if (standingActor.first == actor && standingActor.second == object)
|
||||
return true;
|
||||
}
|
||||
const auto physActor = mActors.find(actor);
|
||||
if (physActor != mActors.end())
|
||||
return physActor->second->getStandingOnPtr() == object;
|
||||
return false;
|
||||
}
|
||||
|
||||
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)
|
||||
out.push_back(standingActor.first);
|
||||
if (actor->getStandingOnPtr() == object)
|
||||
out.emplace_back(actor->getPtr());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ class btVector3;
|
|||
namespace MWPhysics
|
||||
{
|
||||
using PtrPositionList = std::map<MWWorld::Ptr, osg::Vec3f>;
|
||||
using CollisionMap = std::map<MWWorld::Ptr, MWWorld::Ptr>;
|
||||
|
||||
class HeightField;
|
||||
class Object;
|
||||
|
@ -272,13 +271,6 @@ namespace MWPhysics
|
|||
|
||||
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>>;
|
||||
PtrVelocityList mMovementQueue;
|
||||
|
||||
|
|
Loading…
Reference in a new issue