mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-22 10:22:52 +01:00
Implement Vehicle dynamics with Frames instead of Skeleton
This commit is contained in:
parent
f64104600e
commit
1514bd2cc5
@ -70,11 +70,7 @@ public:
|
||||
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});
|
||||
m_part->dummy->setRotation(glm::mat3_cast(r2));
|
||||
}
|
||||
|
||||
private:
|
||||
@ -148,9 +144,6 @@ VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos,
|
||||
: 1.f - info->handling.tractionBias);
|
||||
}
|
||||
|
||||
// Hide all LOD and damage frames.
|
||||
skeleton = new Skeleton;
|
||||
|
||||
setModel(getVehicle()->getModel());
|
||||
setClump(ClumpPtr(getModelInfo<VehicleModelInfo>()->getModel()->clone()));
|
||||
|
||||
@ -557,16 +550,14 @@ bool VehicleObject::takeDamage(const GameObject::DamageInfo& dmg) {
|
||||
|
||||
if (p->normal == nullptr) continue;
|
||||
|
||||
if (skeleton->getData(p->normal->getIndex()).enabled) {
|
||||
/// @todo correct logic
|
||||
float damageradius = 0.1f;
|
||||
auto center = glm::vec3(p->normal->getWorldTransform()[3]);
|
||||
float td = glm::distance(center, dpoint);
|
||||
if (td < damageradius * 1.2f) {
|
||||
setPartState(p, DAM);
|
||||
}
|
||||
/// @todo determine when doors etc. should un-latch
|
||||
/// @todo correct logic
|
||||
float damageradius = 0.1f;
|
||||
auto center = glm::vec3(p->dummy->getWorldTransform()[3]);
|
||||
float td = glm::distance(center, dpoint);
|
||||
if (td < damageradius * 1.2f) {
|
||||
setPartState(p, DAM);
|
||||
}
|
||||
/// @todo determine when doors etc. should un-latch
|
||||
}
|
||||
}
|
||||
|
||||
@ -576,11 +567,11 @@ bool VehicleObject::takeDamage(const GameObject::DamageInfo& dmg) {
|
||||
void VehicleObject::setPartState(VehicleObject::Part* part,
|
||||
VehicleObject::FrameState state) {
|
||||
if (state == VehicleObject::OK) {
|
||||
if (part->normal) skeleton->setEnabled(part->normal, true);
|
||||
if (part->damaged) skeleton->setEnabled(part->damaged, false);
|
||||
if (part->normal) part->normal->setFlag(Atomic::ATOMIC_RENDER, true);
|
||||
if (part->damaged) part->damaged->setFlag(Atomic::ATOMIC_RENDER, false);
|
||||
} else if (state == VehicleObject::DAM) {
|
||||
if (part->normal) skeleton->setEnabled(part->normal, false);
|
||||
if (part->damaged) skeleton->setEnabled(part->damaged, true);
|
||||
if (part->normal) part->normal->setFlag(Atomic::ATOMIC_RENDER, false);
|
||||
if (part->damaged) part->damaged->setFlag(Atomic::ATOMIC_RENDER, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -611,10 +602,7 @@ void VehicleObject::setPartLocked(VehicleObject::Part* part, bool locked) {
|
||||
destroyObjectHinge(part);
|
||||
|
||||
// Restore default bone transform
|
||||
auto dt = part->dummy->getDefaultTranslation();
|
||||
auto dr = glm::quat_cast(part->dummy->getDefaultRotation());
|
||||
Skeleton::FrameTransform tf{dt, dr};
|
||||
skeleton->setData(part->dummy->getIndex(), {tf, tf, true});
|
||||
part->dummy->reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -648,10 +636,10 @@ void VehicleObject::registerPart(ModelFrame* mf) {
|
||||
RW_CHECK(dummynameend != std::string::npos,
|
||||
"Can't create part from non-dummy");
|
||||
auto dummyname = mf->getName().substr(0, dummynameend);
|
||||
auto normal = mf->findDescendant(dummyname + "_hi_ok");
|
||||
auto damage = mf->findDescendant(dummyname + "_hi_dam");
|
||||
auto normalframe = mf->findDescendant(dummyname + "_hi_ok");
|
||||
auto damageframe = mf->findDescendant(dummyname + "_hi_dam");
|
||||
|
||||
if (normal == nullptr && damage == nullptr) {
|
||||
if (normalframe == nullptr && damageframe == nullptr) {
|
||||
// Not actually a useful part, just a dummy.
|
||||
return;
|
||||
}
|
||||
|
@ -36,8 +36,8 @@ public:
|
||||
|
||||
struct Part {
|
||||
ModelFrame* dummy;
|
||||
ModelFrame* normal;
|
||||
ModelFrame* damaged;
|
||||
Atomic* normal;
|
||||
Atomic* damaged;
|
||||
btRigidBody* body;
|
||||
btHingeConstraint* constraint;
|
||||
bool moveToAngle;
|
||||
|
@ -41,8 +41,11 @@ BOOST_AUTO_TEST_CASE(vehicle_parts) {
|
||||
BOOST_REQUIRE(part->normal != nullptr);
|
||||
BOOST_REQUIRE(part->damaged != nullptr);
|
||||
|
||||
BOOST_CHECK_EQUAL(part->normal->getName(), "bonnet_hi_ok");
|
||||
BOOST_CHECK_EQUAL(part->damaged->getName(), "bonnet_hi_dam");
|
||||
BOOST_REQUIRE(part->normal->getFrame());
|
||||
BOOST_REQUIRE(part->damaged->getFrame());
|
||||
|
||||
BOOST_CHECK_EQUAL(part->normal->getFrame()->getName(), "bonnet_hi_ok");
|
||||
BOOST_CHECK_EQUAL(part->damaged->getFrame()->getName(), "bonnet_hi_dam");
|
||||
|
||||
Global::get().e->destroyObject(vehicle);
|
||||
}
|
||||
@ -55,17 +58,16 @@ BOOST_AUTO_TEST_CASE(vehicle_part_vis) {
|
||||
BOOST_REQUIRE(vehicle->getModel() != nullptr);
|
||||
|
||||
VehicleObject::Part* bonnetpart = vehicle->getPart("bonnet_dummy");
|
||||
auto skel = vehicle->skeleton;
|
||||
|
||||
vehicle->setPartState(bonnetpart, VehicleObject::DAM);
|
||||
|
||||
BOOST_CHECK(!skel->getData(bonnetpart->normal->getIndex()).enabled);
|
||||
BOOST_CHECK(skel->getData(bonnetpart->damaged->getIndex()).enabled);
|
||||
BOOST_CHECK((bonnetpart->normal->getFlags() & Atomic::ATOMIC_RENDER) == 0);
|
||||
BOOST_CHECK((bonnetpart->damaged->getFlags() & Atomic::ATOMIC_RENDER) != 0);
|
||||
|
||||
vehicle->setPartState(bonnetpart, VehicleObject::OK);
|
||||
|
||||
BOOST_CHECK(skel->getData(bonnetpart->normal->getIndex()).enabled);
|
||||
BOOST_CHECK(!skel->getData(bonnetpart->damaged->getIndex()).enabled);
|
||||
BOOST_CHECK((bonnetpart->normal->getFlags() & Atomic::ATOMIC_RENDER) != 0);
|
||||
BOOST_CHECK((bonnetpart->damaged->getFlags() & Atomic::ATOMIC_RENDER) == 0);
|
||||
|
||||
Global::get().e->destroyObject(vehicle);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user