1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-21 18:02:43 +01:00

Unify Object Atomic/Clump handling

This commit is contained in:
Daniel Evans 2019-05-11 20:33:23 +01:00
parent 714e4b2041
commit ff10f3769e
19 changed files with 53 additions and 50 deletions

View File

@ -118,6 +118,7 @@ ClumpPtr Clump::clone() const {
auto newroot = rootframe_->cloneHierarchy(); auto newroot = rootframe_->cloneHierarchy();
auto clump = std::make_shared<Clump>(); auto clump = std::make_shared<Clump>();
clump->setFrame(newroot); clump->setFrame(newroot);
clump->boundingRadius = boundingRadius;
// This isn't the most optimal implementation, but this code is likely // This isn't the most optimal implementation, but this code is likely
// to be replaced soon. // to be replaced soon.

View File

@ -227,7 +227,7 @@ CutsceneObject* GameWorld::createCutsceneObject(const uint16_t id,
if (id == 0) { if (id == 0) {
auto playerobj = pedestrianPool.find(state->playerObject); auto playerobj = pedestrianPool.find(state->playerObject);
if (playerobj) { if (playerobj) {
model = playerobj->getModel(); model = playerobj->getClump();
} }
} }
@ -1050,7 +1050,7 @@ GameWorld::findOverlappingObjects(const glm::vec3 &center,
auto checkObjects = [&](const auto& objects) { auto checkObjects = [&](const auto& objects) {
for (auto& p : objects) { for (auto& p : objects) {
const auto& object = p.second.get(); const auto& object = p.second.get();
auto objectBounds = object->getModel()->getBoundingRadius(); auto objectBounds = object->getClump()->getBoundingRadius();
if (glm::distance(center, object->getPosition()) < if (glm::distance(center, object->getPosition()) <
radius + objectBounds) { radius + objectBounds) {
overlapping.push_back(object); overlapping.push_back(object);

View File

@ -38,7 +38,7 @@ Garage::Garage(GameWorld* engine_, size_t id_, const glm::vec3& coord0,
for (const auto& p : engine->instancePool.objects) { for (const auto& p : engine->instancePool.objects) {
const auto inst = static_cast<InstanceObject*>(p.second.get()); const auto inst = static_cast<InstanceObject*>(p.second.get());
if (!inst->getModel()) { if (!inst->getClump()) {
continue; continue;
} }

View File

@ -16,7 +16,7 @@ Payphone::Payphone(GameWorld* engine_, size_t id_, const glm::vec2& coord)
// Find payphone object, original game does this differently // Find payphone object, original game does this differently
for (const auto& p : engine->instancePool.objects) { for (const auto& p : engine->instancePool.objects) {
auto o = p.second.get(); auto o = p.second.get();
if (!o->getModel()) { if (!o->getClump()) {
continue; continue;
} }
if (o->getModelInfo<BaseModelInfo>()->name != "phonebooth1") { if (o->getModelInfo<BaseModelInfo>()->name != "phonebooth1") {

View File

@ -43,9 +43,8 @@ CharacterObject::CharacterObject(GameWorld* engine, const glm::vec3& pos,
ai::CharacterController* controller) ai::CharacterController* controller)
: GameObject(engine, pos, rot, modelinfo), controller(controller) { : GameObject(engine, pos, rot, modelinfo), controller(controller) {
auto info = getModelInfo<PedModelInfo>(); auto info = getModelInfo<PedModelInfo>();
setClump(info->getModel()->clone());
if (info->getModel()) { if (info->getModel()) {
setModel(info->getModel()); setModel(info->getModel()->clone());
animator = std::make_unique<Animator>(getClump()); animator = std::make_unique<Animator>(getClump());
createActor(); createActor();
@ -70,7 +69,7 @@ void CharacterObject::createActor(const glm::vec2& size) {
} }
// Don't create anything without a valid model. // Don't create anything without a valid model.
if (getModel()) { if (getClump()) {
btTransform tf; btTransform tf;
tf.setIdentity(); tf.setIdentity();
tf.setOrigin(btVector3(position.x, position.y, position.z)); tf.setOrigin(btVector3(position.x, position.y, position.z));

View File

@ -53,7 +53,7 @@ class GameWorld;
* @brief The CharacterObject struct * @brief The CharacterObject struct
* Implements Character object behaviours. * Implements Character object behaviours.
*/ */
class CharacterObject final : public GameObject, public ClumpObject { class CharacterObject final : public GameObject {
private: private:
CharacterState currentState{}; CharacterState currentState{};

View File

@ -10,12 +10,11 @@ CutsceneObject::CutsceneObject(GameWorld *engine, const glm::vec3 &pos,
BaseModelInfo *modelinfo) BaseModelInfo *modelinfo)
: GameObject(engine, pos, rot, modelinfo) { : GameObject(engine, pos, rot, modelinfo) {
if (model) { if (model) {
setModel(model); setModel(model->clone());
} }
else { else {
setModel(getModelInfo<ClumpModelInfo>()->getModel()); setModel(getModelInfo<ClumpModelInfo>()->getModel()->clone());
} }
setClump(getModel()->clone());
animator = std::make_unique<Animator>(getClump()); animator = std::make_unique<Animator>(getClump());
} }

View File

@ -12,7 +12,7 @@ class ModelFrame;
/** /**
* @brief Object type used for cutscene animations. * @brief Object type used for cutscene animations.
*/ */
class CutsceneObject final : public GameObject, public ClumpObject { class CutsceneObject final : public GameObject {
GameObject* _parent = nullptr; GameObject* _parent = nullptr;
ModelFrame* _bone = nullptr; ModelFrame* _bone = nullptr;

View File

@ -6,6 +6,9 @@
#include "engine/Animator.hpp" #include "engine/Animator.hpp"
const AtomicPtr GameObject::NullAtomic;
const ClumpPtr GameObject::NullClump;
GameObject::~GameObject() { GameObject::~GameObject() {
if (modelinfo_) { if (modelinfo_) {
modelinfo_->removeReference(); modelinfo_->removeReference();

View File

@ -2,6 +2,7 @@
#define _RWENGINE_GAMEOBJECT_HPP_ #define _RWENGINE_GAMEOBJECT_HPP_
#include <limits> #include <limits>
#include <variant>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
@ -28,10 +29,11 @@ class GameObject {
BaseModelInfo* modelinfo_; BaseModelInfo* modelinfo_;
/** using Model = std::variant<AtomicPtr, ClumpPtr>;
* Model used for rendering Model model_;
*/
ClumpPtr model_ = nullptr; static const AtomicPtr NullAtomic;
static const ClumpPtr NullClump;
protected: protected:
void changeModelInfo(BaseModelInfo* next) { void changeModelInfo(BaseModelInfo* next) {
@ -92,16 +94,30 @@ public:
return static_cast<T*>(modelinfo_); return static_cast<T*>(modelinfo_);
} }
/** const Model& getModel() const {
* @return The model used in rendering
*/
ClumpPtr getModel() const {
return model_; return model_;
} }
/** const AtomicPtr& getAtomic() const {
* Changes the current model, used for re-dressing chars if (auto atomic = std::get_if<AtomicPtr>(&model_))
*/ {
return *atomic;
}
return NullAtomic;
}
const ClumpPtr& getClump() const {
if (auto clump = std::get_if<ClumpPtr>(&model_))
{
return *clump;
}
return NullClump;
}
void setModel(const AtomicPtr& model) {
model_ = model;
}
void setModel(const ClumpPtr& model) { void setModel(const ClumpPtr& model) {
model_ = model; model_ = model;
} }
@ -265,18 +281,4 @@ private:
ObjectLifetime lifetime = GameObject::UnknownLifetime; 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__ #endif // __GAMEOBJECTS_HPP__

View File

@ -173,8 +173,7 @@ VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos,
wheelsRotation.push_back(0.f); wheelsRotation.push_back(0.f);
} }
setModel(getVehicle()->getModel()); setModel(getVehicle()->getModel()->clone());
setClump(getModelInfo<VehicleModelInfo>()->getModel()->clone());
setupModel(); setupModel();
} }

View File

@ -39,7 +39,7 @@ struct btVehicleRaycaster;
* @class VehicleObject * @class VehicleObject
* Implements Vehicle behaviours. * Implements Vehicle behaviours.
*/ */
class VehicleObject final : public GameObject, public ClumpObject { class VehicleObject final : public GameObject {
private: private:
float steerAngle{0.f}; float steerAngle{0.f};
float throttle{0.f}; float throttle{0.f};

View File

@ -219,9 +219,9 @@ ScriptModel getModel(const ScriptArguments& args, ScriptModel model);
inline void clearSpaceForObject(const ScriptArguments& args, inline void clearSpaceForObject(const ScriptArguments& args,
GameObject* object) { 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( const auto& overlapping = args.getWorld()->findOverlappingObjects(
object->getPosition(), radius); object->getPosition(), radius);

View File

@ -10900,7 +10900,7 @@ void opcode_03b6(const ScriptArguments& args, ScriptVec3 coord, const ScriptFloa
for(auto& p : args.getWorld()->instancePool.objects) { for(auto& p : args.getWorld()->instancePool.objects) {
auto o = p.second.get(); auto o = p.second.get();
if( !o->getModel() ) continue; if( !o->getClump() ) continue;
if( o->getModelInfo<BaseModelInfo>()->name != oldmodel ) continue; if( o->getModelInfo<BaseModelInfo>()->name != oldmodel ) continue;
float d = glm::distance(coord, o->getPosition()); float d = glm::distance(coord, o->getPosition());
if( d < radius ) { if( d < radius ) {

View File

@ -448,7 +448,7 @@ const ViewCamera& IngameState::getCamera(float alpha) {
if (target->type() == GameObject::Vehicle) { if (target->type() == GameObject::Vehicle) {
auto vehicle = static_cast<VehicleObject*>(target); auto vehicle = static_cast<VehicleObject*>(target);
auto model = vehicle->getModel(); auto model = vehicle->getClump();
auto maxDist = model->getBoundingRadius() * 2.f; auto maxDist = model->getBoundingRadius() * 2.f;
viewDistance = viewDistance + maxDist; viewDistance = viewDistance + maxDist;
lookTargetPosition.z += (vehicle->info->handling.dimensions.z * 0.5f); lookTargetPosition.z += (vehicle->info->handling.dimensions.z * 0.5f);

View File

@ -230,8 +230,8 @@ void ViewerWidget::showObject(quint16 item) {
RW_CHECK(_object != nullptr, "Dummy Object is null"); RW_CHECK(_object != nullptr, "Dummy Object is null");
if (_object->getModel()) { if (_object->getClump()) {
auto objectRadius = _object->getModel()->getBoundingRadius(); auto objectRadius = _object->getClump()->getBoundingRadius();
viewDistance = objectRadius * 2; viewDistance = objectRadius * 2;
viewAngles.x = glm::radians(-45.f); viewAngles.x = glm::radians(-45.f);
viewAngles.y = glm::radians(22.5f); viewAngles.y = glm::radians(22.5f);

View File

@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(test_activities) {
VehicleObject* vehicle = Global::get().e->createVehicle( 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}); 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 != nullptr);
BOOST_REQUIRE(vehicle->getModel() != nullptr); BOOST_REQUIRE(vehicle->getClump() != nullptr);
auto character = Global::get().e->createPedestrian(1, {0.f, 0.f, 0.f}); auto character = Global::get().e->createPedestrian(1, {0.f, 0.f, 0.f});
BOOST_REQUIRE(character != nullptr); BOOST_REQUIRE(character != nullptr);

View File

@ -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}); Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f});
BOOST_REQUIRE(vehicle); BOOST_REQUIRE(vehicle);
BOOST_REQUIRE(vehicle->getModel()); BOOST_REQUIRE(vehicle->getClump());
VehicleObject::Part* part = vehicle->getPart("bonnet_dummy"); 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}); Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f});
BOOST_REQUIRE(vehicle); BOOST_REQUIRE(vehicle);
BOOST_REQUIRE(vehicle->getModel()); BOOST_REQUIRE(vehicle->getClump());
VehicleObject::Part* bonnetpart = vehicle->getPart("bonnet_dummy"); VehicleObject::Part* bonnetpart = vehicle->getPart("bonnet_dummy");

View File

@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(TestDoWeaponScan, DATA_TEST_PREDICATE) {
// Test RADIUS scan // Test RADIUS scan
auto character = Global::get().e->createPedestrian(1, {0.f, 0.f, 0.f}); auto character = Global::get().e->createPedestrian(1, {0.f, 0.f, 0.f});
BOOST_REQUIRE(character != nullptr); BOOST_REQUIRE(character != nullptr);
BOOST_REQUIRE(character->getModel() != nullptr); BOOST_REQUIRE(character->getClump() != nullptr);
BOOST_REQUIRE(character->physObject != nullptr); BOOST_REQUIRE(character->physObject != nullptr);
WeaponScan scan(10.f, {0.f, 0.f, 10.f}, {0.f, 0.f, -10.f}); WeaponScan scan(10.f, {0.f, 0.f, 10.f}, {0.f, 0.f, -10.f});