1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-04-02 12:06:41 +00:00

Make the Object class manage its collision object and position.

This commit is contained in:
fredzio 2020-10-14 15:55:15 +02:00
parent 4ef36973fb
commit d76cc5d0a9
5 changed files with 52 additions and 15 deletions

View file

@ -30,6 +30,7 @@ namespace MWPhysics
setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude())); setRotation(Misc::Convert::toBullet(ptr.getRefData().getBaseNode()->getAttitude()));
const float* pos = ptr.getRefData().getPosition().pos; const float* pos = ptr.getRefData().getPosition().pos;
setOrigin(btVector3(pos[0], pos[1], pos[2])); setOrigin(btVector3(pos[0], pos[1], pos[2]));
commitPositionChange();
} }
Object::~Object() Object::~Object()
@ -45,17 +46,34 @@ namespace MWPhysics
void Object::setScale(float scale) void Object::setScale(float scale)
{ {
mShapeInstance->setLocalScaling(btVector3(scale, scale, scale)); mScale = { scale,scale,scale };
mScaleUpdatePending = true;
} }
void Object::setRotation(const btQuaternion& quat) void Object::setRotation(const btQuaternion& quat)
{ {
mCollisionObject->getWorldTransform().setRotation(quat); mLocalTransform.setRotation(quat);
mTransformUpdatePending = true;
} }
void Object::setOrigin(const btVector3& vec) void Object::setOrigin(const btVector3& vec)
{ {
mCollisionObject->getWorldTransform().setOrigin(vec); mLocalTransform.setOrigin(vec);
mTransformUpdatePending = true;
}
void Object::commitPositionChange()
{
if (mScaleUpdatePending)
{
mShapeInstance->setLocalScaling(mScale);
mScaleUpdatePending = false;
}
if (mTransformUpdatePending)
{
mCollisionObject->setWorldTransform(mLocalTransform);
mTransformUpdatePending = false;
}
} }
btCollisionObject* Object::getCollisionObject() btCollisionObject* Object::getCollisionObject()
@ -68,6 +86,11 @@ namespace MWPhysics
return mCollisionObject.get(); return mCollisionObject.get();
} }
btTransform Object::getTransform() const
{
return mLocalTransform;
}
bool Object::isSolid() const bool Object::isSolid() const
{ {
return mSolid; return mSolid;
@ -83,10 +106,10 @@ namespace MWPhysics
return !mShapeInstance->mAnimatedShapes.empty(); return !mShapeInstance->mAnimatedShapes.empty();
} }
void Object::animateCollisionShapes(btCollisionWorld* collisionWorld) bool Object::animateCollisionShapes()
{ {
if (mShapeInstance->mAnimatedShapes.empty()) if (mShapeInstance->mAnimatedShapes.empty())
return; return false;
assert (mShapeInstance->getCollisionShape()->isCompound()); assert (mShapeInstance->getCollisionShape()->isCompound());
@ -107,7 +130,7 @@ namespace MWPhysics
// Remove nonexistent nodes from animated shapes map and early out // Remove nonexistent nodes from animated shapes map and early out
mShapeInstance->mAnimatedShapes.erase(recIndex); mShapeInstance->mAnimatedShapes.erase(recIndex);
return; return false;
} }
osg::NodePath nodePath = visitor.mFoundPath; osg::NodePath nodePath = visitor.mFoundPath;
nodePath.erase(nodePath.begin()); nodePath.erase(nodePath.begin());
@ -129,7 +152,6 @@ namespace MWPhysics
if (!(transform == compound->getChildTransform(shapeIndex))) if (!(transform == compound->getChildTransform(shapeIndex)))
compound->updateChildTransform(shapeIndex, transform); compound->updateChildTransform(shapeIndex, transform);
} }
return true;
collisionWorld->updateSingleAabb(mCollisionObject.get());
} }
} }

View file

