Merge branch 'physics_refactor' into 'master'

Small physics refactoring

See merge request OpenMW/openmw!2417
make_linux_ci_do_zoomies
psi29a 2 years ago
commit 525f81393a

@ -22,7 +22,8 @@ namespace MWPhysics
Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler,
bool canWaterWalk, DetourNavigator::CollisionShapeType collisionShapeType)
: mStandingOnPtr(nullptr), mCanWaterWalk(canWaterWalk), mWalkingOnWater(false)
: PtrHolder(ptr, ptr.getRefData().getPosition().asVec3())
, mStandingOnPtr(nullptr), mCanWaterWalk(canWaterWalk), mWalkingOnWater(false)
, mMeshTranslation(shape->mCollisionBox.mCenter), mOriginalHalfExtents(shape->mCollisionBox.mExtents)
, mStuckFrames(0), mLastStuckPosition{0, 0, 0}
, mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false)
@ -31,8 +32,6 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic
, mActive(false)
, mTaskScheduler(scheduler)
{
mPtr = ptr;
// We can not create actor without collisions - he will fall through the ground.
// In this case we should autogenerate collision box based on mesh shape
// (NPCs have bodyparts and use a different approach)
@ -94,14 +93,13 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic
mCollisionObject->setCollisionShape(mShape.get());
mCollisionObject->setUserPointer(this);
updateScale();
updateScaleUnsafe();
if(!mRotationallyInvariant)
setRotation(mPtr.getRefData().getBaseNode()->getAttitude());
mRotation = mPtr.getRefData().getBaseNode()->getAttitude();
updatePosition();
addCollisionMask(getCollisionMask());
updateCollisionObjectPosition();
updateCollisionObjectPositionUnsafe();
}
Actor::~Actor()
@ -169,6 +167,11 @@ osg::Vec3f Actor::getScaledMeshTranslation() const
void Actor::updateCollisionObjectPosition()
{
std::scoped_lock lock(mPositionMutex);
updateCollisionObjectPositionUnsafe();
}
void Actor::updateCollisionObjectPositionUnsafe()
{
mShape->setLocalScaling(Misc::Convert::toBullet(mScale));
osg::Vec3f newPosition = getScaledMeshTranslation() + mPosition;
@ -230,6 +233,11 @@ bool Actor::isRotationallyInvariant() const
void Actor::updateScale()
{
std::scoped_lock lock(mPositionMutex);
updateScaleUnsafe();
}
void Actor::updateScaleUnsafe()
{
float scale = mPtr.getCellRef().getScale();
osg::Vec3f scaleVec(scale,scale,scale);

@ -33,6 +33,10 @@ namespace MWPhysics
bool canWaterWalk, DetourNavigator::CollisionShapeType collisionShapeType);
~Actor() override;
Actor(const Actor&) = delete;
Actor& operator=(const Actor&) = delete;
/**
* Sets the collisionMode for this actor. If disabled, the actor can fly and clip geometry.
*/
@ -189,8 +193,8 @@ namespace MWPhysics
osg::Vec3f mScale;
osg::Vec3f mPositionOffset;
bool mWorldPositionChanged;
bool mSkipSimulation;
bool mWorldPositionChanged = false;
bool mSkipSimulation = true;
mutable std::mutex mPositionMutex;
unsigned int mStuckFrames;
@ -205,8 +209,9 @@ namespace MWPhysics
PhysicsTaskScheduler* mTaskScheduler;
Actor(const Actor&);
Actor& operator=(const Actor&);
inline void updateScaleUnsafe();
inline void updateCollisionObjectPositionUnsafe();
};
}

@ -15,14 +15,14 @@
namespace MWPhysics
{
Object::Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance, osg::Quat rotation, int collisionType, PhysicsTaskScheduler* scheduler)
: mShapeInstance(std::move(shapeInstance))
: PtrHolder(ptr, osg::Vec3f())
, mShapeInstance(std::move(shapeInstance))
, mSolid(true)
, mScale(ptr.getCellRef().getScale(), ptr.getCellRef().getScale(), ptr.getCellRef().getScale())
, mPosition(ptr.getRefData().getPosition().asVec3())
, mRotation(rotation)
, mTaskScheduler(scheduler)
{
mPtr = ptr;
mCollisionObject = BulletHelpers::makeCollisionObject(mShapeInstance->mCollisionShape.get(),
Misc::Convert::toBullet(mPosition), Misc::Convert::toBullet(rotation));
mCollisionObject->setUserPointer(this);

@ -15,7 +15,8 @@
namespace MWPhysics
{
Projectile::Projectile(const MWWorld::Ptr& caster, const osg::Vec3f& position, float radius, PhysicsTaskScheduler* scheduler, PhysicsSystem* physicssystem)
: mHitWater(false)
: PtrHolder(MWWorld::Ptr(), position)
, mHitWater(false)
, mActive(true)
, mHitTarget(nullptr)
, mPhysics(physicssystem)

@ -16,6 +16,14 @@ namespace MWPhysics
class PtrHolder
{
public:
explicit PtrHolder(const MWWorld::Ptr& ptr, const osg::Vec3f& position)
: mPtr(ptr)
, mSimulationPosition(position)
, mPosition(position)
, mPreviousPosition(position)
{
}
virtual ~PtrHolder() = default;
void updatePtr(const MWWorld::Ptr& updated)

@ -286,15 +286,6 @@ namespace MWWorld
}
}
void Scene::updateObjectPosition(const Ptr &ptr, const osg::Vec3f &pos, bool movePhysics)
{
mRendering.moveObject(ptr, pos);
if (movePhysics)
{
mPhysics->updatePosition(ptr);
}
}
void Scene::updateObjectRotation(const Ptr &ptr, RotationOrder order)
{
const auto rot = makeNodeRotation(ptr, order);

@ -188,7 +188,6 @@ namespace MWWorld
void updateObjectRotation(const Ptr& ptr, RotationOrder order);
void updateObjectScale(const Ptr& ptr);
void updateObjectPosition(const Ptr &ptr, const osg::Vec3f &pos, bool movePhysics);
bool isCellActive(const CellStore &cell);

@ -1260,10 +1260,11 @@ namespace MWWorld
}
if (haveToMove && newPtr.getRefData().getBaseNode())
{
mWorldScene->updateObjectPosition(newPtr, position, movePhysics);
mRendering->moveObject(newPtr, position);
if (movePhysics)
{
if (const auto object = mPhysics->getObject(ptr))
mPhysics->updatePosition(newPtr);
if (const MWPhysics::Object* object = mPhysics->getObject(newPtr))
updateNavigatorObject(*object);
}
}

Loading…
Cancel
Save