diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 66c0208d8d..92956770ef 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 6859022d48..c6c8beb753 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 6363065323..1e69136abb 100644 --- a/apps/openmw/mwphysics/object.cpp +++ b/apps/openmw/mwphysics/object.cpp @@ -27,8 +27,8 @@ namespace MWPhysics mCollisionObject->setUserPointer(this); setScale(ptr.getCellRef().getScale()); - setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude())); - setOrigin(Misc::Convert::toBullet(ptr.getRefData().getPosition().asVec3())); + setRotation(ptr.getRefData().getBaseNode()->getAttitude()); + updatePosition(); commitPositionChange(); mTaskScheduler->addCollisionObject(mCollisionObject.get(), collisionType, CollisionType_Actor|CollisionType_HeightMap|CollisionType_Projectile); @@ -51,17 +51,17 @@ namespace MWPhysics mScaleUpdatePending = true; } - void Object::setRotation(const btQuaternion& quat) + void Object::setRotation(const osg::Quat& quat) { std::unique_lock lock(mPositionMutex); - mLocalTransform.setRotation(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 cae8771809..c640318c78 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 @@ -31,8 +30,8 @@ namespace MWPhysics const Resource::BulletShapeInstance* getShapeInstance() const; void setScale(float scale); - void setRotation(const btQuaternion& quat); - void setOrigin(const btVector3& vec); + void setRotation(const osg::Quat& quat); + 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 833bb9a161..0e616e7415 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -630,7 +630,7 @@ namespace MWPhysics ObjectMap::iterator found = mObjects.find(ptr); if (found != mObjects.end()) { - found->second->setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude())); + found->second->setRotation(ptr.getRefData().getBaseNode()->getAttitude()); mTaskScheduler->updateSingleAabb(found->second); return; } @@ -651,7 +651,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 252da0a687..0e233562c2 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 81c33d2a5e..2ce1a72d5b 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;