mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-10 15:45:37 +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;
|
isOnGround = true;
|
||||||
isOnSlope = !isWalkableSlope(tracer.mPlaneNormal);
|
isOnSlope = !isWalkableSlope(tracer.mPlaneNormal);
|
||||||
|
actor.mStandingOn = tracer.mHitObject;
|
||||||
|
|
||||||
const btCollisionObject* standingOn = tracer.mHitObject;
|
if (actor.mStandingOn->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Water)
|
||||||
PtrHolder* ptrHolder = static_cast<PtrHolder*>(standingOn->getUserPointer());
|
|
||||||
if (ptrHolder)
|
|
||||||
actor.mStandingOn = ptrHolder->getPtr();
|
|
||||||
|
|
||||||
if (standingOn->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Water)
|
|
||||||
actor.mWalkingOnWater = true;
|
actor.mWalkingOnWater = true;
|
||||||
if (!actor.mFlying && !isOnSlope)
|
if (!actor.mFlying && !isOnSlope)
|
||||||
{
|
{
|
||||||
|
@ -83,21 +83,6 @@ namespace
|
|||||||
return actorData.mPosition * interpolationFactor + actor.getPreviousPosition() * (1.f - interpolationFactor);
|
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
|
namespace Config
|
||||||
{
|
{
|
||||||
/// @return either the number of thread as configured by the user, or 1 if Bullet doesn't support multithreading
|
/// @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)
|
void PhysicsTaskScheduler::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask)
|
||||||
{
|
{
|
||||||
|
mCollisionObjects.insert(collisionObject);
|
||||||
std::unique_lock lock(mCollisionWorldMutex);
|
std::unique_lock lock(mCollisionWorldMutex);
|
||||||
mCollisionWorld->addCollisionObject(collisionObject, collisionFilterGroup, collisionFilterMask);
|
mCollisionWorld->addCollisionObject(collisionObject, collisionFilterGroup, collisionFilterMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsTaskScheduler::removeCollisionObject(btCollisionObject* collisionObject)
|
void PhysicsTaskScheduler::removeCollisionObject(btCollisionObject* collisionObject)
|
||||||
{
|
{
|
||||||
|
mCollisionObjects.erase(collisionObject);
|
||||||
std::unique_lock lock(mCollisionWorldMutex);
|
std::unique_lock lock(mCollisionWorldMutex);
|
||||||
mCollisionWorld->removeCollisionObject(collisionObject);
|
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)
|
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
|
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();
|
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()
|
void PhysicsTaskScheduler::afterPreStep()
|
||||||
{
|
{
|
||||||
updateAabbs();
|
updateAabbs();
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <shared_mutex>
|
#include <shared_mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
|
||||||
|
|
||||||
@ -55,11 +56,13 @@ namespace MWPhysics
|
|||||||
void updateSingleAabb(std::weak_ptr<PtrHolder> ptr, bool immediate=false);
|
void updateSingleAabb(std::weak_ptr<PtrHolder> ptr, bool immediate=false);
|
||||||
bool getLineOfSight(const std::weak_ptr<Actor>& actor1, const std::weak_ptr<Actor>& actor2);
|
bool getLineOfSight(const std::weak_ptr<Actor>& actor1, const std::weak_ptr<Actor>& actor2);
|
||||||
void debugDraw();
|
void debugDraw();
|
||||||
|
void* getUserPointer(const btCollisionObject* object) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void syncComputation();
|
void syncComputation();
|
||||||
void worker();
|
void worker();
|
||||||
void updateActorsPositions();
|
void updateActorsPositions();
|
||||||
|
void updateActor(Actor& actor, ActorFrameData& actorData, bool simulationPerformed, float timeAccum, float dt) const;
|
||||||
bool hasLineOfSight(const Actor* actor1, const Actor* actor2);
|
bool hasLineOfSight(const Actor* actor1, const Actor* actor2);
|
||||||
void refreshLOSCache();
|
void refreshLOSCache();
|
||||||
void updateAabbs();
|
void updateAabbs();
|
||||||
@ -73,6 +76,7 @@ namespace MWPhysics
|
|||||||
std::unique_ptr<WorldFrameData> mWorldFrameData;
|
std::unique_ptr<WorldFrameData> mWorldFrameData;
|
||||||
std::vector<std::weak_ptr<Actor>> mActors;
|
std::vector<std::weak_ptr<Actor>> mActors;
|
||||||
std::vector<ActorFrameData> mActorsFrameData;
|
std::vector<ActorFrameData> mActorsFrameData;
|
||||||
|
std::unordered_set<const btCollisionObject*> mCollisionObjects;
|
||||||
float mDefaultPhysicsDt;
|
float mDefaultPhysicsDt;
|
||||||
float mPhysicsDt;
|
float mPhysicsDt;
|
||||||
float mTimeAccum;
|
float mTimeAccum;
|
||||||
|
@ -811,13 +811,8 @@ namespace MWPhysics
|
|||||||
// Slow fall reduces fall speed by a factor of (effect magnitude / 200)
|
// 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));
|
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.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 the simulation will run, a jump request will be fulfilled. Update mechanics accordingly.
|
||||||
if (willSimulate)
|
if (willSimulate)
|
||||||
@ -989,10 +984,9 @@ namespace MWPhysics
|
|||||||
mDebugDrawer->addCollision(position, normal);
|
mDebugDrawer->addCollision(position, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
ActorFrameData::ActorFrameData(Actor& actor, const MWWorld::Ptr standingOn,
|
ActorFrameData::ActorFrameData(Actor& actor, bool waterCollision, float slowFall, float waterlevel)
|
||||||
bool waterCollision, float slowFall, float waterlevel)
|
|
||||||
: mCollisionObject(actor.getCollisionObject())
|
: mCollisionObject(actor.getCollisionObject())
|
||||||
, mStandingOn(standingOn)
|
, mStandingOn(nullptr)
|
||||||
, mWasOnGround(actor.getOnGround())
|
, mWasOnGround(actor.getOnGround())
|
||||||
, mIsOnGround(actor.getOnGround())
|
, mIsOnGround(actor.getOnGround())
|
||||||
, mIsOnSlope(actor.getOnSlope())
|
, mIsOnSlope(actor.getOnSlope())
|
||||||
|
@ -78,10 +78,10 @@ namespace MWPhysics
|
|||||||
|
|
||||||
struct ActorFrameData
|
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);
|
void updatePosition(Actor& actor, btCollisionWorld* world);
|
||||||
btCollisionObject* mCollisionObject;
|
btCollisionObject* mCollisionObject;
|
||||||
MWWorld::Ptr mStandingOn;
|
const btCollisionObject* mStandingOn;
|
||||||
bool mFlying;
|
bool mFlying;
|
||||||
bool mWasOnGround;
|
bool mWasOnGround;
|
||||||
bool mIsOnGround;
|
bool mIsOnGround;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user