1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-25 20:02:40 +01:00

Refactor objects into a single set to DRY

This commit is contained in:
Daniel Evans 2014-07-01 23:04:23 +01:00
parent 3c57d9278c
commit aa7f77009c
8 changed files with 76 additions and 120 deletions

View File

@ -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__

View File

@ -23,6 +23,7 @@ class WeaponScan;
#include <btBulletCollisionCommon.h>
#include <vector>
#include <set>
#include <queue>
#include <random>
@ -165,24 +166,16 @@ public:
std::map<uint16_t, std::shared_ptr<CharacterData>> 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<std::shared_ptr<InstanceObject>> objectInstances;
std::set<GameObject*> objects;
/**
* Map of Model Names to Instances
*/
std::map<std::string, std::shared_ptr<InstanceObject>> modelInstances;
/**
* Game Vehicles!
*/
std::vector<VehicleObject*> vehicleInstances;
/**
* Pedestrians and PCs.
*/
std::vector<CharacterObject*> pedestrians;
std::map<std::string, InstanceObject*> modelInstances;
/**
* AI Graph

View File

@ -13,19 +13,18 @@ struct InstanceObject : public GameObject
glm::vec3 scale;
btRigidBody* body = nullptr;
std::shared_ptr<ObjectData> object;
std::shared_ptr<InstanceObject> LODinstance;
InstanceObject* LODinstance;
std::shared_ptr<DynamicObjectData> 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<ObjectData> obj,
std::shared_ptr<InstanceObject> lod,
InstanceObject *lod,
std::shared_ptr<DynamicObjectData> dyn
);

View File

@ -38,11 +38,14 @@ 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());
for( GameObject* object : world->objects ) {
if( object->type() == GameObject::Vehicle ) {
float vd = glm::length( character->getPosition() - object->getPosition());
if( vd < d ) {
d = vd;
nearest = *it;
nearest = static_cast<VehicleObject*>(object);
}
}
}

View File

@ -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));
for(GameObject* object : objects) {
if( object->type() == GameObject::Instance ) {
InstanceObject* instance = static_cast<InstanceObject*>(object);
if( !instance->object->LOD ) {
auto lodInstit = modelInstances.find("LOD" + instance->object->modelName.substr(3));
if( lodInstit != modelInstances.end() ) {
objectInstances[i]->LODinstance = lodInstit->second;
instance->LODinstance = lodInstit->second;
}
}
}
}
@ -251,25 +254,27 @@ InstanceObject *GameWorld::createInstance(const uint16_t id, const glm::vec3& po
dydata = dyit->second;
}
auto instance = std::shared_ptr<InstanceObject>(new InstanceObject(
if( oi->second->modelName.empty() ) {
logWarning("Instance with missing model: " + std::to_string(id));
}
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);
objects.insert(instance);
if( !oi->second->modelName.empty() ) {
modelInstances.insert({
oi->second->modelName,
objectInstances.back()
instance
});
}
return instance.get();
return instance;
}
return nullptr;
@ -330,8 +335,11 @@ 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;
}
}
}
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;
}
}
}
/// @TODO deletion queue
auto iterator = objects.find(object);
if( iterator != objects.end() ) {
delete object;
objects.erase(iterator);
}
}
void GameWorld::doWeaponScan(const WeaponScan &scan)
@ -537,8 +517,10 @@ void GameWorld::PhysicsTickCallback(btDynamicsWorld *physWorld, btScalar timeSte
{
GameWorld* world = static_cast<GameWorld*>(physWorld->getWorldUserInfo());
for(VehicleObject* v : world->vehicleInstances) {
v->tickPhysics(timeStep);
for( GameObject* object : world->objects ) {
if( object->type() == GameObject::Vehicle ) {
static_cast<VehicleObject*>(object)->tickPhysics(timeStep);
}
}
}

View File

@ -8,7 +8,7 @@ InstanceObject::InstanceObject(GameWorld* engine,
ModelHandle *model,
const glm::vec3& scale,
std::shared_ptr<ObjectData> obj,
std::shared_ptr<InstanceObject> lod,
InstanceObject* lod,
std::shared_ptr<DynamicObjectData> dyn)
: GameObject(engine, pos, rot, model), scale(scale), object(obj),
LODinstance(lod), dynamics(dyn), _collisionHeight(0.f), _enablePhysics(false)

View File

@ -250,16 +250,19 @@ void GameRenderer::renderWorld(float alpha)
glActiveTexture(GL_TEXTURE0);
glUniform1i(uniTexture, 0);
for(GameObject* object : engine->pedestrians) {
for( GameObject* object : engine->objects ) {
switch(object->type()) {
case GameObject::Character:
renderPedestrian(static_cast<CharacterObject*>(object));
}
for(auto object : engine->objectInstances) {
renderInstance(static_cast<InstanceObject*>(object.get()));
}
for(GameObject* object : engine->vehicleInstances) {
break;
case GameObject::Vehicle:
renderVehicle(static_cast<VehicleObject*>(object));
break;
case GameObject::Instance:
renderInstance(static_cast<InstanceObject*>(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);

View File

@ -330,24 +330,8 @@ 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);