@ -3,6 +3,7 @@
#include "ptrholder.hpp" #include "ptrholder.hpp"
#include <LinearMath/btTransform.h>
#include <osg/Node> #include <osg/Node>
#include <map> #include <map>
@ -30,13 +31,17 @@ namespace MWPhysics
void setScale(float scale); void setScale(float scale);
void setRotation(const btQuaternion& quat); void setRotation(const btQuaternion& quat);
void setOrigin(const btVector3& vec); void setOrigin(const btVector3& vec);
void commitPositionChange();
btCollisionObject* getCollisionObject(); btCollisionObject* getCollisionObject();
const btCollisionObject* getCollisionObject() const; const btCollisionObject* getCollisionObject() const;
btTransform getTransform() const;
/// Return solid flag. Not used by the object itself, true by default. /// Return solid flag. Not used by the object itself, true by default.
bool isSolid() const; bool isSolid() const;
void setSolid(bool solid); void setSolid(bool solid);
bool isAnimated() const; bool isAnimated() const;
void animateCollisionShapes(btCollisionWorld* collisionWorld); /// @brief update object shape
/// @return true if shape changed
bool animateCollisionShapes();
private: private:
std::unique_ptr<btCollisionObject> mCollisionObject; std::unique_ptr<btCollisionObject> mCollisionObject;
@ -44,6 +49,10 @@ namespace MWPhysics
std::map<int, osg::NodePath> mRecIndexToNodePath; std::map<int, osg::NodePath> mRecIndexToNodePath;
bool mSolid; bool mSolid;
btCollisionWorld* mCollisionWorld; btCollisionWorld* mCollisionWorld;
btVector3 mScale;
btTransform mLocalTransform;
bool mScaleUpdatePending;
bool mTransformUpdatePending;
}; };
} }

View file

@ -768,7 +768,12 @@ namespace MWPhysics
void PhysicsSystem::stepSimulation() void PhysicsSystem::stepSimulation()
{ {
for (Object* animatedObject : mAnimatedObjects) for (Object* animatedObject : mAnimatedObjects)
animatedObject->animateCollisionShapes(mCollisionWorld.get()); if (animatedObject->animateCollisionShapes())
{
auto obj = mObjects.find(animatedObject->getPtr());
assert(obj != mObjects.end());
mCollisionWorld->updateSingleAabb(obj->second->getCollisionObject());
}
#ifndef BT_NO_PROFILE #ifndef BT_NO_PROFILE
CProfileManager::Reset(); CProfileManager::Reset();
@ -780,7 +785,8 @@ namespace MWPhysics
{ {
ObjectMap::iterator found = mObjects.find(object); ObjectMap::iterator found = mObjects.find(object);
if (found != mObjects.end()) if (found != mObjects.end())
found->second->animateCollisionShapes(mCollisionWorld.get()); if (found->second->animateCollisionShapes())
mCollisionWorld->updateSingleAabb(found->second->getCollisionObject());
} }
void PhysicsSystem::debugDraw() void PhysicsSystem::debugDraw()

View file

@ -152,7 +152,7 @@ namespace
? btVector3(distanceFromDoor, 0, 0) ? btVector3(distanceFromDoor, 0, 0)
: btVector3(0, distanceFromDoor, 0); : btVector3(0, distanceFromDoor, 0);
const auto& transform = object->getCollisionObject()->getWorldTransform(); const auto transform = object->getTransform();
const btTransform closedDoorTransform( const btTransform closedDoorTransform(
Misc::Convert::toBullet(makeObjectOsgQuat(ptr.getCellRef().getPosition())), Misc::Convert::toBullet(makeObjectOsgQuat(ptr.getCellRef().getPosition())),
transform.getOrigin() transform.getOrigin()
@ -187,7 +187,7 @@ namespace
*object->getShapeInstance()->getCollisionShape(), *object->getShapeInstance()->getCollisionShape(),
object->getShapeInstance()->getAvoidCollisionShape() object->getShapeInstance()->getAvoidCollisionShape()
}, },
object->getCollisionObject()->getWorldTransform() object->getTransform()
); );
} }
} }

View file

@ -1537,7 +1537,7 @@ namespace MWWorld
*object->getShapeInstance()->getCollisionShape(), *object->getShapeInstance()->getCollisionShape(),
object->getShapeInstance()->getAvoidCollisionShape() object->getShapeInstance()->getAvoidCollisionShape()
}; };
return mNavigator->updateObject(DetourNavigator::ObjectId(object), shapes, object->getCollisionObject()->getWorldTransform()); return mNavigator->updateObject(DetourNavigator::ObjectId(object), shapes, object->getTransform());
} }
const MWPhysics::RayCastingInterface* World::getRayCasting() const const MWPhysics::RayCastingInterface* World::getRayCasting() const
@ -3880,7 +3880,7 @@ namespace MWWorld
btVector3 aabbMax; btVector3 aabbMax;
object->getShapeInstance()->getCollisionShape()->getAabb(btTransform::getIdentity(), aabbMin, aabbMax); object->getShapeInstance()->getCollisionShape()->getAabb(btTransform::getIdentity(), aabbMin, aabbMax);
const auto toLocal = object->getCollisionObject()->getWorldTransform().inverse(); const auto toLocal = object->getTransform().inverse();
const auto localFrom = toLocal(Misc::Convert::toBullet(position)); const auto localFrom = toLocal(Misc::Convert::toBullet(position));
const auto localTo = toLocal(Misc::Convert::toBullet(destination)); const auto localTo = toLocal(Misc::Convert::toBullet(destination));