1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-23 02:42:39 +01:00

Refactored GTA objects to make more sense

Objects now inherit from GTAObject.
This commit is contained in:
Daniel Evans 2013-07-24 01:44:08 +01:00
parent 6a1b3df54a
commit 1251c4c2a7
8 changed files with 104 additions and 95 deletions

View File

@ -338,7 +338,7 @@ void GTAData::loadDFF(const std::string& name)
if(file)
{
LoaderDFF dffLoader;
models[name.substr(0, name.size() - 4)] = std::move(dffLoader.loadFromMemory(file));
models[name.substr(0, name.size() - 4)] = dffLoader.loadFromMemory(file);
delete[] file;
}
}

View File

@ -189,7 +189,13 @@ bool GTAEngine::placeItems(const std::string& name)
dynamicsWorld->addRigidBody(body);
}
objectInstances.push_back({ inst, oi->second });
objectInstances.push_back({
glm::vec3(inst.posX, inst.posY, inst.posZ),
glm::quat(-inst.rotW, inst.rotX, inst.rotY, inst.rotZ),
gameData.models[inst.model],
glm::vec3(inst.scaleX, inst.scaleY, inst.scaleZ),
inst, oi->second
});
}
else {
std::cerr << "No object for instance " << inst.id << " (" << path << ")" << std::endl;
@ -258,7 +264,7 @@ void GTAEngine::createVehicle(const uint16_t id, const glm::vec3& pos, const glm
}
}
std::unique_ptr<Model> &model = gameData.models[vti->second->modelName];
Model* model = gameData.models[vti->second->modelName];
if(model) {
if( vti->second->wheelPositions.size() == 0 ) {
for( size_t f = 0; f < model->frames.size(); ++f) {
@ -272,7 +278,7 @@ void GTAEngine::createVehicle(const uint16_t id, const glm::vec3& pos, const glm
}
}
vehicleInstances.push_back({ vti->second, pos, rot, prim, sec });
vehicleInstances.push_back({ pos, rot, model, vti->second, prim, sec });
}
}
@ -290,6 +296,8 @@ void GTAEngine::createPedestrian(const uint16_t id, const glm::vec3 &pos, const
gameData.loadTXD(pt->textureName + ".txd");
}
pedestrians.push_back({ pt, pos, rot });
Model* model = gameData.models[pt->modelName];
pedestrians.push_back({ pos, rot, model, pt });
}
}

View File

