Make the Actor class manage its collision object and position.

pull/593/head
fredzio 4 years ago
parent 82da2045a9
commit 4ef36973fb

@ -76,6 +76,7 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, btColl
updatePosition();
addCollisionMask(getCollisionMask());
commitPositionChange();
}
Actor::~Actor()
@ -105,8 +106,7 @@ void Actor::addCollisionMask(int collisionMask)
void Actor::updateCollisionMask()
{
mCollisionWorld->removeCollisionObject(mCollisionObject.get());
addCollisionMask(getCollisionMask());
mCollisionObject->getBroadphaseHandle()->m_collisionFilterMask = getCollisionMask();
}
int Actor::getCollisionMask() const
@ -126,29 +126,53 @@ void Actor::updatePosition()
mPosition = position;
mPreviousPosition = position;
mTransformUpdatePending = true;
updateCollisionObjectPosition();
}
void Actor::updateCollisionObjectPosition()
{
btTransform tr = mCollisionObject->getWorldTransform();
osg::Vec3f scaledTranslation = mRotation * osg::componentMultiply(mMeshTranslation, mScale);
osg::Vec3f newPosition = scaledTranslation + mPosition;
tr.setOrigin(Misc::Convert::toBullet(newPosition));
mCollisionObject->setWorldTransform(tr);
mLocalTransform.setOrigin(Misc::Convert::toBullet(newPosition));
mLocalTransform.setRotation(Misc::Convert::toBullet(mRotation));
}
void Actor::commitPositionChange()
{
if (mScaleUpdatePending)
{
mShape->setLocalScaling(Misc::Convert::toBullet(mScale));
mScaleUpdatePending = false;
}
if (mTransformUpdatePending)
{
mCollisionObject->setWorldTransform(mLocalTransform);
mTransformUpdatePending = false;
}
}
osg::Vec3f Actor::getCollisionObjectPosition() const
{
return Misc::Convert::toOsg(mCollisionObject->getWorldTransform().getOrigin());
return Misc::Convert::toOsg(mLocalTransform.getOrigin());
}
void Actor::setPosition(const osg::Vec3f &position)
{
mPreviousPosition = mPosition;
if (mTransformUpdatePending)
{
mCollisionObject->setWorldTransform(mLocalTransform);
mTransformUpdatePending = false;
}
else
{
mPreviousPosition = mPosition;
mPosition = position;
updateCollisionObjectPosition();
mPosition = position;
updateCollisionObjectPosition();
mCollisionObject->setWorldTransform(mLocalTransform);
}
}
osg::Vec3f Actor::getPosition() const
@ -163,11 +187,11 @@ osg::Vec3f Actor::getPreviousPosition() const
void Actor::updateRotation ()
{
btTransform tr = mCollisionObject->getWorldTransform();
if (mRotation == mPtr.getRefData().getBaseNode()->getAttitude())
return;
mRotation = mPtr.getRefData().getBaseNode()->getAttitude();
tr.setRotation(Misc::Convert::toBullet(mRotation));
mCollisionObject->setWorldTransform(tr);
mTransformUpdatePending = true;
updateCollisionObjectPosition();
}
@ -183,12 +207,13 @@ void Actor::updateScale()
mPtr.getClass().adjustScale(mPtr, scaleVec, false);
mScale = scaleVec;
mShape->setLocalScaling(Misc::Convert::toBullet(mScale));
mScaleUpdatePending = true;
scaleVec = osg::Vec3f(scale,scale,scale);
mPtr.getClass().adjustScale(mPtr, scaleVec, true);
mRenderingScale = scaleVec;
mTransformUpdatePending = true;
updateCollisionObjectPosition();
}

@ -5,6 +5,7 @@
#include "ptrholder.hpp"
#include <LinearMath/btTransform.h>
#include <osg/Vec3f>
#include <osg/Quat>
#include <osg/ref_ptr>
@ -61,6 +62,7 @@ namespace MWPhysics
void updatePosition();
void updateCollisionObjectPosition();
void commitPositionChange();
/**
* Returns the half extents of the collision body (scaled according to collision scale)
@ -157,6 +159,9 @@ namespace MWPhysics
osg::Vec3f mRenderingScale;
osg::Vec3f mPosition;
osg::Vec3f mPreviousPosition;
btTransform mLocalTransform;
bool mScaleUpdatePending;
bool mTransformUpdatePending;
osg::Vec3f mForce;
bool mOnGround;

Loading…
Cancel
Save