mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-09 20:32:43 +01:00
Add bullet motion states for dynamic vehicle parts
This commit is contained in:
parent
f860e4c9a7
commit
21d103642e
@ -145,7 +145,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
void registerPart(ModelFrame* mf);
|
void registerPart(ModelFrame* mf);
|
||||||
void createObjectHinge(btTransform &local, Part* part);
|
void createObjectHinge(Part* part);
|
||||||
void destroyObjectHinge(Part* part);
|
void destroyObjectHinge(Part* part);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,6 +47,41 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class VehiclePartMotionState : public btMotionState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VehiclePartMotionState(VehicleObject *object, VehicleObject::Part *part)
|
||||||
|
: m_object(object)
|
||||||
|
, m_part(part)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void getWorldTransform(btTransform& tform) const
|
||||||
|
{
|
||||||
|
const auto& p = m_part->dummy->getDefaultTranslation();
|
||||||
|
const auto& o = glm::toQuat(m_part->dummy->getDefaultRotation());
|
||||||
|
tform.setOrigin(btVector3(p.x, p.y, p.z));
|
||||||
|
tform.setRotation(btQuaternion(o.x, o.y, o.z, o.w));
|
||||||
|
tform = m_object->collision->getBulletBody()->getWorldTransform() * tform;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setWorldTransform(const btTransform& tform)
|
||||||
|
{
|
||||||
|
auto inv = glm::inverse(m_object->getRotation());
|
||||||
|
const auto& rot = tform.getRotation();
|
||||||
|
auto r2 = inv * glm::quat(rot.w(), rot.x(), rot.y(), rot.z());
|
||||||
|
|
||||||
|
auto skeleton = m_object->skeleton;
|
||||||
|
auto& prev = skeleton->getData(m_part->dummy->getIndex()).a;
|
||||||
|
auto next = prev;
|
||||||
|
next.rotation = r2;
|
||||||
|
skeleton->setData(m_part->dummy->getIndex(), { next, prev, true } );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VehicleObject *m_object;
|
||||||
|
VehicleObject::Part *m_part;
|
||||||
|
};
|
||||||
|
|
||||||
VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, const ModelRef& model, VehicleDataHandle data, VehicleInfoHandle info, const glm::u8vec3& prim, const glm::u8vec3& sec)
|
VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, const ModelRef& model, VehicleDataHandle data, VehicleInfoHandle info, const glm::u8vec3& prim, const glm::u8vec3& sec)
|
||||||
: GameObject(engine, pos, rot, model)
|
: GameObject(engine, pos, rot, model)
|
||||||
, steerAngle(0.f)
|
, steerAngle(0.f)
|
||||||
@ -133,7 +168,7 @@ VehicleObject::~VehicleObject()
|
|||||||
|
|
||||||
for(auto& p : dynamicParts)
|
for(auto& p : dynamicParts)
|
||||||
{
|
{
|
||||||
setPartLocked(&p.second, true);
|
destroyObjectHinge(&p.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete collision;
|
delete collision;
|
||||||
@ -364,18 +399,6 @@ void VehicleObject::tickPhysics(float dt)
|
|||||||
// Update hinge object rotations
|
// Update hinge object rotations
|
||||||
for(auto& it : dynamicParts) {
|
for(auto& it : dynamicParts) {
|
||||||
if(it.second.body == nullptr) continue;
|
if(it.second.body == nullptr) continue;
|
||||||
auto inv = glm::inverse(getRotation());
|
|
||||||
auto rot = it.second.body->getWorldTransform().getRotation();
|
|
||||||
//auto pos = it.second.body->getWorldTransform().getOrigin();
|
|
||||||
auto r2 = inv * glm::quat(rot.w(), rot.x(), rot.y(), rot.z());
|
|
||||||
//auto p2 = inv * (glm::vec3(pos.x(), pos.y(), pos.z()) - getPosition());
|
|
||||||
|
|
||||||
auto& prev = skeleton->getData(it.second.dummy->getIndex()).a;
|
|
||||||
auto next = prev;
|
|
||||||
next.rotation = r2;
|
|
||||||
//next.translation = p2;
|
|
||||||
skeleton->setData(it.second.dummy->getIndex(), { next, prev, true } );
|
|
||||||
|
|
||||||
if( it.second.moveToAngle )
|
if( it.second.moveToAngle )
|
||||||
{
|
{
|
||||||
auto angledelta = it.second.targetAngle - it.second.constraint->getHingeAngle();
|
auto angledelta = it.second.targetAngle - it.second.constraint->getHingeAngle();
|
||||||
@ -598,7 +621,7 @@ void VehicleObject::setPartLocked(VehicleObject::Part* part, bool locked)
|
|||||||
{
|
{
|
||||||
if( part->body == nullptr && locked == false )
|
if( part->body == nullptr && locked == false )
|
||||||
{
|
{
|
||||||
createObjectHinge(collision->getBulletBody()->getWorldTransform(), part);
|
createObjectHinge(part);
|
||||||
}
|
}
|
||||||
else if( part->body != nullptr && locked == true )
|
else if( part->body != nullptr && locked == true )
|
||||||
{
|
{
|
||||||
@ -683,7 +706,7 @@ void VehicleObject::registerPart(ModelFrame* mf)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleObject::createObjectHinge(btTransform& local, Part *part)
|
void VehicleObject::createObjectHinge(Part *part)
|
||||||
{
|
{
|
||||||
float sign = glm::sign(part->dummy->getDefaultTranslation().x);
|
float sign = glm::sign(part->dummy->getDefaultTranslation().x);
|
||||||
btVector3 hingeAxis,
|
btVector3 hingeAxis,
|
||||||
@ -738,14 +761,13 @@ void VehicleObject::createObjectHinge(btTransform& local, Part *part)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
btDefaultMotionState* dms = new btDefaultMotionState();
|
auto ms = new VehiclePartMotionState(this, part);
|
||||||
btTransform tr = btTransform::getIdentity();
|
|
||||||
|
|
||||||
auto p = part->dummy->getDefaultTranslation();
|
btTransform tr = btTransform::getIdentity();
|
||||||
auto o = glm::toQuat(part->dummy->getDefaultRotation());
|
const auto& p = part->dummy->getDefaultTranslation();
|
||||||
|
const auto& o = glm::toQuat(part->dummy->getDefaultRotation());
|
||||||
tr.setOrigin(btVector3(p.x, p.y, p.z));
|
tr.setOrigin(btVector3(p.x, p.y, p.z));
|
||||||
tr.setRotation(btQuaternion(o.x, o.y, o.z, o.w));
|
tr.setRotation(btQuaternion(o.x, o.y, o.z, o.w));
|
||||||
dms->setWorldTransform(local * tr);
|
|
||||||
|
|
||||||
btCollisionShape* cs = new btBoxShape( boxSize );
|
btCollisionShape* cs = new btBoxShape( boxSize );
|
||||||
btTransform t; t.setIdentity();
|
btTransform t; t.setIdentity();
|
||||||
@ -754,7 +776,7 @@ void VehicleObject::createObjectHinge(btTransform& local, Part *part)
|
|||||||
btVector3 inertia;
|
btVector3 inertia;
|
||||||
cs->calculateLocalInertia(10.f, inertia);
|
cs->calculateLocalInertia(10.f, inertia);
|
||||||
|
|
||||||
btRigidBody::btRigidBodyConstructionInfo rginfo(10.f, dms, cs, inertia);
|
btRigidBody::btRigidBodyConstructionInfo rginfo(10.f, ms, cs, inertia);
|
||||||
btRigidBody* subObject = new btRigidBody(rginfo);
|
btRigidBody* subObject = new btRigidBody(rginfo);
|
||||||
subObject->setUserPointer(this);
|
subObject->setUserPointer(this);
|
||||||
|
|
||||||
@ -766,28 +788,31 @@ void VehicleObject::createObjectHinge(btTransform& local, Part *part)
|
|||||||
hinge->setLimit(hingeMin, hingeMax);
|
hinge->setLimit(hingeMin, hingeMax);
|
||||||
hinge->setBreakingImpulseThreshold(250.f);
|
hinge->setBreakingImpulseThreshold(250.f);
|
||||||
|
|
||||||
engine->dynamicsWorld->addRigidBody(subObject);
|
|
||||||
engine->dynamicsWorld->addConstraint(hinge, true);
|
|
||||||
|
|
||||||
part->body = subObject;
|
part->body = subObject;
|
||||||
part->constraint = hinge;
|
part->constraint = hinge;
|
||||||
|
|
||||||
|
engine->dynamicsWorld->addRigidBody(part->body);
|
||||||
|
engine->dynamicsWorld->addConstraint(part->constraint, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleObject::destroyObjectHinge(Part* part)
|
void VehicleObject::destroyObjectHinge(Part* part)
|
||||||
{
|
{
|
||||||
if( part->body != nullptr ) {
|
if (part->constraint != nullptr) {
|
||||||
engine->dynamicsWorld->removeConstraint(part->constraint);
|
engine->dynamicsWorld->removeConstraint(part->constraint);
|
||||||
engine->dynamicsWorld->removeRigidBody(part->body);
|
|
||||||
|
|
||||||
delete part->body;
|
|
||||||
delete part->constraint;
|
delete part->constraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (part->body != nullptr ) {
|
||||||
|
engine->dynamicsWorld->removeCollisionObject(part->body);
|
||||||
|
delete part->body->getMotionState();
|
||||||
|
delete part->body;
|
||||||
|
}
|
||||||
|
|
||||||
part->body = nullptr;
|
part->body = nullptr;
|
||||||
part->constraint = nullptr;
|
part->constraint = nullptr;
|
||||||
|
|
||||||
// Reset target.
|
// Reset target.
|
||||||
part->moveToAngle = false;
|
part->moveToAngle = false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleObject::setPrimaryColour(uint8_t color)
|
void VehicleObject::setPrimaryColour(uint8_t color)
|
||||||
|
Loading…
Reference in New Issue
Block a user