@ -303,41 +303,33 @@ void GTARenderer::renderWorld()
matrixModel = glm::translate(matrixModel, charac.position);
matrixModel = matrixModel * glm::mat4_cast(charac.rotation);
Model* model = engine->gameData.models["pimp"].get();
auto mit = engine->gameData.models.find(charac.ped->modelName);
if( mit != engine->gameData.models.end() ) {
model = mit->second.get();
}
if(!model) continue;
if(!charac.model) continue;
renderModel(model, matrixModel);
renderModel(charac.model, matrixModel);
}
for(size_t i = 0; i < engine->objectInstances.size(); ++i) {
GTAInstance& inst = engine->objectInstances[i];
LoaderIPLInstance &obj = inst.instance;
std::string modelname = obj.model;
LoaderIPLInstance &obj = inst.instance;
if(((inst.object->flags & LoaderIDE::OBJS_t::NIGHTONLY) | (inst.object->flags & LoaderIDE::OBJS_t::DAYONLY)) != 0) {
continue;
}
Model* model = engine->gameData.models[modelname].get();
if(!model)
if(!inst.model)
{
std::cout << "model " << modelname << " not there (" << engine->gameData.models.size() << " models loaded)" << std::endl;
std::cout << "model " << obj.model << " not loaded (" << engine->gameData.models.size() << " models loaded)" << std::endl;
}
glm::mat4 matrixModel;
matrixModel = glm::translate(matrixModel, glm::vec3(obj.posX, obj.posY, obj.posZ));
matrixModel = glm::scale(matrixModel, glm::vec3(obj.scaleX, obj.scaleY, obj.scaleZ));
matrixModel = matrixModel * glm::mat4_cast(glm::quat(-obj.rotW, obj.rotX, obj.rotY, obj.rotZ));
matrixModel = glm::translate(matrixModel, inst.position);
matrixModel = glm::scale(matrixModel, inst.scale);
matrixModel = matrixModel * glm::mat4_cast(inst.rotation);
float mindist = 100000.f;
for (size_t g = 0; g < model->geometries.size(); g++)
for (size_t g = 0; g < inst.model->geometries.size(); g++)
{
RW::BSGeometryBounds& bounds = model->geometries[g].geometryBounds;
RW::BSGeometryBounds& bounds = inst.model->geometries[g].geometryBounds;
mindist = std::min(mindist, glm::length((glm::vec3(matrixModel[3])+bounds.center) - camera.worldPos) - bounds.radius);
}
if( mindist > (inst.object->drawDistance[0] * (inst.object->LOD ? 1.f : 2.f))
@ -346,18 +338,15 @@ void GTARenderer::renderWorld()
continue;
}
renderModel(model, matrixModel);
renderModel(inst.model, matrixModel);
}
for(size_t v = 0; v < engine->vehicleInstances.size(); ++v) {
GTAVehicle& inst = engine->vehicleInstances[v];
std::string modelname = inst.vehicle->modelName;
Model* model = engine->gameData.models[modelname].get();
if(!model)
if(!inst.model)
{
std::cout << "model " << modelname << " not there (" << engine->gameData.models.size() << " models loaded)" << std::endl;
std::cout << "model " << inst.vehicle->modelName << " not loaded (" << engine->gameData.models.size() << " models loaded)" << std::endl;
}
glm::mat4 matrixModel;
@ -365,13 +354,13 @@ void GTARenderer::renderWorld()
glm::mat4 matrixVehicle = matrixModel;
renderModel(model, matrixModel, &inst);
renderModel(inst.model, matrixModel, &inst);
// Draw wheels n' stuff
for( size_t w = 0; w < inst.vehicle->wheelPositions.size(); ++w) {
auto woi = engine->objectTypes.find(inst.vehicle->wheelModelID);
if(woi != engine->objectTypes.end()) {
std::unique_ptr<Model> &wheelModel = engine->gameData.models["wheels"];
Model* wheelModel = engine->gameData.models["wheels"];
if( wheelModel) {
auto wwpos = matrixVehicle * glm::vec4(inst.vehicle->wheelPositions[w], 1.f);
renderNamedFrame(wheelModel, glm::vec3(wwpos), glm::quat(), glm::vec3(1.f, inst.vehicle->wheelScale, inst.vehicle->wheelScale), woi->second->modelName);
@ -401,7 +390,7 @@ void GTARenderer::renderWorld()
glBindVertexArray( 0 );
}
void GTARenderer::renderNamedFrame(const std::unique_ptr<Model>& model, const glm::vec3& pos, const glm::quat& rot, const glm::vec3& scale, const std::string& name)
void GTARenderer::renderNamedFrame(Model* model, const glm::vec3& pos, const glm::quat& rot, const glm::vec3& scale, const std::string& name)
{
for (size_t f = 0; f < model->frames.size(); f++)
{
@ -431,47 +420,12 @@ void GTARenderer::renderNamedFrame(const std::unique_ptr<Model>& model, const gl
matrixModel = glm::scale(matrixModel, scale);
matrixModel = matrixModel * glm::mat4_cast(rot);
renderGeometry(model.get(), g, matrixModel);
renderGeometry(model, g, matrixModel);
break;
}
}
void GTARenderer::renderObject(const std::unique_ptr<Model>& model, const glm::vec3& pos, const glm::quat& rot, const glm::vec3& scale)
{
for (size_t a = 0; a < model->atomics.size(); a++)
{
size_t g = model->atomics[a].geometry;
RW::BSGeometryBounds& bounds = model->geometries[g].geometryBounds;
if(! camera.frustum.intersects(bounds.center + pos, bounds.radius)) {
culled++;
continue;
}
else {
rendered++;
}
if( model->geometries[g].clumpNum > 0) {
continue;
}
glm::mat4 matrixModel;
matrixModel = glm::translate(matrixModel, pos);
matrixModel = glm::scale(matrixModel, scale);
matrixModel = matrixModel * glm::mat4_cast(rot);
/*size_t fi = model->atomics[a].frame;
while(true) {
matrixModel = glm::translate(matrixModel, model->frames[fi].position);
matrixModel = matrixModel * glm::mat4(model->frames[fi].rotation);
if(fi == 0) break;
fi = model->frames[fi].index;
}*/
renderGeometry(model.get(), g, matrixModel);
}
}
void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelMatrix, GTAVehicle* vehicle)
void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelMatrix, GTAObject* object)
{
glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(modelMatrix));
glUniform4f(uniCol, 1.f, 1.f, 1.f, 1.f);
@ -506,11 +460,17 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
size_t R = colmasked % 256; colmasked /= 256;
size_t G = colmasked % 256; colmasked /= 256;
size_t B = colmasked % 256; colmasked /= 256;
if( vehicle && R == 60 && G == 255 && B == 0 ) {
glUniform4f(uniCol, vehicle->colourPrimary.r, vehicle->colourPrimary.g, vehicle->colourPrimary.b, 1.f);
}
else if( vehicle && R == 255 && G == 0 && B == 175 ) {
glUniform4f(uniCol, vehicle->colourSecondary.r, vehicle->colourSecondary.g, vehicle->colourSecondary.b, 1.f);
if( object && object->type() == GTAObject::Vehicle ) {
auto vehicle = static_cast<GTAVehicle*>(object);
if( R == 60 && G == 255 && B == 0 ) {
glUniform4f(uniCol, vehicle->colourPrimary.r, vehicle->colourPrimary.g, vehicle->colourPrimary.b, 1.f);
}
else if( R == 255 && G == 0 && B == 175 ) {
glUniform4f(uniCol, vehicle->colourSecondary.r, vehicle->colourSecondary.g, vehicle->colourSecondary.b, 1.f);
}
else {
glUniform4f(uniCol, R/255.f, G/255.f, B/255.f, 1.f);
}
}
else {
glUniform4f(uniCol, R/255.f, G/255.f, B/255.f, 1.f);
@ -527,7 +487,7 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
}
}
void GTARenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GTAVehicle* vehicle)
void GTARenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GTAObject* object)
{
for (size_t a = 0; a < model->atomics.size(); a++)
{
@ -545,7 +505,7 @@ void GTARenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GTAVeh
std::deque<size_t> frames;
int32_t fi = model->atomics[a].frame;
if( vehicle ) {
if( object && object->type() == GTAObject::Vehicle ) {
if(model->frameNames.size() > fi) {
std::string& name = model->frameNames[fi];
if( name.substr(name.size()-3) == "dam" || name.find("lo") != name.npos || name.find("dummy") != name.npos ) {
@ -568,6 +528,6 @@ void GTARenderer::renderModel(Model* model, const glm::mat4& modelMatrix, GTAVeh
glUniform4f(uniCol, 1.f, 1.f, 1.f, 1.f);
}
renderGeometry(model, g, atomicMatrix, vehicle);
renderGeometry(model, g, atomicMatrix, object);
}
}

View File

@ -2,9 +2,9 @@
#include <iostream>
std::unique_ptr<Model> LoaderDFF::loadFromMemory(char *data)
Model* LoaderDFF::loadFromMemory(char *data)
{
auto model = std::unique_ptr<Model>(new Model);
auto model = new Model;
RW::BinaryStreamSection root(data);
model->clump = root.readStructure<RW::BSClump>();

View File

@ -147,7 +147,7 @@ public:
/**
* Loaded models
*/
std::map<std::string, std::unique_ptr<Model>> models;
std::map<std::string, Model*> models;
/**
* Loaded collision proxies
@ -175,4 +175,4 @@ public:
uint8_t realWater[128*128];
};
#endif
#endif

View File

@ -7,35 +7,76 @@
#include <glm/gtc/quaternion.hpp>
#include <memory>
class Model;
/**
* @brief The GTAObject struct
* Stores data that is relevant to all types of objects.
*/
struct GTAObject
{
glm::vec3 position;
glm::quat rotation;
Model* model; /// Cached pointer to Object's Model.
GTAObject(const glm::vec3& pos, const glm::quat& rot, Model* model)
: position(pos), rotation(rot), model(model) {}
enum Type
{
Instance,
Character,
Vehicle
};
virtual Type type() = 0;
};
/**
* @struct GTAObject
* Stores references to the Object data and the instance
*/
struct GTAInstance {
struct GTAInstance : public GTAObject
{
glm::vec3 scale;
LoaderIPLInstance instance;
std::shared_ptr<LoaderIDE::OBJS_t> object;
GTAInstance(const glm::vec3& pos, const glm::quat& rot, Model* model, const glm::vec3& scale, LoaderIPLInstance inst, std::shared_ptr<LoaderIDE::OBJS_t> obj)
: GTAObject(pos, rot, model), scale(scale), instance(inst), object(obj) {}
Type type() { return Instance; }
};
/**
* @brief The GTACharacter struct
* Stores data relating to an instance of a "pedestrian".
*/
struct GTACharacter {
struct GTACharacter : public GTAObject
{
std::shared_ptr<LoaderIDE::PEDS_t> ped;
glm::vec3 position;
glm::quat rotation;
GTACharacter(const glm::vec3& pos, const glm::quat& rot, Model* model, std::shared_ptr<LoaderIDE::PEDS_t> ped)
: GTAObject(pos, rot, model), ped(ped) {}
Type type() { return Character; }
};
/**
* @class GTAVehicle
* Stores references to the vehicle data and the instance
*/
struct GTAVehicle {
struct GTAVehicle : public GTAObject
{
std::shared_ptr<LoaderIDE::CARS_t> vehicle; /// Vehicle type
glm::vec3 position;
glm::quat rotation;
glm::vec3 colourPrimary;
glm::vec3 colourSecondary;
GTAVehicle(const glm::vec3& pos, const glm::quat& rot, Model* model, std::shared_ptr<LoaderIDE::CARS_t> veh, const glm::vec3& prim, const glm::vec3& sec)
: GTAObject(pos, rot, model), vehicle(veh), colourPrimary(prim), colourSecondary(sec) {}
Type type() { return Vehicle; }
};

View File

@ -73,7 +73,7 @@ private:
RW::BSSectionHeader readHeader(char *data, size_t &dataI);
public:
std::unique_ptr<Model> loadFromMemory(char *data);
Model* loadFromMemory(char *data);
};
#endif
#endif

View File

@ -9,7 +9,7 @@
class Model;
class GTAEngine;
class GTAVehicle;
class GTAObject;
class GTARenderer
{
@ -39,11 +39,11 @@ public:
void renderWorld();
void renderNamedFrame(const std::unique_ptr<Model>&, const glm::vec3& pos, const glm::quat& rot, const glm::vec3& scale, const std::string& name);
void renderNamedFrame(Model*, const glm::vec3& pos, const glm::quat& rot, const glm::vec3& scale, const std::string& name);
void renderGeometry(Model*, size_t geom, const glm::mat4& modelMatrix, GTAVehicle* vehicle = nullptr);
void renderGeometry(Model*, size_t geom, const glm::mat4& modelMatrix, GTAObject* = nullptr);
void renderModel(Model*, const glm::mat4& modelMatrix, GTAVehicle* = nullptr);
void renderModel(Model*, const glm::mat4& modelMatrix, GTAObject* = nullptr);
};
#endif