From 5574eccebd16ae38a2a21ed202d1f9d1ba8f67a4 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Wed, 26 Dec 2012 20:58:02 +0100 Subject: Engine optimization - rewritten model management - new class CModelManager - rewritten engine object structure in CEngine - created shared model data instead of separate objects per each model instance - minor refactoring --- src/graphics/engine/modelmanager.cpp | 213 +++++++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 src/graphics/engine/modelmanager.cpp (limited to 'src/graphics/engine/modelmanager.cpp') diff --git a/src/graphics/engine/modelmanager.cpp b/src/graphics/engine/modelmanager.cpp new file mode 100644 index 0000000..afaa718 --- /dev/null +++ b/src/graphics/engine/modelmanager.cpp @@ -0,0 +1,213 @@ +#include "graphics/engine/modelmanager.h" + +#include "app/app.h" + +#include "common/logger.h" + +#include "graphics/engine/engine.h" + +#include + +namespace Gfx { + +template<> CModelManager* CSingleton::mInstance = nullptr; + +CModelManager::CModelManager(CEngine* engine) +{ + m_engine = engine; +} + +CModelManager::~CModelManager() +{ +} + +bool CModelManager::LoadModel(const std::string& fileName, bool mirrored) +{ + GetLogger()->Info("Loading model '%s'\n", fileName.c_str()); + + CModelFile modelFile; + + std::string filePath = CApplication::GetInstance().GetDataFilePath(DIR_MODEL, fileName); + + if (!modelFile.ReadModel(filePath)) + { + GetLogger()->Error("Loading model '%s' failed\n", filePath.c_str()); + return false; + } + + ModelInfo modelInfo; + modelInfo.baseObjRank = m_engine->CreateBaseObject(); + modelInfo.triangles = modelFile.GetTriangles(); + + if (mirrored) + Mirror(modelInfo.triangles); + + FileInfo fileInfo(fileName, mirrored); + m_models[fileInfo] = modelInfo; + + std::vector vs(3, VertexTex2()); + + float limit[2]; + limit[0] = m_engine->GetLimitLOD(0); // frontier AB as config + limit[1] = m_engine->GetLimitLOD(1); // frontier BC as config + + for (int i = 0; i < static_cast( modelInfo.triangles.size() ); i++) + { + float min = modelInfo.triangles[i].min; + float max = modelInfo.triangles[i].max; + + // Standard frontiers -> config + if (min == 0.0f && max == 100.0f) // resolution A ? + { + max = limit[0]; + } + else if (min == 100.0f && max == 200.0f) // resolution B ? + { + min = limit[0]; + max = limit[1]; + } + else if (min == 200.0f && max == 1000000.0f) // resolution C ? + { + min = limit[1]; + } + + int state = modelInfo.triangles[i].state; + std::string tex2Name = modelInfo.triangles[i].tex2Name; + + if (modelInfo.triangles[i].variableTex2) + { + int texNum = m_engine->GetSecondTexture(); + + if (texNum >= 1 && texNum <= 10) + state |= ENG_RSTATE_DUAL_BLACK; + + if (texNum >= 11 && texNum <= 20) + state |= ENG_RSTATE_DUAL_WHITE; + + char name[20] = { 0 }; + sprintf(name, "dirty%.2d.png", texNum); + tex2Name = name; + } + + vs[0] = modelInfo.triangles[i].p1; + vs[1] = modelInfo.triangles[i].p2; + vs[2] = modelInfo.triangles[i].p3; + + m_engine->AddBaseObjTriangles(modelInfo.baseObjRank, vs, ENG_TRIANGLE_TYPE_TRIANGLES, + modelInfo.triangles[i].material, state, + modelInfo.triangles[i].tex1Name, tex2Name, + min, max, false); + } + + return true; +} + +bool CModelManager::AddModelReference(const std::string& fileName, bool mirrored, int objRank) +{ + auto it = m_models.find(FileInfo(fileName, mirrored)); + if (it == m_models.end()) + { + if (!LoadModel(fileName, mirrored)) + return false; + + it = m_models.find(FileInfo(fileName, mirrored)); + } + + m_engine->SetObjectBaseRank(objRank, (*it).second.baseObjRank); + + return true; +} + +bool CModelManager::AddModelCopy(const std::string& fileName, bool mirrored, int objRank) +{ + auto it = m_models.find(FileInfo(fileName, mirrored)); + if (it == m_models.end()) + { + if (!LoadModel(fileName, mirrored)) + return false; + + it = m_models.find(FileInfo(fileName, mirrored)); + } + + int copyBaseObjRank = m_engine->CreateBaseObject(); + m_engine->CopyBaseObject((*it).second.baseObjRank, copyBaseObjRank); + m_engine->SetObjectBaseRank(objRank, copyBaseObjRank); + + return true; +} + +bool CModelManager::IsModelLoaded(const std::string& fileName, bool mirrored) +{ + return m_models.count(FileInfo(fileName, mirrored)) > 0; +} + +int CModelManager::GetModelBaseObjRank(const std::string& fileName, bool mirrored) +{ + auto it = m_models.find(FileInfo(fileName, mirrored)); + if (it == m_models.end()) + return -1; + + return (*it).second.baseObjRank; +} + +void CModelManager::UnloadModel(const std::string& fileName, bool mirrored) +{ + auto it = m_models.find(FileInfo(fileName, mirrored)); + if (it == m_models.end()) + return; + + m_engine->DeleteBaseObject((*it).second.baseObjRank); + + m_models.erase(it); +} + +void CModelManager::UnloadAllModels() +{ + for (auto& mf : m_models) + m_engine->DeleteBaseObject(mf.second.baseObjRank); + + m_models.clear(); +} + +void CModelManager::Mirror(std::vector& triangles) +{ + for (int i = 0; i < static_cast( triangles.size() ); i++) + { + VertexTex2 t = triangles[i].p1; + triangles[i].p1 = triangles[i].p2; + triangles[i].p2 = t; + + triangles[i].p1.coord.z = -triangles[i].p1.coord.z; + triangles[i].p2.coord.z = -triangles[i].p2.coord.z; + triangles[i].p3.coord.z = -triangles[i].p3.coord.z; + + triangles[i].p1.normal.z = -triangles[i].p1.normal.z; + triangles[i].p2.normal.z = -triangles[i].p2.normal.z; + triangles[i].p3.normal.z = -triangles[i].p3.normal.z; + } +} + +float CModelManager::GetHeight(std::vector& triangles, Math::Vector pos) +{ + const float limit = 5.0f; + + for (int i = 0; i < static_cast( triangles.size() ); i++) + { + if ( fabs(pos.x - triangles[i].p1.coord.x) < limit && + fabs(pos.z - triangles[i].p1.coord.z) < limit ) + return triangles[i].p1.coord.y; + + if ( fabs(pos.x - triangles[i].p2.coord.x) < limit && + fabs(pos.z - triangles[i].p2.coord.z) < limit ) + return triangles[i].p2.coord.y; + + if ( fabs(pos.x - triangles[i].p3.coord.x) < limit && + fabs(pos.z - triangles[i].p3.coord.z) < limit ) + return triangles[i].p3.coord.y; + } + + return 0.0f; +} + + +} -- cgit v1.2.3-1-g7c22