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:
parent
4ef36973fb
commit
d76cc5d0a9
5 changed files with 52 additions and 15 deletions
|
@ -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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue