mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-29 13:20:35 +00:00
Store the btCollisionObject* of the object we're standing on instead of
MWWorld::Ptr: - they are equivalent - btCollisionObject* is readily available from the simulation, it saves a call to a mutex - btCollisionObject* is smaller
This commit is contained in:
parent
26d9052b8c
commit
0c5cf6ec19
@ -345,13 +345,9 @@ namespace MWPhysics
|
||||
{
|
||||
isOnGround = true;
|
||||
isOnSlope = !isWalkableSlope(tracer.mPlaneNormal);
|
||||
actor.mStandingOn = tracer.mHitObject;
|
||||
|
||||
const btCollisionObject* standingOn = tracer.mHitObject;
|
||||
PtrHolder* ptrHolder = static_cast<PtrHolder*>(standingOn->getUserPointer());
|
||||
if (ptrHolder)
|
||||
actor.mStandingOn = ptrHolder->getPtr();
|
||||
|
||||
if (standingOn->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Water)
|
||||
if (actor.mStandingOn->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Water)
|
||||
actor.mWalkingOnWater = true;
|
||||
if (!actor.mFlying && !isOnSlope)
|
||||
{
|
||||
|
@ -83,21 +83,6 @@ namespace
|
||||
return actorData.mPosition * interpolationFactor + actor.getPreviousPosition() * (1.f - interpolationFactor);
|
||||
}
|
||||
|
||||
void updateActor(MWPhysics::Actor& actor, MWPhysics::ActorFrameData& actorData, bool simulationPerformed, float timeAccum, float dt)
|
||||
{
|
||||
actor.setSimulationPosition(interpolateMovements(actor, actorData, timeAccum, dt));
|
||||
actor.setLastStuckPosition(actorData.mLastStuckPosition);
|
||||
actor.setStuckFrames(actorData.mStuckFrames);
|
||||
if (simulationPerformed)
|
||||
{
|
||||
actor.setStandingOnPtr(actorData.mStandingOn);
|
||||
actor.setOnGround(actorData.mIsOnGround);
|
||||
actor.setOnSlope(actorData.mIsOnSlope);
|
||||
actor.setWalkingOnWater(actorData.mWalkingOnWater);
|
||||
actor.setInertialForce(actorData.mInertia);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Config
|
||||
{
|
||||
/// @return either the number of thread as configured by the user, or 1 if Bullet doesn't support multithreading
|
||||
@ -357,12 +342,14 @@ namespace MWPhysics
|
||||
|
||||
void PhysicsTaskScheduler::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask)
|
||||
{
|
||||
mCollisionObjects.insert(collisionObject);
|
||||
std::unique_lock lock(mCollisionWorldMutex);
|
||||
mCollisionWorld->addCollisionObject(collisionObject, collisionFilterGroup, collisionFilterMask);
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::removeCollisionObject(btCollisionObject* collisionObject)
|
||||
{
|
||||
mCollisionObjects.erase(collisionObject);
|
||||
std::unique_lock lock(mCollisionWorldMutex);
|
||||
mCollisionWorld->removeCollisionObject(collisionObject);
|
||||
}
|
||||
@ -506,6 +493,27 @@ namespace MWPhysics
|
||||
}
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::updateActor(Actor& actor, ActorFrameData& actorData, bool simulationPerformed, float timeAccum, float dt) const
|
||||
{
|
||||
actor.setSimulationPosition(interpolateMovements(actor, actorData, timeAccum, dt));
|
||||
actor.setLastStuckPosition(actorData.mLastStuckPosition);
|
||||
actor.setStuckFrames(actorData.mStuckFrames);
|
||||
if (simulationPerformed)
|
||||
{
|
||||
MWWorld::Ptr standingOn;
|
||||
auto* ptrHolder = static_cast<MWPhysics::PtrHolder*>(getUserPointer(actorData.mStandingOn));
|
||||
if (ptrHolder)
|
||||
standingOn = ptrHolder->getPtr();
|
||||
actor.setStandingOnPtr(standingOn);
|
||||
// the "on ground" state of an actor might have been updated by a traceDown, don't overwrite the change
|
||||
if (actor.getOnGround() == actorData.mWasOnGround)
|
||||
actor.setOnGround(actorData.mIsOnGround);
|
||||
actor.setOnSlope(actorData.mIsOnSlope);
|
||||
actor.setWalkingOnWater(actorData.mWalkingOnWater);
|
||||
actor.setInertialForce(actorData.mInertia);
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicsTaskScheduler::hasLineOfSight(const Actor* actor1, const Actor* actor2)
|
||||
{
|
||||
btVector3 pos1 = Misc::Convert::toBullet(actor1->getCollisionObjectPosition() + osg::Vec3f(0,0,actor1->getHalfExtents().z() * 0.9)); // eye level
|
||||
@ -566,6 +574,14 @@ namespace MWPhysics
|
||||
mDebugDrawer->step();
|
||||
}
|
||||
|
||||
void* PhysicsTaskScheduler::getUserPointer(const btCollisionObject* object) const
|
||||
{
|
||||
auto it = mCollisionObjects.find(object);
|
||||
if (it == mCollisionObjects.end())
|
||||
return nullptr;
|
||||
return (*it)->getUserPointer();
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::afterPreStep()
|
||||
{
|
||||
updateAabbs();
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#include <thread>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
||||
|
||||
@ -55,11 +56,13 @@ namespace MWPhysics
|
||||
void updateSingleAabb(std::weak_ptr<PtrHolder> ptr, bool immediate=false);
|
||||
bool getLineOfSight(const std::weak_ptr<Actor>& actor1, const std::weak_ptr<Actor>& actor2);
|
||||
void debugDraw();
|
||||
void* getUserPointer(const btCollisionObject* object) const;
|
||||
|
||||
private:
|
||||
void syncComputation();
|
||||
void worker();
|
||||
void updateActorsPositions();
|
||||
void updateActor(Actor& actor, ActorFrameData& actorData, bool simulationPerformed, float timeAccum, float dt) const;
|
||||
bool hasLineOfSight(const Actor* actor1, const Actor* actor2);
|
||||
void refreshLOSCache();
|
||||
void updateAabbs();
|
||||
@ -73,6 +76,7 @@ namespace MWPhysics
|
||||
std::unique_ptr<WorldFrameData> mWorldFrameData;
|
||||
std::vector<std::weak_ptr<Actor>> mActors;
|
||||
std::vector<ActorFrameData> mActorsFrameData;
|
||||
std::unordered_set<const btCollisionObject*> mCollisionObjects;
|
||||
float mDefaultPhysicsDt;
|
||||
float mPhysicsDt;
|
||||
float mTimeAccum;
|
||||
|
@ -811,13 +811,8 @@ namespace MWPhysics
|
||||
// Slow fall reduces fall speed by a factor of (effect magnitude / 200)
|
||||
const float slowFall = 1.f - std::max(0.f, std::min(1.f, effects.get(ESM::MagicEffect::SlowFall).getMagnitude() * 0.005f));
|
||||
|
||||
// Ue current value only if we don't advance the simulation. Otherwise we might get a stale value.
|
||||
MWWorld::Ptr standingOn;
|
||||
if (!willSimulate)
|
||||
standingOn = physicActor->getStandingOnPtr();
|
||||
|
||||
framedata.first.emplace_back(physicActor);
|
||||
framedata.second.emplace_back(*physicActor, standingOn, waterCollision, slowFall, waterlevel);
|
||||
framedata.second.emplace_back(*physicActor, waterCollision, slowFall, waterlevel);
|
||||
|
||||
// if the simulation will run, a jump request will be fulfilled. Update mechanics accordingly.
|
||||
if (willSimulate)
|
||||
@ -989,10 +984,9 @@ namespace MWPhysics
|
||||
mDebugDrawer->addCollision(position, normal);
|
||||
}
|
||||
|
||||
ActorFrameData::ActorFrameData(Actor& actor, const MWWorld::Ptr standingOn,
|
||||
bool waterCollision, float slowFall, float waterlevel)
|
||||
ActorFrameData::ActorFrameData(Actor& actor, bool waterCollision, float slowFall, float waterlevel)
|
||||
: mCollisionObject(actor.getCollisionObject())
|
||||
, mStandingOn(standingOn)
|
||||
, mStandingOn(nullptr)
|
||||
, mWasOnGround(actor.getOnGround())
|
||||
, mIsOnGround(actor.getOnGround())
|
||||
, mIsOnSlope(actor.getOnSlope())
|
||||
|
@ -78,10 +78,10 @@ namespace MWPhysics
|
||||
|
||||
struct ActorFrameData
|
||||
{
|
||||
ActorFrameData(Actor& actor, const MWWorld::Ptr standingOn, bool moveToWaterSurface, float slowFall, float waterlevel);
|
||||
ActorFrameData(Actor& actor, bool moveToWaterSurface, float slowFall, float waterlevel);
|
||||
void updatePosition(Actor& actor, btCollisionWorld* world);
|
||||
btCollisionObject* mCollisionObject;
|
||||
MWWorld::Ptr mStandingOn;
|
||||
const btCollisionObject* mStandingOn;
|
||||
bool mFlying;
|
||||
bool mWasOnGround;
|
||||
bool mIsOnGround;
|
||||
|
Loading…
x
Reference in New Issue
Block a user