From 714e4b204192abd99ded58783f7104c68b8e5f3b Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Tue, 7 May 2019 22:58:05 +0100 Subject: [PATCH 1/8] Additional Semicolon Removal --- rwengine/src/render/ObjectRenderer.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/rwengine/src/render/ObjectRenderer.cpp b/rwengine/src/render/ObjectRenderer.cpp index a98f3a6b..47586f44 100644 --- a/rwengine/src/render/ObjectRenderer.cpp +++ b/rwengine/src/render/ObjectRenderer.cpp @@ -365,11 +365,9 @@ void ObjectRenderer::buildRenderList(GameObject* object, RenderList& outList) { case GameObject::Character: renderCharacter(static_cast(object), outList); break; - ; case GameObject::Vehicle: renderVehicle(static_cast(object), outList); break; - ; case GameObject::Pickup: renderPickup(static_cast(object), outList); break; From ff10f3769ec8de994c212e82b626cd3f249b0bbe Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Sat, 11 May 2019 20:33:23 +0100 Subject: [PATCH 2/8] Unify Object Atomic/Clump handling --- rwcore/data/Clump.cpp | 1 + rwengine/src/engine/GameWorld.cpp | 4 +- rwengine/src/engine/Garage.cpp | 2 +- rwengine/src/engine/Payphone.cpp | 2 +- rwengine/src/objects/CharacterObject.cpp | 5 +- rwengine/src/objects/CharacterObject.hpp | 2 +- rwengine/src/objects/CutsceneObject.cpp | 5 +- rwengine/src/objects/CutsceneObject.hpp | 2 +- rwengine/src/objects/GameObject.cpp | 3 ++ rwengine/src/objects/GameObject.hpp | 52 ++++++++++--------- rwengine/src/objects/VehicleObject.cpp | 3 +- rwengine/src/objects/VehicleObject.hpp | 2 +- rwengine/src/script/ScriptFunctions.hpp | 4 +- .../src/script/modules/GTA3ModuleImpl.inl | 2 +- rwgame/states/IngameState.cpp | 2 +- rwviewer/ViewerWidget.cpp | 4 +- tests/test_Character.cpp | 2 +- tests/test_Vehicle.cpp | 4 +- tests/test_Weapon.cpp | 2 +- 19 files changed, 53 insertions(+), 50 deletions(-) diff --git a/rwcore/data/Clump.cpp b/rwcore/data/Clump.cpp index eb6a2621..6f2d2945 100644 --- a/rwcore/data/Clump.cpp +++ b/rwcore/data/Clump.cpp @@ -118,6 +118,7 @@ ClumpPtr Clump::clone() const { auto newroot = rootframe_->cloneHierarchy(); auto clump = std::make_shared(); clump->setFrame(newroot); + clump->boundingRadius = boundingRadius; // This isn't the most optimal implementation, but this code is likely // to be replaced soon. diff --git a/rwengine/src/engine/GameWorld.cpp b/rwengine/src/engine/GameWorld.cpp index bb942547..b3a69cfe 100644 --- a/rwengine/src/engine/GameWorld.cpp +++ b/rwengine/src/engine/GameWorld.cpp @@ -227,7 +227,7 @@ CutsceneObject* GameWorld::createCutsceneObject(const uint16_t id, if (id == 0) { auto playerobj = pedestrianPool.find(state->playerObject); if (playerobj) { - model = playerobj->getModel(); + model = playerobj->getClump(); } } @@ -1050,7 +1050,7 @@ GameWorld::findOverlappingObjects(const glm::vec3 ¢er, auto checkObjects = [&](const auto& objects) { for (auto& p : objects) { const auto& object = p.second.get(); - auto objectBounds = object->getModel()->getBoundingRadius(); + auto objectBounds = object->getClump()->getBoundingRadius(); if (glm::distance(center, object->getPosition()) < radius + objectBounds) { overlapping.push_back(object); diff --git a/rwengine/src/engine/Garage.cpp b/rwengine/src/engine/Garage.cpp index bed11d71..c1214cd2 100644 --- a/rwengine/src/engine/Garage.cpp +++ b/rwengine/src/engine/Garage.cpp @@ -38,7 +38,7 @@ Garage::Garage(GameWorld* engine_, size_t id_, const glm::vec3& coord0, for (const auto& p : engine->instancePool.objects) { const auto inst = static_cast(p.second.get()); - if (!inst->getModel()) { + if (!inst->getClump()) { continue; } diff --git a/rwengine/src/engine/Payphone.cpp b/rwengine/src/engine/Payphone.cpp index e9f8051f..eb4dec3c 100644 --- a/rwengine/src/engine/Payphone.cpp +++ b/rwengine/src/engine/Payphone.cpp @@ -16,7 +16,7 @@ Payphone::Payphone(GameWorld* engine_, size_t id_, const glm::vec2& coord) // Find payphone object, original game does this differently for (const auto& p : engine->instancePool.objects) { auto o = p.second.get(); - if (!o->getModel()) { + if (!o->getClump()) { continue; } if (o->getModelInfo()->name != "phonebooth1") { diff --git a/rwengine/src/objects/CharacterObject.cpp b/rwengine/src/objects/CharacterObject.cpp index c260a8aa..5816b50f 100644 --- a/rwengine/src/objects/CharacterObject.cpp +++ b/rwengine/src/objects/CharacterObject.cpp @@ -43,9 +43,8 @@ CharacterObject::CharacterObject(GameWorld* engine, const glm::vec3& pos, ai::CharacterController* controller) : GameObject(engine, pos, rot, modelinfo), controller(controller) { auto info = getModelInfo(); - setClump(info->getModel()->clone()); if (info->getModel()) { - setModel(info->getModel()); + setModel(info->getModel()->clone()); animator = std::make_unique(getClump()); createActor(); @@ -70,7 +69,7 @@ void CharacterObject::createActor(const glm::vec2& size) { } // Don't create anything without a valid model. - if (getModel()) { + if (getClump()) { btTransform tf; tf.setIdentity(); tf.setOrigin(btVector3(position.x, position.y, position.z)); diff --git a/rwengine/src/objects/CharacterObject.hpp b/rwengine/src/objects/CharacterObject.hpp index 816bd303..9f8acdbe 100644 --- a/rwengine/src/objects/CharacterObject.hpp +++ b/rwengine/src/objects/CharacterObject.hpp @@ -53,7 +53,7 @@ class GameWorld; * @brief The CharacterObject struct * Implements Character object behaviours. */ -class CharacterObject final : public GameObject, public ClumpObject { +class CharacterObject final : public GameObject { private: CharacterState currentState{}; diff --git a/rwengine/src/objects/CutsceneObject.cpp b/rwengine/src/objects/CutsceneObject.cpp index 27e37cdc..bf13d0a5 100644 --- a/rwengine/src/objects/CutsceneObject.cpp +++ b/rwengine/src/objects/CutsceneObject.cpp @@ -10,12 +10,11 @@ CutsceneObject::CutsceneObject(GameWorld *engine, const glm::vec3 &pos, BaseModelInfo *modelinfo) : GameObject(engine, pos, rot, modelinfo) { if (model) { - setModel(model); + setModel(model->clone()); } else { - setModel(getModelInfo()->getModel()); + setModel(getModelInfo()->getModel()->clone()); } - setClump(getModel()->clone()); animator = std::make_unique(getClump()); } diff --git a/rwengine/src/objects/CutsceneObject.hpp b/rwengine/src/objects/CutsceneObject.hpp index 1094f267..18042810 100644 --- a/rwengine/src/objects/CutsceneObject.hpp +++ b/rwengine/src/objects/CutsceneObject.hpp @@ -12,7 +12,7 @@ class ModelFrame; /** * @brief Object type used for cutscene animations. */ -class CutsceneObject final : public GameObject, public ClumpObject { +class CutsceneObject final : public GameObject { GameObject* _parent = nullptr; ModelFrame* _bone = nullptr; diff --git a/rwengine/src/objects/GameObject.cpp b/rwengine/src/objects/GameObject.cpp index cf6d9aae..07a6c1fa 100644 --- a/rwengine/src/objects/GameObject.cpp +++ b/rwengine/src/objects/GameObject.cpp @@ -6,6 +6,9 @@ #include "engine/Animator.hpp" +const AtomicPtr GameObject::NullAtomic; +const ClumpPtr GameObject::NullClump; + GameObject::~GameObject() { if (modelinfo_) { modelinfo_->removeReference(); diff --git a/rwengine/src/objects/GameObject.hpp b/rwengine/src/objects/GameObject.hpp index f6566c2d..93148d16 100644 --- a/rwengine/src/objects/GameObject.hpp +++ b/rwengine/src/objects/GameObject.hpp @@ -2,6 +2,7 @@ #define _RWENGINE_GAMEOBJECT_HPP_ #include +#include #include #include @@ -28,10 +29,11 @@ class GameObject { BaseModelInfo* modelinfo_; - /** - * Model used for rendering - */ - ClumpPtr model_ = nullptr; + using Model = std::variant; + Model model_; + + static const AtomicPtr NullAtomic; + static const ClumpPtr NullClump; protected: void changeModelInfo(BaseModelInfo* next) { @@ -92,16 +94,30 @@ public: return static_cast(modelinfo_); } - /** - * @return The model used in rendering - */ - ClumpPtr getModel() const { + const Model& getModel() const { return model_; } - /** - * Changes the current model, used for re-dressing chars - */ + const AtomicPtr& getAtomic() const { + if (auto atomic = std::get_if(&model_)) + { + return *atomic; + } + return NullAtomic; + } + + const ClumpPtr& getClump() const { + if (auto clump = std::get_if(&model_)) + { + return *clump; + } + return NullClump; + } + + void setModel(const AtomicPtr& model) { + model_ = model; + } + void setModel(const ClumpPtr& model) { model_ = model; } @@ -265,18 +281,4 @@ private: ObjectLifetime lifetime = GameObject::UnknownLifetime; }; -class ClumpObject { - ClumpPtr clump_; - -protected: - void setClump(const ClumpPtr& ptr) { - clump_ = ptr; - } - -public: - const ClumpPtr& getClump() const { - return clump_; - } -}; - #endif // __GAMEOBJECTS_HPP__ diff --git a/rwengine/src/objects/VehicleObject.cpp b/rwengine/src/objects/VehicleObject.cpp index 991288f0..b52960e4 100644 --- a/rwengine/src/objects/VehicleObject.cpp +++ b/rwengine/src/objects/VehicleObject.cpp @@ -173,8 +173,7 @@ VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos, wheelsRotation.push_back(0.f); } - setModel(getVehicle()->getModel()); - setClump(getModelInfo()->getModel()->clone()); + setModel(getVehicle()->getModel()->clone()); setupModel(); } diff --git a/rwengine/src/objects/VehicleObject.hpp b/rwengine/src/objects/VehicleObject.hpp index 39e9933d..b7ccdcea 100644 --- a/rwengine/src/objects/VehicleObject.hpp +++ b/rwengine/src/objects/VehicleObject.hpp @@ -39,7 +39,7 @@ struct btVehicleRaycaster; * @class VehicleObject * Implements Vehicle behaviours. */ -class VehicleObject final : public GameObject, public ClumpObject { +class VehicleObject final : public GameObject { private: float steerAngle{0.f}; float throttle{0.f}; diff --git a/rwengine/src/script/ScriptFunctions.hpp b/rwengine/src/script/ScriptFunctions.hpp index 03a2f1cb..5eda08a1 100644 --- a/rwengine/src/script/ScriptFunctions.hpp +++ b/rwengine/src/script/ScriptFunctions.hpp @@ -219,9 +219,9 @@ ScriptModel getModel(const ScriptArguments& args, ScriptModel model); inline void clearSpaceForObject(const ScriptArguments& args, GameObject* object) { - RW_ASSERT(object->getModel()); + RW_ASSERT(object->getClump()); - auto radius = object->getModel()->getBoundingRadius(); + auto radius = object->getClump()->getBoundingRadius(); const auto& overlapping = args.getWorld()->findOverlappingObjects( object->getPosition(), radius); diff --git a/rwengine/src/script/modules/GTA3ModuleImpl.inl b/rwengine/src/script/modules/GTA3ModuleImpl.inl index c6cf0955..06ae9e27 100644 --- a/rwengine/src/script/modules/GTA3ModuleImpl.inl +++ b/rwengine/src/script/modules/GTA3ModuleImpl.inl @@ -10900,7 +10900,7 @@ void opcode_03b6(const ScriptArguments& args, ScriptVec3 coord, const ScriptFloa for(auto& p : args.getWorld()->instancePool.objects) { auto o = p.second.get(); - if( !o->getModel() ) continue; + if( !o->getClump() ) continue; if( o->getModelInfo()->name != oldmodel ) continue; float d = glm::distance(coord, o->getPosition()); if( d < radius ) { diff --git a/rwgame/states/IngameState.cpp b/rwgame/states/IngameState.cpp index cf2913cf..9d08ccac 100644 --- a/rwgame/states/IngameState.cpp +++ b/rwgame/states/IngameState.cpp @@ -448,7 +448,7 @@ const ViewCamera& IngameState::getCamera(float alpha) { if (target->type() == GameObject::Vehicle) { auto vehicle = static_cast(target); - auto model = vehicle->getModel(); + auto model = vehicle->getClump(); auto maxDist = model->getBoundingRadius() * 2.f; viewDistance = viewDistance + maxDist; lookTargetPosition.z += (vehicle->info->handling.dimensions.z * 0.5f); diff --git a/rwviewer/ViewerWidget.cpp b/rwviewer/ViewerWidget.cpp index 49441402..952312fc 100644 --- a/rwviewer/ViewerWidget.cpp +++ b/rwviewer/ViewerWidget.cpp @@ -230,8 +230,8 @@ void ViewerWidget::showObject(quint16 item) { RW_CHECK(_object != nullptr, "Dummy Object is null"); - if (_object->getModel()) { - auto objectRadius = _object->getModel()->getBoundingRadius(); + if (_object->getClump()) { + auto objectRadius = _object->getClump()->getBoundingRadius(); viewDistance = objectRadius * 2; viewAngles.x = glm::radians(-45.f); viewAngles.y = glm::radians(22.5f); diff --git a/tests/test_Character.cpp b/tests/test_Character.cpp index c34d819b..07e44062 100644 --- a/tests/test_Character.cpp +++ b/tests/test_Character.cpp @@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(test_activities) { VehicleObject* vehicle = Global::get().e->createVehicle( 90u, glm::vec3(10.f, 0.f, 0.f), glm::quat{1.0f,0.0f,0.0f,0.0f}); BOOST_REQUIRE(vehicle != nullptr); - BOOST_REQUIRE(vehicle->getModel() != nullptr); + BOOST_REQUIRE(vehicle->getClump() != nullptr); auto character = Global::get().e->createPedestrian(1, {0.f, 0.f, 0.f}); BOOST_REQUIRE(character != nullptr); diff --git a/tests/test_Vehicle.cpp b/tests/test_Vehicle.cpp index c032ea89..f4fdb944 100644 --- a/tests/test_Vehicle.cpp +++ b/tests/test_Vehicle.cpp @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(vehicle_parts) { Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}); BOOST_REQUIRE(vehicle); - BOOST_REQUIRE(vehicle->getModel()); + BOOST_REQUIRE(vehicle->getClump()); VehicleObject::Part* part = vehicle->getPart("bonnet_dummy"); @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(vehicle_part_vis) { Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}); BOOST_REQUIRE(vehicle); - BOOST_REQUIRE(vehicle->getModel()); + BOOST_REQUIRE(vehicle->getClump()); VehicleObject::Part* bonnetpart = vehicle->getPart("bonnet_dummy"); diff --git a/tests/test_Weapon.cpp b/tests/test_Weapon.cpp index 92ec10fb..ba536fca 100644 --- a/tests/test_Weapon.cpp +++ b/tests/test_Weapon.cpp @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(TestDoWeaponScan, DATA_TEST_PREDICATE) { // Test RADIUS scan auto character = Global::get().e->createPedestrian(1, {0.f, 0.f, 0.f}); BOOST_REQUIRE(character != nullptr); - BOOST_REQUIRE(character->getModel() != nullptr); + BOOST_REQUIRE(character->getClump() != nullptr); BOOST_REQUIRE(character->physObject != nullptr); WeaponScan scan(10.f, {0.f, 0.f, 10.f}, {0.f, 0.f, -10.f}); From e55688e21ce7b902e6e944acfec432e29a93763d Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Sun, 12 May 2019 00:49:07 +0100 Subject: [PATCH 3/8] Render Projectile and Pickup Objects via Atomics --- rwengine/src/objects/PickupObject.cpp | 5 +++++ rwengine/src/objects/ProjectileObject.cpp | 6 ++++++ rwengine/src/render/ObjectRenderer.cpp | 20 ++++---------------- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/rwengine/src/objects/PickupObject.cpp b/rwengine/src/objects/PickupObject.cpp index cb66e38b..4d7ce4a1 100644 --- a/rwengine/src/objects/PickupObject.cpp +++ b/rwengine/src/objects/PickupObject.cpp @@ -271,6 +271,11 @@ PickupObject::PickupObject(GameWorld* world, const glm::vec3& position, setEnabled(true); setCollected(false); + + auto modelData = getModelInfo(); + auto atomic = modelData->getAtomic(0)->clone(); + atomic->setFrame(std::make_shared()); + setModel(std::move(atomic)); } PickupObject::~PickupObject() { diff --git a/rwengine/src/objects/ProjectileObject.cpp b/rwengine/src/objects/ProjectileObject.cpp index 185257f1..6002fd9d 100644 --- a/rwengine/src/objects/ProjectileObject.cpp +++ b/rwengine/src/objects/ProjectileObject.cpp @@ -158,6 +158,12 @@ ProjectileObject::ProjectileObject(GameWorld* world, const glm::vec3& position, _ghostBody.get(), btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::AllFilter); } + + const auto& modelData = world->data->findModelInfo( + getProjectileInfo().weapon->modelID); + auto atomic = modelData->getAtomic(0)->clone(); + atomic->setFrame(std::make_shared()); + setModel(std::move(atomic)); } ProjectileObject::~ProjectileObject() { diff --git a/rwengine/src/render/ObjectRenderer.cpp b/rwengine/src/render/ObjectRenderer.cpp index 47586f44..3d23245d 100644 --- a/rwengine/src/render/ObjectRenderer.cpp +++ b/rwengine/src/render/ObjectRenderer.cpp @@ -313,14 +313,8 @@ void ObjectRenderer::renderPickup(PickupObject* pickup, RenderList& outList) { glm::translate(glm::mat4(1.0f), pickup->getPosition()); modelMatrix = glm::rotate(modelMatrix, m_world->getGameTime() * kRotationSpeedCoeff, glm::vec3(0.f, 0.f, 1.f)); - - auto odata = pickup->getModelInfo(); - - RW_CHECK(odata, "Failed to read modelinfo for Pickup"); - - auto atomic = odata->getAtomic(0); - - renderAtomic(atomic, modelMatrix, nullptr, outList); + const auto& atomic = pickup->getAtomic(); + renderAtomic(atomic.get(), modelMatrix, nullptr, outList); } void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene, @@ -346,14 +340,8 @@ void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene, void ObjectRenderer::renderProjectile(ProjectileObject* projectile, RenderList& outList) { glm::mat4 modelMatrix = projectile->getTimeAdjustedTransform(m_renderAlpha); - - auto odata = m_world->data->findModelInfo( - projectile->getProjectileInfo().weapon->modelID); - - RW_CHECK(odata, "Failed to read modelinfo"); - - auto atomic = odata->getAtomic(0); - renderAtomic(atomic, modelMatrix, nullptr, outList); + const auto& atomic = projectile->getAtomic(); + renderAtomic(atomic.get(), modelMatrix, nullptr, outList); } void ObjectRenderer::buildRenderList(GameObject* object, RenderList& outList) { From 5d6e3598cabae3b255a7dd266d13bb206acb9047 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 13 May 2019 00:01:47 +0100 Subject: [PATCH 4/8] Expose GameObjectMotionState --- rwengine/src/dynamics/CollisionInstance.cpp | 37 ++++++++------------- rwengine/src/dynamics/CollisionInstance.hpp | 17 ++++++++-- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/rwengine/src/dynamics/CollisionInstance.cpp b/rwengine/src/dynamics/CollisionInstance.cpp index b58f9043..d61de4c3 100644 --- a/rwengine/src/dynamics/CollisionInstance.cpp +++ b/rwengine/src/dynamics/CollisionInstance.cpp @@ -21,30 +21,21 @@ #include "objects/GameObject.hpp" #include "objects/VehicleInfo.hpp" -class GameObjectMotionState : public btMotionState { -public: - GameObjectMotionState(GameObject* object) : m_object(object) { - } +void GameObjectMotionState::getWorldTransform(btTransform& tform) const { + auto& position = m_object->getPosition(); + auto& rotation = m_object->getRotation(); + tform.setOrigin(btVector3(position.x, position.y, position.z)); + tform.setRotation( + btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); +} - void getWorldTransform(btTransform& tform) const override { - auto& position = m_object->getPosition(); - auto& rotation = m_object->getRotation(); - tform.setOrigin(btVector3(position.x, position.y, position.z)); - tform.setRotation( - btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); - } - - void setWorldTransform(const btTransform& tform) override { - auto& o = tform.getOrigin(); - auto r = tform.getRotation(); - glm::vec3 position(o.x(), o.y(), o.z()); - glm::quat rotation(r.w(), r.x(), r.y(), r.z()); - m_object->updateTransform(position, rotation); - } - -private: - GameObject* m_object; -}; +void GameObjectMotionState::setWorldTransform(const btTransform& tform) { + auto& o = tform.getOrigin(); + auto r = tform.getRotation(); + glm::vec3 position(o.x(), o.y(), o.z()); + glm::quat rotation(r.w(), r.x(), r.y(), r.z()); + m_object->updateTransform(position, rotation); +} CollisionInstance::~CollisionInstance() { if (m_body) { diff --git a/rwengine/src/dynamics/CollisionInstance.hpp b/rwengine/src/dynamics/CollisionInstance.hpp index f47ad9ab..cf3a6fe0 100644 --- a/rwengine/src/dynamics/CollisionInstance.hpp +++ b/rwengine/src/dynamics/CollisionInstance.hpp @@ -4,10 +4,10 @@ #include #include +#include + class btCollisionShape; class btCompoundShape; -class btMotionState; -class btRigidBody; class btTriangleIndexVertexArray; struct CollisionModel; @@ -15,6 +15,19 @@ class GameObject; struct DynamicObjectData; struct VehicleHandlingInfo; +class GameObjectMotionState : public btMotionState { +public: + explicit GameObjectMotionState(GameObject* object) : m_object(object) { + } + + void getWorldTransform(btTransform& tform) const override; + + void setWorldTransform(const btTransform& tform) override; + +private: + GameObject* m_object; +}; + /** * @brief CollisionInstance stores bullet body information */ From a3e924ff3cdf99200f54aa4513a4fe004a8922f2 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 13 May 2019 20:23:10 +0100 Subject: [PATCH 5/8] Use MotionState to move projectiles --- rwengine/src/objects/GameObject.cpp | 20 ++++++++++++++++++++ rwengine/src/objects/GameObject.hpp | 7 +------ rwengine/src/objects/InstanceObject.cpp | 8 -------- rwengine/src/objects/InstanceObject.hpp | 2 -- rwengine/src/objects/ProjectileObject.cpp | 12 ++++-------- rwengine/src/objects/ProjectileObject.hpp | 5 +++-- rwengine/src/objects/VehicleObject.cpp | 8 -------- rwengine/src/objects/VehicleObject.hpp | 2 -- rwengine/src/render/ObjectRenderer.cpp | 3 +-- 9 files changed, 29 insertions(+), 38 deletions(-) diff --git a/rwengine/src/objects/GameObject.cpp b/rwengine/src/objects/GameObject.cpp index 07a6c1fa..25579af9 100644 --- a/rwengine/src/objects/GameObject.cpp +++ b/rwengine/src/objects/GameObject.cpp @@ -1,5 +1,7 @@ #include "objects/GameObject.hpp" +#include + #include #include #include @@ -40,3 +42,21 @@ glm::mat4 GameObject::getTimeAdjustedTransform(float alpha) const { t = t * glm::mat4_cast(glm::slerp(_lastRotation, getRotation(), alpha)); return t; } + +void GameObject::updateTransform(const glm::vec3& pos, const glm::quat& rot) { + _lastPosition = position; + _lastRotation = rotation; + position = pos; + rotation = rot; + + const auto& clump = getClump(); + const auto& atomic = getAtomic(); + if (clump) { + clump->getFrame()->setRotation(glm::mat3_cast(rot)); + clump->getFrame()->setTranslation(pos); + } + if (atomic) { + atomic->getFrame()->setRotation(glm::mat3_cast(rot)); + atomic->getFrame()->setTranslation(pos); + } +} diff --git a/rwengine/src/objects/GameObject.hpp b/rwengine/src/objects/GameObject.hpp index 93148d16..aae6862f 100644 --- a/rwengine/src/objects/GameObject.hpp +++ b/rwengine/src/objects/GameObject.hpp @@ -270,12 +270,7 @@ public: } } - virtual void updateTransform(const glm::vec3& pos, const glm::quat& rot) { - _lastPosition = position; - _lastRotation = rotation; - position = pos; - rotation = rot; - } + void updateTransform(const glm::vec3& pos, const glm::quat& rot); private: ObjectLifetime lifetime = GameObject::UnknownLifetime; diff --git a/rwengine/src/objects/InstanceObject.cpp b/rwengine/src/objects/InstanceObject.cpp index 37a45e18..80191ab8 100644 --- a/rwengine/src/objects/InstanceObject.cpp +++ b/rwengine/src/objects/InstanceObject.cpp @@ -270,11 +270,3 @@ void InstanceObject::setSolid(bool solid) { } body->getBulletBody()->setCollisionFlags(flags); } - -void InstanceObject::updateTransform(const glm::vec3& pos, - const glm::quat& rot) { - position = pos; - rotation = rot; - getAtomic()->getFrame()->setRotation(glm::mat3_cast(rot)); - getAtomic()->getFrame()->setTranslation(pos); -} diff --git a/rwengine/src/objects/InstanceObject.hpp b/rwengine/src/objects/InstanceObject.hpp index 3e36f1b1..eef7d3b7 100644 --- a/rwengine/src/objects/InstanceObject.hpp +++ b/rwengine/src/objects/InstanceObject.hpp @@ -86,8 +86,6 @@ public: float getHealth() const { return health; } - - void updateTransform(const glm::vec3& pos, const glm::quat& rot) override; }; #endif diff --git a/rwengine/src/objects/ProjectileObject.cpp b/rwengine/src/objects/ProjectileObject.cpp index 6002fd9d..58144f26 100644 --- a/rwengine/src/objects/ProjectileObject.cpp +++ b/rwengine/src/objects/ProjectileObject.cpp @@ -117,8 +117,9 @@ void ProjectileObject::cleanup() { ProjectileObject::ProjectileObject(GameWorld* world, const glm::vec3& position, const ProjectileObject::ProjectileInfo& info) - : GameObject(world, position, glm::quat{1.0f,0.0f,0.0f,0.0f}, nullptr) - , _info(info) { + : GameObject(world, position, glm::quat{1.0f, 0.0f, 0.0f, 0.0f}, nullptr) + , _info(info) + , _motionState(this) { _shape = std::make_unique(0.45f); btVector3 inertia(0.f, 0.f, 0.f); _shape->calculateLocalInertia(1.f, inertia); @@ -130,6 +131,7 @@ ProjectileObject::ProjectileObject(GameWorld* world, const glm::vec3& position, ws.setOrigin(btVector3(position.x, position.y, position.z)); riginfo.m_startWorldTransform = ws; riginfo.m_mass = 1.f; + riginfo.m_motionState = &_motionState; _body = std::make_unique(riginfo); _body->setUserPointer(this); @@ -173,12 +175,6 @@ ProjectileObject::~ProjectileObject() { void ProjectileObject::tick(float dt) { if (_body == nullptr) return; - auto& bttr = _body->getWorldTransform(); - position = {bttr.getOrigin().x(), bttr.getOrigin().y(), - bttr.getOrigin().z()}; - auto r = bttr.getRotation(); - rotation = {r.x(), r.y(), r.z(), r.w()}; - _info.time -= dt; if (_ghostBody) { diff --git a/rwengine/src/objects/ProjectileObject.hpp b/rwengine/src/objects/ProjectileObject.hpp index 542b97eb..c7c89d85 100644 --- a/rwengine/src/objects/ProjectileObject.hpp +++ b/rwengine/src/objects/ProjectileObject.hpp @@ -1,13 +1,12 @@ #ifndef _RWENGINE_PROJECTILEOBJECT_HPP_ #define _RWENGINE_PROJECTILEOBJECT_HPP_ +#include #include #include "render/VisualFX.hpp" - class GameWorld; class btPairCachingGhostObject; -class btRigidBody; class btSphereShape; struct WeaponData; @@ -51,6 +50,8 @@ private: /** Used for RPGs and Molotov collision detection */ std::unique_ptr _ghostBody; + GameObjectMotionState _motionState; + bool _exploded = false; void checkPhysicsContact(); diff --git a/rwengine/src/objects/VehicleObject.cpp b/rwengine/src/objects/VehicleObject.cpp index b52960e4..a4374809 100644 --- a/rwengine/src/objects/VehicleObject.cpp +++ b/rwengine/src/objects/VehicleObject.cpp @@ -309,14 +309,6 @@ void VehicleObject::setRotation(const glm::quat& orientation) { GameObject::setRotation(orientation); } -void VehicleObject::updateTransform(const glm::vec3& pos, - const glm::quat& rot) { - position = pos; - rotation = rot; - getClump()->getFrame()->setRotation(glm::mat3_cast(rot)); - getClump()->getFrame()->setTranslation(pos); -} - void VehicleObject::setExtraEnabled(size_t extra, bool enabled) { auto atomic = extras_.at(extra); if (!atomic) { diff --git a/rwengine/src/objects/VehicleObject.hpp b/rwengine/src/objects/VehicleObject.hpp index b7ccdcea..fac730ff 100644 --- a/rwengine/src/objects/VehicleObject.hpp +++ b/rwengine/src/objects/VehicleObject.hpp @@ -106,8 +106,6 @@ public: glm::vec3 getCenterOffset() override; - void updateTransform(const glm::vec3& pos, const glm::quat& rot) override; - VehicleModelInfo* getVehicle() const { return getModelInfo(); } diff --git a/rwengine/src/render/ObjectRenderer.cpp b/rwengine/src/render/ObjectRenderer.cpp index 3d23245d..fb08208b 100644 --- a/rwengine/src/render/ObjectRenderer.cpp +++ b/rwengine/src/render/ObjectRenderer.cpp @@ -339,9 +339,8 @@ void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene, void ObjectRenderer::renderProjectile(ProjectileObject* projectile, RenderList& outList) { - glm::mat4 modelMatrix = projectile->getTimeAdjustedTransform(m_renderAlpha); const auto& atomic = projectile->getAtomic(); - renderAtomic(atomic.get(), modelMatrix, nullptr, outList); + renderAtomic(atomic.get(), glm::mat4(1.0f), nullptr, outList); } void ObjectRenderer::buildRenderList(GameObject* object, RenderList& outList) { From 8af04b48cf2a532af321fbb7116f538b260bd57d Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 13 May 2019 21:24:18 +0100 Subject: [PATCH 6/8] Update pickup frame position --- rwengine/src/objects/PickupObject.cpp | 7 +++++++ rwengine/src/render/ObjectRenderer.cpp | 8 +------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/rwengine/src/objects/PickupObject.cpp b/rwengine/src/objects/PickupObject.cpp index 4d7ce4a1..25c5bf6f 100644 --- a/rwengine/src/objects/PickupObject.cpp +++ b/rwengine/src/objects/PickupObject.cpp @@ -276,6 +276,7 @@ PickupObject::PickupObject(GameWorld* world, const glm::vec3& position, auto atomic = modelData->getAtomic(0)->clone(); atomic->setFrame(std::make_shared()); setModel(std::move(atomic)); + updateTransform(getPosition(), getRotation()); } PickupObject::~PickupObject() { @@ -318,6 +319,12 @@ void PickupObject::tick(float dt) { glm::vec4(red / 255.f, green / 255.f, blue / 255.f, 1.f) * colourValue; if (m_enabled) { + static constexpr float kRotationSpeedCoeff = 3.0f; + updateTransform( + getPosition(), + glm::angleAxis(engine->getGameTime() * kRotationSpeedCoeff, + glm::vec3(0.f, 0.f, 1.f))); + // Sort out interactions with things that may or may not be players. btManifoldArray manifoldArray; btBroadphasePairArray& pairArray = diff --git a/rwengine/src/render/ObjectRenderer.cpp b/rwengine/src/render/ObjectRenderer.cpp index fb08208b..0fc5d44a 100644 --- a/rwengine/src/render/ObjectRenderer.cpp +++ b/rwengine/src/render/ObjectRenderer.cpp @@ -307,14 +307,8 @@ void ObjectRenderer::renderVehicle(VehicleObject* vehicle, void ObjectRenderer::renderPickup(PickupObject* pickup, RenderList& outList) { if (!pickup->isEnabled()) return; - - static constexpr float kRotationSpeedCoeff = 3.0f; - glm::mat4 modelMatrix = - glm::translate(glm::mat4(1.0f), pickup->getPosition()); - modelMatrix = glm::rotate(modelMatrix, m_world->getGameTime() * kRotationSpeedCoeff, - glm::vec3(0.f, 0.f, 1.f)); const auto& atomic = pickup->getAtomic(); - renderAtomic(atomic.get(), modelMatrix, nullptr, outList); + renderAtomic(atomic.get(), glm::mat4(1.f), nullptr, outList); } void ObjectRenderer::renderCutsceneObject(CutsceneObject* cutscene, From 77b405b7c5de9f180e98a10a085be25c34f47421 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Mon, 13 May 2019 21:36:16 +0100 Subject: [PATCH 7/8] Remove getTimeAdjustedTransform --- rwengine/src/objects/GameObject.cpp | 11 +---------- rwengine/src/objects/GameObject.hpp | 23 +---------------------- rwengine/src/render/GameRenderer.cpp | 7 ++++++- rwgame/RWGame.cpp | 1 - rwgame/states/IngameState.cpp | 2 +- 5 files changed, 9 insertions(+), 35 deletions(-) diff --git a/rwengine/src/objects/GameObject.cpp b/rwengine/src/objects/GameObject.cpp index 25579af9..b6647202 100644 --- a/rwengine/src/objects/GameObject.cpp +++ b/rwengine/src/objects/GameObject.cpp @@ -18,7 +18,7 @@ GameObject::~GameObject() { } void GameObject::setPosition(const glm::vec3& pos) { - _lastPosition = position = pos; + position = pos; } void GameObject::setRotation(const glm::quat& orientation) { @@ -36,16 +36,7 @@ void GameObject::setHeading(float heading) { setRotation(quat); } -glm::mat4 GameObject::getTimeAdjustedTransform(float alpha) const { - glm::mat4 t{1.0f}; - t = glm::translate(t, glm::mix(_lastPosition, getPosition(), alpha)); - t = t * glm::mat4_cast(glm::slerp(_lastRotation, getRotation(), alpha)); - return t; -} - void GameObject::updateTransform(const glm::vec3& pos, const glm::quat& rot) { - _lastPosition = position; - _lastRotation = rotation; position = pos; rotation = rot; diff --git a/rwengine/src/objects/GameObject.hpp b/rwengine/src/objects/GameObject.hpp index aae6862f..802d76e5 100644 --- a/rwengine/src/objects/GameObject.hpp +++ b/rwengine/src/objects/GameObject.hpp @@ -23,8 +23,6 @@ class GameWorld; * tracking used to make tunnels work. */ class GameObject { - glm::vec3 _lastPosition; - glm::quat _lastRotation; GameObjectID objectID = 0; BaseModelInfo* modelinfo_; @@ -62,12 +60,7 @@ public: GameObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, BaseModelInfo* modelinfo) - : _lastPosition(pos) - , _lastRotation(rot) - , modelinfo_(modelinfo) - , position(pos) - , rotation(rot) - , engine(engine) { + : modelinfo_(modelinfo), position(pos), rotation(rot), engine(engine) { if (modelinfo_) { modelinfo_->addReference(); } @@ -148,9 +141,6 @@ public: const glm::vec3& getPosition() const { return position; } - const glm::vec3& getLastPosition() const { - return _lastPosition; - } const glm::quat& getRotation() const { return rotation; @@ -229,17 +219,6 @@ public: virtual void tick(float dt) = 0; - /** - * @brief Function used to modify the last transform - * @param newPos - */ - void _updateLastTransform() { - _lastPosition = getPosition(); - _lastRotation = getRotation(); - } - - glm::mat4 getTimeAdjustedTransform(float alpha) const; - enum ObjectLifetime { /// lifetime has not been set UnknownLifetime, diff --git a/rwengine/src/render/GameRenderer.cpp b/rwengine/src/render/GameRenderer.cpp index d9712f0b..df976bf3 100644 --- a/rwengine/src/render/GameRenderer.cpp +++ b/rwengine/src/render/GameRenderer.cpp @@ -349,7 +349,12 @@ RenderList GameRenderer::createObjectRenderList(const GameWorld *world) { if (blip.second.target > 0) { auto object = world->getBlipTarget(blip.second); if (object) { - model = object->getTimeAdjustedTransform(_renderAlpha); + auto& clump = object->getClump(); + auto& atomic = object->getAtomic(); + if (clump) + model = clump->getFrame()->getWorldTransform(); + else if (atomic) + model = atomic->getFrame()->getWorldTransform(); } } else { model = translate(model, blip.second.coord); diff --git a/rwgame/RWGame.cpp b/rwgame/RWGame.cpp index 50e81b3f..bbfed79f 100644 --- a/rwgame/RWGame.cpp +++ b/rwgame/RWGame.cpp @@ -605,7 +605,6 @@ void RWGame::tickObjects(float dt) const { RW_PROFILE_SCOPEC("allObjects", MP_HOTPINK1); RW_PROFILE_COUNTER_SET("tickObjects/allObjects", world->allObjects.size()); for (auto &object : world->allObjects) { - object->_updateLastTransform(); object->tick(dt); } } diff --git a/rwgame/states/IngameState.cpp b/rwgame/states/IngameState.cpp index 9d08ccac..ed2b9284 100644 --- a/rwgame/states/IngameState.cpp +++ b/rwgame/states/IngameState.cpp @@ -439,7 +439,7 @@ const ViewCamera& IngameState::getCamera(float alpha) { bool lookright = held(GameInputState::LookRight); btCollisionObject* physTarget = player->getCharacter()->physObject.get(); - auto targetTransform = target->getTimeAdjustedTransform(alpha); + auto targetTransform = target->getClump()->getFrame()->getWorldTransform(); glm::vec3 targetPosition(targetTransform[3]); glm::vec3 lookTargetPosition(targetPosition); From 86bf69b0a0e59397997d0aac4374307a77aae701 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Wed, 15 May 2019 23:28:09 +0100 Subject: [PATCH 8/8] Helper argument to clone Atomics with a new frame --- rwcore/data/Clump.cpp | 4 ++-- rwcore/data/Clump.hpp | 2 +- rwengine/src/objects/InstanceObject.cpp | 9 ++------- rwengine/src/objects/PickupObject.cpp | 4 +--- rwengine/src/objects/ProjectileObject.cpp | 4 +--- 5 files changed, 7 insertions(+), 16 deletions(-) diff --git a/rwcore/data/Clump.cpp b/rwcore/data/Clump.cpp index 6f2d2945..a7a325fe 100644 --- a/rwcore/data/Clump.cpp +++ b/rwcore/data/Clump.cpp @@ -82,10 +82,10 @@ ModelFramePtr ModelFrame::cloneHierarchy() const { return self; } -AtomicPtr Atomic::clone() const { +AtomicPtr Atomic::clone(const ModelFramePtr& newFrame) const { auto newatomic = std::make_shared(); newatomic->setGeometry(getGeometry()); - newatomic->setFrame(getFrame()); + newatomic->setFrame(newFrame ? newFrame : getFrame()); newatomic->setFlags(getFlags()); return newatomic; } diff --git a/rwcore/data/Clump.hpp b/rwcore/data/Clump.hpp index af430940..d6312527 100644 --- a/rwcore/data/Clump.hpp +++ b/rwcore/data/Clump.hpp @@ -234,7 +234,7 @@ public: } } - AtomicPtr clone() const; + AtomicPtr clone(const ModelFramePtr& newFrame = {}) const; }; /** diff --git a/rwengine/src/objects/InstanceObject.cpp b/rwengine/src/objects/InstanceObject.cpp index 80191ab8..b85df8fc 100644 --- a/rwengine/src/objects/InstanceObject.cpp +++ b/rwengine/src/objects/InstanceObject.cpp @@ -165,13 +165,8 @@ void InstanceObject::changeModel(BaseModelInfo* incoming, int atomicNumber) { atomicNumber); auto atomic = getModelInfo()->getAtomic(atomicNumber); if (atomic) { - auto previous = atomic_; - atomic_ = atomic->clone(); - if (previous) { - atomic_->setFrame(previous->getFrame()); - } else { - atomic_->setFrame(std::make_shared()); - } + const auto frame = atomic_ ? atomic_->getFrame() : std::make_shared(); + atomic_ = atomic->clone(frame); } if (collision) { diff --git a/rwengine/src/objects/PickupObject.cpp b/rwengine/src/objects/PickupObject.cpp index 25c5bf6f..2ba252de 100644 --- a/rwengine/src/objects/PickupObject.cpp +++ b/rwengine/src/objects/PickupObject.cpp @@ -273,9 +273,7 @@ PickupObject::PickupObject(GameWorld* world, const glm::vec3& position, setCollected(false); auto modelData = getModelInfo(); - auto atomic = modelData->getAtomic(0)->clone(); - atomic->setFrame(std::make_shared()); - setModel(std::move(atomic)); + setModel(modelData->getAtomic(0)->clone(std::make_shared())); updateTransform(getPosition(), getRotation()); } diff --git a/rwengine/src/objects/ProjectileObject.cpp b/rwengine/src/objects/ProjectileObject.cpp index 58144f26..27f439bc 100644 --- a/rwengine/src/objects/ProjectileObject.cpp +++ b/rwengine/src/objects/ProjectileObject.cpp @@ -163,9 +163,7 @@ ProjectileObject::ProjectileObject(GameWorld* world, const glm::vec3& position, const auto& modelData = world->data->findModelInfo( getProjectileInfo().weapon->modelID); - auto atomic = modelData->getAtomic(0)->clone(); - atomic->setFrame(std::make_shared()); - setModel(std::move(atomic)); + setModel(modelData->getAtomic(0)->clone(std::make_shared())); } ProjectileObject::~ProjectileObject() {