diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 4df5646516..50b400c2ac 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -147,18 +147,20 @@ void Actor::updateCollisionObjectPosition() { std::scoped_lock lock(mPositionMutex); mShape->setLocalScaling(Misc::Convert::toBullet(mScale)); - osg::Vec3f scaledTranslation = mRotation * osg::componentMultiply(mMeshTranslation, mScale); - osg::Vec3f newPosition = scaledTranslation + mPosition; - mLocalTransform.setOrigin(Misc::Convert::toBullet(newPosition)); - mLocalTransform.setRotation(Misc::Convert::toBullet(mRotation)); - mCollisionObject->setWorldTransform(mLocalTransform); + osg::Vec3f newPosition = getScaledMeshTranslation() + mPosition; + + auto& trans = mCollisionObject->getWorldTransform(); + trans.setOrigin(Misc::Convert::toBullet(newPosition)); + trans.setRotation(Misc::Convert::toBullet(mRotation)); + mCollisionObject->setWorldTransform(trans); + mWorldPositionChanged = false; } osg::Vec3f Actor::getCollisionObjectPosition() const { std::scoped_lock lock(mPositionMutex); - return Misc::Convert::toOsg(mLocalTransform.getOrigin()); + return getScaledMeshTranslation() + mPosition; } bool Actor::setPosition(const osg::Vec3f& position) diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index 8bbb90dbed..3925edf59f 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -74,9 +74,6 @@ namespace MWPhysics */ osg::Vec3f getOriginalHalfExtents() const; - /// Returns the mesh translation, scaled and rotated as necessary - osg::Vec3f getScaledMeshTranslation() const; - /** * Returns the position of the collision body * @note The collision shape's origin is in its center, so the position returned can be described as center of the actor collision box in world space. @@ -181,6 +178,9 @@ namespace MWPhysics void addCollisionMask(int collisionMask); int getCollisionMask() const; + /// Returns the mesh translation, scaled and rotated as necessary + osg::Vec3f getScaledMeshTranslation() const; + bool mCanWaterWalk; std::atomic mWalkingOnWater; @@ -205,7 +205,6 @@ namespace MWPhysics bool mWorldPositionChanged; bool mSkipCollisions; bool mSkipSimulation; - btTransform mLocalTransform; mutable std::mutex mPositionMutex; unsigned int mStuckFrames; diff --git a/apps/openmw/mwphysics/object.cpp b/apps/openmw/mwphysics/object.cpp index 2a94d28f12..9575a97da2 100644 --- a/apps/openmw/mwphysics/object.cpp +++ b/apps/openmw/mwphysics/object.cpp @@ -28,7 +28,7 @@ namespace MWPhysics setScale(ptr.getCellRef().getScale()); setRotation(rotation); - setOrigin(Misc::Convert::toBullet(ptr.getRefData().getPosition().asVec3())); + updatePosition(); commitPositionChange(); mTaskScheduler->addCollisionObject(mCollisionObject.get(), collisionType, CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); @@ -54,14 +54,14 @@ namespace MWPhysics void Object::setRotation(osg::Quat quat) { std::unique_lock lock(mPositionMutex); - mLocalTransform.setRotation(Misc::Convert::toBullet(quat)); + mRotation = quat; mTransformUpdatePending = true; } - void Object::setOrigin(const btVector3& vec) + void Object::updatePosition() { std::unique_lock lock(mPositionMutex); - mLocalTransform.setOrigin(vec); + mPosition = mPtr.getRefData().getPosition().asVec3(); mTransformUpdatePending = true; } @@ -75,7 +75,10 @@ namespace MWPhysics } if (mTransformUpdatePending) { - mCollisionObject->setWorldTransform(mLocalTransform); + btTransform trans; + trans.setOrigin(Misc::Convert::toBullet(mPosition)); + trans.setRotation(Misc::Convert::toBullet(mRotation)); + mCollisionObject->setWorldTransform(trans); mTransformUpdatePending = false; } } @@ -93,7 +96,10 @@ namespace MWPhysics btTransform Object::getTransform() const { std::unique_lock lock(mPositionMutex); - return mLocalTransform; + btTransform trans; + trans.setOrigin(Misc::Convert::toBullet(mPosition)); + trans.setRotation(Misc::Convert::toBullet(mRotation)); + return trans; } bool Object::isSolid() const diff --git a/apps/openmw/mwphysics/object.hpp b/apps/openmw/mwphysics/object.hpp index c2273831e5..fe395dc89b 100644 --- a/apps/openmw/mwphysics/object.hpp +++ b/apps/openmw/mwphysics/object.hpp @@ -16,7 +16,6 @@ namespace Resource } class btCollisionObject; -class btQuaternion; class btVector3; namespace MWPhysics @@ -32,7 +31,7 @@ namespace MWPhysics const Resource::BulletShapeInstance* getShapeInstance() const; void setScale(float scale); void setRotation(osg::Quat quat); - void setOrigin(const btVector3& vec); + void updatePosition(); void commitPositionChange(); btCollisionObject* getCollisionObject(); const btCollisionObject* getCollisionObject() const; @@ -51,7 +50,8 @@ namespace MWPhysics std::map mRecIndexToNodePath; bool mSolid; btVector3 mScale; - btTransform mLocalTransform; + osg::Vec3f mPosition; + osg::Quat mRotation; bool mScaleUpdatePending; bool mTransformUpdatePending; mutable std::mutex mPositionMutex; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index e5bd936abb..69a4d8d478 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -658,7 +658,7 @@ namespace MWPhysics ObjectMap::iterator found = mObjects.find(ptr); if (found != mObjects.end()) { - found->second->setOrigin(Misc::Convert::toBullet(ptr.getRefData().getPosition().asVec3())); + found->second->updatePosition(); mTaskScheduler->updateSingleAabb(found->second); return; } diff --git a/apps/openmw/mwphysics/projectile.cpp b/apps/openmw/mwphysics/projectile.cpp index 0a6e9ac123..1a94de01ee 100644 --- a/apps/openmw/mwphysics/projectile.cpp +++ b/apps/openmw/mwphysics/projectile.cpp @@ -3,14 +3,11 @@ #include #include -#include - #include #include "../mwworld/class.hpp" #include "collisiontype.hpp" -#include "memory" #include "mtphysics.hpp" #include "projectile.hpp" @@ -55,7 +52,9 @@ void Projectile::commitPositionChange() std::scoped_lock lock(mMutex); if (mTransformUpdatePending) { - mCollisionObject->setWorldTransform(mLocalTransform); + auto& trans = mCollisionObject->getWorldTransform(); + trans.setOrigin(Misc::Convert::toBullet(mPosition)); + mCollisionObject->setWorldTransform(trans); mTransformUpdatePending = false; } } @@ -63,14 +62,14 @@ void Projectile::commitPositionChange() void Projectile::setPosition(const osg::Vec3f &position) { std::scoped_lock lock(mMutex); - mLocalTransform.setOrigin(Misc::Convert::toBullet(position)); + mPosition = position; mTransformUpdatePending = true; } osg::Vec3f Projectile::getPosition() const { std::scoped_lock lock(mMutex); - return Misc::Convert::toOsg(mLocalTransform.getOrigin()); + return mPosition; } bool Projectile::canTraverseWater() const diff --git a/apps/openmw/mwphysics/projectile.hpp b/apps/openmw/mwphysics/projectile.hpp index 7bcf33b38d..f18c455020 100644 --- a/apps/openmw/mwphysics/projectile.hpp +++ b/apps/openmw/mwphysics/projectile.hpp @@ -6,12 +6,13 @@ #include #include +#include + #include "ptrholder.hpp" class btCollisionObject; class btCollisionShape; class btConvexShape; -class btVector3; namespace osg { @@ -76,7 +77,6 @@ namespace MWPhysics btConvexShape* mConvexShape; std::unique_ptr mCollisionObject; - btTransform mLocalTransform; bool mTransformUpdatePending; bool mCanCrossWaterSurface; bool mCrossedWaterSurface; @@ -84,6 +84,7 @@ namespace MWPhysics MWWorld::Ptr mCaster; MWWorld::Ptr mHitTarget; std::optional mWaterHitPosition; + osg::Vec3f mPosition; btVector3 mHitPosition; btVector3 mHitNormal;