1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-21 18:40:01 +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()));
const float* pos = ptr.getRefData().getPosition().pos;
setOrigin(btVector3(pos[0], pos[1], pos[2]));
commitPositionChange();
}
Object::~Object()
@ -45,17 +46,34 @@ namespace MWPhysics
void Object::setScale(float scale)
{
mShapeInstance->setLocalScaling(btVector3(scale, scale, scale));
mScale = { scale,scale,scale };
mScaleUpdatePending = true;
}
void Object::setRotation(const btQuaternion& quat)
{
mCollisionObject->getWorldTransform().setRotation(quat);
mLocalTransform.setRotation(quat);
mTransformUpdatePending = true;
}
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()
@ -68,6 +86,11 @@ namespace MWPhysics
return mCollisionObject.get();
}
btTransform Object::getTransform() const
{
return mLocalTransform;
}
bool Object::isSolid() const
{
return mSolid;
@ -83,10 +106,10 @@ namespace MWPhysics
return !mShapeInstance->mAnimatedShapes.empty();
}
void Object::animateCollisionShapes(btCollisionWorld* collisionWorld)
bool Object::animateCollisionShapes()
{
if (mShapeInstance->mAnimatedShapes.empty())
return;
return false;
assert (mShapeInstance->getCollisionShape()->isCompound());
@ -107,7 +130,7 @@ namespace MWPhysics
// Remove nonexistent nodes from animated shapes map and early out
mShapeInstance->mAnimatedShapes.erase(recIndex);
return;
return false;
}
osg::NodePath nodePath = visitor.mFoundPath;
nodePath.erase(nodePath.begin());
@ -129,7 +152,6 @@ namespace MWPhysics
if (!(transform == compound->getChildTransform(shapeIndex)))
compound->updateChildTransform(shapeIndex, transform);
}
collisionWorld->updateSingleAabb(mCollisionObject.get());
return true;
}
}

View File

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

View File

@ -768,7 +768,12 @@ namespace MWPhysics
void PhysicsSystem::stepSimulation()
{
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
CProfileManager::Reset();
@ -780,7 +785,8 @@ namespace MWPhysics
{
ObjectMap::iterator found = mObjects.find(object);
if (found != mObjects.end())
found->second->animateCollisionShapes(mCollisionWorld.get());
if (found->second->animateCollisionShapes())
mCollisionWorld->updateSingleAabb(found->second->getCollisionObject());
}
void PhysicsSystem::debugDraw()

View File

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

View File

@ -1537,7 +1537,7 @@ namespace MWWorld
*object->getShapeInstance()->getCollisionShape(),
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
@ -3880,7 +3880,7 @@ namespace MWWorld
btVector3 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 localTo = toLocal(Misc::Convert::toBullet(destination));