diff --git a/rwengine/include/engine/GameObject.hpp b/rwengine/include/engine/GameObject.hpp index 0e97f66b..0277db22 100644 --- a/rwengine/include/engine/GameObject.hpp +++ b/rwengine/include/engine/GameObject.hpp @@ -102,6 +102,8 @@ struct GameObject virtual bool isAnimationFixed() const { return true; } virtual bool isInWater() const { return _inWater; } + + virtual void tick(float dt) = 0; }; #endif // __GAMEOBJECTS_HPP__ diff --git a/rwengine/include/engine/GameWorld.hpp b/rwengine/include/engine/GameWorld.hpp index c7b92e70..25fbef3a 100644 --- a/rwengine/include/engine/GameWorld.hpp +++ b/rwengine/include/engine/GameWorld.hpp @@ -23,6 +23,7 @@ class WeaponScan; #include #include +#include #include #include @@ -163,27 +164,19 @@ public: * Ped definitions */ std::map> pedestrianTypes; - + /** - * Game Objects! + * @brief objects All active GameObjects in the world. + * @TODO add some mechanism to allow objects to be "locked" preventing deletion. + * @TODO add deletion queue to allow objects to self delete. */ - std::vector> objectInstances; - + std::set objects; + /** * Map of Model Names to Instances */ - std::map> modelInstances; - - /** - * Game Vehicles! - */ - std::vector vehicleInstances; + std::map modelInstances; - /** - * Pedestrians and PCs. - */ - std::vector pedestrians; - /** * AI Graph */ diff --git a/rwengine/include/objects/InstanceObject.hpp b/rwengine/include/objects/InstanceObject.hpp index 1573760d..f143414b 100644 --- a/rwengine/include/objects/InstanceObject.hpp +++ b/rwengine/include/objects/InstanceObject.hpp @@ -13,19 +13,18 @@ struct InstanceObject : public GameObject glm::vec3 scale; btRigidBody* body = nullptr; std::shared_ptr object; - std::shared_ptr LODinstance; + InstanceObject* LODinstance; std::shared_ptr dynamics; float _collisionHeight; bool _enablePhysics; - InstanceObject( - GameWorld* engine, + InstanceObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, ModelHandle* model, const glm::vec3& scale, std::shared_ptr obj, - std::shared_ptr lod, + InstanceObject *lod, std::shared_ptr dyn ); diff --git a/rwengine/src/ai/PlayerController.cpp b/rwengine/src/ai/PlayerController.cpp index 5ef85e0b..c097abf9 100644 --- a/rwengine/src/ai/PlayerController.cpp +++ b/rwengine/src/ai/PlayerController.cpp @@ -38,14 +38,17 @@ void PlayerController::enterNearestVehicle() if(! character->getCurrentVehicle()) { auto world = character->engine; VehicleObject* nearest = nullptr; float d = 10.f; - for(auto it = world->vehicleInstances.begin(); it != world->vehicleInstances.end(); ++it) { - float vd = glm::length( character->getPosition() - (*it)->getPosition()); - if( vd < d ) { - d = vd; - nearest = *it; + + for( GameObject* object : world->objects ) { + if( object->type() == GameObject::Vehicle ) { + float vd = glm::length( character->getPosition() - object->getPosition()); + if( vd < d ) { + d = vd; + nearest = static_cast(object); + } } } - + if( nearest ) { setNextActivity(new Activities::EnterVehicle(nearest, 0)); } diff --git a/rwengine/src/engine/GameWorld.cpp b/rwengine/src/engine/GameWorld.cpp index 1160bfde..bfe5fb44 100644 --- a/rwengine/src/engine/GameWorld.cpp +++ b/rwengine/src/engine/GameWorld.cpp @@ -194,11 +194,14 @@ bool GameWorld::placeItems(const std::string& name) } // Attempt to Associate LODs. - for( size_t i = 0; i < objectInstances.size(); ++i ) { - if( !objectInstances[i]->object->LOD ) { - auto lodInstit = modelInstances.find("LOD" + objectInstances[i]->object->modelName.substr(3)); - if( lodInstit != modelInstances.end() ) { - objectInstances[i]->LODinstance = lodInstit->second; + for(GameObject* object : objects) { + if( object->type() == GameObject::Instance ) { + InstanceObject* instance = static_cast(object); + if( !instance->object->LOD ) { + auto lodInstit = modelInstances.find("LOD" + instance->object->modelName.substr(3)); + if( lodInstit != modelInstances.end() ) { + instance->LODinstance = lodInstit->second; + } } } } @@ -250,26 +253,28 @@ InstanceObject *GameWorld::createInstance(const uint16_t id, const glm::vec3& po if( dyit != gameData.dynamicObjectData.end() ) { dydata = dyit->second; } + + if( oi->second->modelName.empty() ) { + logWarning("Instance with missing model: " + std::to_string(id)); + } - auto instance = std::shared_ptr(new InstanceObject( + auto instance = new InstanceObject( this, pos, rot, gameData.models[oi->second->modelName], glm::vec3(1.f, 1.f, 1.f), oi->second, nullptr, dydata - )); - - objectInstances.push_back(instance); - - if( !oi->second->modelName.empty() ) { - modelInstances.insert({ - oi->second->modelName, - objectInstances.back() - }); - } + ); - return instance.get(); + objects.insert(instance); + + modelInstances.insert({ + oi->second->modelName, + instance + }); + + return instance; } return nullptr; @@ -329,9 +334,12 @@ VehicleObject *GameWorld::createVehicle(const uint16_t id, const glm::vec3& pos, } } } - - vehicleInstances.push_back(new VehicleObject{ this, pos, rot, m, vti->second, info->second, prim, sec }); - return vehicleInstances.back(); + + auto vehicle = new VehicleObject{ this, pos, rot, m, vti->second, info->second, prim, sec }; + + objects.insert(vehicle); + + return vehicle; } return nullptr; } @@ -356,7 +364,7 @@ CharacterObject* GameWorld::createPedestrian(const uint16_t id, const glm::vec3 if(m != nullptr) { auto ped = new CharacterObject( this, pos, rot, m, pt ); - pedestrians.push_back(ped); + objects.insert(ped); new DefaultAIController(ped); return ped; } @@ -366,40 +374,12 @@ CharacterObject* GameWorld::createPedestrian(const uint16_t id, const glm::vec3 void GameWorld::destroyObject(GameObject* object) { - if(object->type() == GameObject::Character) - { - for(auto it = pedestrians.begin(); it != pedestrians.end(); ) { - if( *it == object ) { - it = pedestrians.erase(it); - } - else { - ++it; - } - } + /// @TODO deletion queue + auto iterator = objects.find(object); + if( iterator != objects.end() ) { + delete object; + objects.erase(iterator); } - else if(object->type() == GameObject::Vehicle) - { - for(auto it = vehicleInstances.begin(); it != vehicleInstances.end(); ) { - if( *it == object ) { - it = vehicleInstances.erase(it); - } - else { - ++it; - } - } - } - else if(object->type() == GameObject::Instance) - { - for(auto it = modelInstances.begin(); it != modelInstances.end(); ) { - if( it->second.get() == object ) { - it = modelInstances.erase(it); - } - else { - ++it; - } - } - } - delete object; } void GameWorld::doWeaponScan(const WeaponScan &scan) @@ -537,8 +517,10 @@ void GameWorld::PhysicsTickCallback(btDynamicsWorld *physWorld, btScalar timeSte { GameWorld* world = static_cast(physWorld->getWorldUserInfo()); - for(VehicleObject* v : world->vehicleInstances) { - v->tickPhysics(timeStep); + for( GameObject* object : world->objects ) { + if( object->type() == GameObject::Vehicle ) { + static_cast(object)->tickPhysics(timeStep); + } } } diff --git a/rwengine/src/objects/InstanceObject.cpp b/rwengine/src/objects/InstanceObject.cpp index 790f82c2..4a1775ac 100644 --- a/rwengine/src/objects/InstanceObject.cpp +++ b/rwengine/src/objects/InstanceObject.cpp @@ -8,7 +8,7 @@ InstanceObject::InstanceObject(GameWorld* engine, ModelHandle *model, const glm::vec3& scale, std::shared_ptr obj, - std::shared_ptr lod, + InstanceObject* lod, std::shared_ptr dyn) : GameObject(engine, pos, rot, model), scale(scale), object(obj), LODinstance(lod), dynamics(dyn), _collisionHeight(0.f), _enablePhysics(false) diff --git a/rwengine/src/render/GameRenderer.cpp b/rwengine/src/render/GameRenderer.cpp index b738a5de..35438d85 100644 --- a/rwengine/src/render/GameRenderer.cpp +++ b/rwengine/src/render/GameRenderer.cpp @@ -250,16 +250,19 @@ void GameRenderer::renderWorld(float alpha) glActiveTexture(GL_TEXTURE0); glUniform1i(uniTexture, 0); - for(GameObject* object : engine->pedestrians) { - renderPedestrian(static_cast(object)); - } - - for(auto object : engine->objectInstances) { - renderInstance(static_cast(object.get())); - } - - for(GameObject* object : engine->vehicleInstances) { - renderVehicle(static_cast(object)); + for( GameObject* object : engine->objects ) { + switch(object->type()) { + case GameObject::Character: + renderPedestrian(static_cast(object)); + break; + case GameObject::Vehicle: + renderVehicle(static_cast(object)); + break; + case GameObject::Instance: + renderInstance(static_cast(object)); + break; + default: break; + } } // Draw anything that got queued. @@ -742,16 +745,6 @@ void GameRenderer::renderPaths() } } - - for(size_t i = 0; i < engine->pedestrians.size(); ++i) { - CharacterObject* charac = engine->pedestrians[i]; - - if(charac->controller) { - carlines.push_back(charac->getPosition()); - carlines.push_back(charac->controller->getTargetPosition()); - } - } - glm::mat4 model; glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model)); glEnableVertexAttribArray(posAttrib); diff --git a/rwgame/main.cpp b/rwgame/main.cpp index 3bfe3b08..f4f11377 100644 --- a/rwgame/main.cpp +++ b/rwgame/main.cpp @@ -329,25 +329,9 @@ void update(float dt) gta->renderer.camera.worldPos = viewPosition; gta->renderer.camera.frustum.view = view; - - // Update all objects. - for( size_t p = 0; p < gta->pedestrians.size(); ++p) { - gta->pedestrians[p]->tick(dt); - if(gta->pedestrians[p]->mHealth <= 0.f) { - gta->destroyObject(gta->pedestrians[p]); - p--; - } - } - for( size_t v = 0; v < gta->vehicleInstances.size(); ++v ) { - gta->vehicleInstances[v]->tick(dt); - if(gta->vehicleInstances[v]->mHealth <= 0.f) { - gta->destroyObject(gta->vehicleInstances[v]); - v--; - } - } - for( size_t p = 0; p < gta->objectInstances.size(); ++p) { - gta->objectInstances[p]->tick(dt); + for( GameObject* object : gta->objects ) { + object->tick(dt); } gta->dynamicsWorld->stepSimulation(dt, 2, dt);