From 1514bd2cc52759b9269b590d7797cfb1d7f3a1cb Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Sun, 8 Jan 2017 01:36:08 +0000 Subject: [PATCH] Implement Vehicle dynamics with Frames instead of Skeleton --- rwengine/src/objects/VehicleObject.cpp | 44 ++++++++++---------------- rwengine/src/objects/VehicleObject.hpp | 4 +-- tests/test_vehicle.cpp | 16 ++++++---- 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/rwengine/src/objects/VehicleObject.cpp b/rwengine/src/objects/VehicleObject.cpp index f26110cf..30b76773 100644 --- a/rwengine/src/objects/VehicleObject.cpp +++ b/rwengine/src/objects/VehicleObject.cpp @@ -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()->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; } diff --git a/rwengine/src/objects/VehicleObject.hpp b/rwengine/src/objects/VehicleObject.hpp index e9e42253..180497cc 100644 --- a/rwengine/src/objects/VehicleObject.hpp +++ b/rwengine/src/objects/VehicleObject.hpp @@ -36,8 +36,8 @@ public: struct Part { ModelFrame* dummy; - ModelFrame* normal; - ModelFrame* damaged; + Atomic* normal; + Atomic* damaged; btRigidBody* body; btHingeConstraint* constraint; bool moveToAngle; diff --git a/tests/test_vehicle.cpp b/tests/test_vehicle.cpp index 69d79c8e..d5082d8d 100644 --- a/tests/test_vehicle.cpp +++ b/tests/test_vehicle.cpp @@ -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); }