From a937a7b6ec081ab546505e5ab1fcd9b3723a6f4b Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 27 Jan 2013 11:43:53 +0100 Subject: Changed model min/max to LOD levels --- src/graphics/engine/engine.cpp | 199 +++++++++------------------- src/graphics/engine/engine.h | 41 +++--- src/graphics/engine/modelfile.cpp | 146 ++++++++++++-------- src/graphics/engine/modelfile.h | 35 +++-- src/graphics/engine/modelmanager.cpp | 24 +--- src/graphics/engine/pyro.cpp | 38 ++++-- src/graphics/engine/terrain.cpp | 13 +- src/graphics/engine/terrain.h | 2 +- src/graphics/engine/test/modelfile_test.cpp | 17 +-- src/object/auto/autoportico.cpp | 8 +- src/object/brain.cpp | 1 + src/object/motion/motionvehicle.cpp | 41 ++---- src/object/object.cpp | 42 +++--- src/tools/convert_model.cpp | 42 +++--- 14 files changed, 281 insertions(+), 368 deletions(-) (limited to 'src') diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 7c90a8d..71b5e7d 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -109,13 +109,9 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_lookatPt = Math::Vector(0.0f, 0.0f, 1.0f); m_drawWorld = true; m_drawFront = false; - m_limitLOD[0] = 100.0f; - m_limitLOD[1] = 200.0f; m_particleDensity = 1.0f; - m_clippingDistance = 1.0f; m_lastClippingDistance = m_clippingDistance = 1.0f; m_objectDetail = 1.0f; - m_lastObjectDetail = m_objectDetail; m_terrainVision = 1000.0f; m_gadgetQuantity = 1.0f; m_textureQuality = 1; @@ -130,7 +126,6 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_editIndentValue = 4; m_tracePrecision = 1.0f; - m_alphaMode = 1; m_updateGeometry = false; m_updateStaticBuffers = false; @@ -208,7 +203,7 @@ CText* CEngine::GetText() bool CEngine::Create() { - m_size = m_lastSize = m_app->GetVideoConfig().size; + m_size = m_app->GetVideoConfig().size; m_lightMan = new CLightManager(m_iMan, this); m_text = new CText(m_iMan, this); @@ -416,11 +411,6 @@ Math::IntPoint CEngine::GetWindowSize() return m_size; } -Math::IntPoint CEngine::GetLastWindowSize() -{ - return m_lastSize; -} - Math::Point CEngine::WindowToInterfaceCoords(Math::IntPoint pos) { return Math::Point( static_cast(pos.x) / static_cast(m_size.x), @@ -473,15 +463,15 @@ EngineBaseObjTexTier& CEngine::AddLevel2(EngineBaseObject& p1, const std::string return p1.next.back(); } -EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, float min, float max) +EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, LODLevel lodLevel) { for (int i = 0; i < static_cast( p2.next.size() ); i++) { - if ( (p2.next[i].min == min) && (p2.next[i].max == max) ) + if (p2.next[i].lodLevel == lodLevel) return p2.next[i]; } - p2.next.push_back(EngineBaseObjLODTier(min, max)); + p2.next.push_back(EngineBaseObjLODTier(lodLevel)); return p2.next.back(); } @@ -570,17 +560,13 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector EngineTriangleType triangleType, const Material& material, int state, std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate) + LODLevel lodLevel, bool globalUpdate) { assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); - m_lastSize = m_size; - m_lastObjectDetail = m_objectDetail; - m_lastClippingDistance = m_clippingDistance; - EngineBaseObject& p1 = m_baseObjects[baseObjRank]; EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name); - EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max); + EngineBaseObjLODTier& p3 = AddLevel3(p2, lodLevel); EngineBaseObjDataTier& p4 = AddLevel4(p3, triangleType, material, state); p4.vertices.insert(p4.vertices.end(), vertices.begin(), vertices.end()); @@ -615,13 +601,13 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer, std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate) + LODLevel lodLevel, bool globalUpdate) { assert(baseObjRank >= 0 && baseObjRank < static_cast( m_baseObjects.size() )); EngineBaseObject& p1 = m_baseObjects[baseObjRank]; EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name); - EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max); + EngineBaseObjLODTier& p3 = AddLevel3(p2, lodLevel); p3.next.push_back(buffer); @@ -797,7 +783,7 @@ int CEngine::GetObjectTotalTriangles(int objRank) EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& material, int state, std::string tex1Name, - std::string tex2Name, float min, float max) + std::string tex2Name, int lodLevelMask) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); @@ -820,7 +806,7 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (p3.min != min || p3.max != max) + if ((p3.lodLevel & lodLevelMask) == 0) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -839,7 +825,7 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater return nullptr; } -int CEngine::GetPartialTriangles(int objRank, float min, float max, float percent, int maxCount, +int CEngine::GetPartialTriangles(int objRank, int lodLevelMask, float percent, int maxCount, std::vector& triangles) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); @@ -866,7 +852,7 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (p3.min != min || p3.max != max) + if ((p3.lodLevel & lodLevelMask) == 0) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -928,68 +914,6 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen return actualCount; } -void CEngine::ChangeLOD() -{ - float oldLimit[2] = - { - GetLimitLOD(0, true), - GetLimitLOD(1, true) - }; - - float newLimit[2] = - { - GetLimitLOD(0, false), - GetLimitLOD(1, false) - }; - - float oldTerrain = m_terrainVision * m_lastClippingDistance; - float newTerrain = m_terrainVision * m_clippingDistance; - - for (int baseObjRank = 0; baseObjRank < static_cast( m_baseObjects.size() ); baseObjRank++) - { - EngineBaseObject& p1 = m_baseObjects[baseObjRank]; - - if (! p1.used) - continue; - - for (int l2 = 0; l2 < static_cast( p1.next.size() ); l2++) - { - EngineBaseObjTexTier& p2 = p1.next[l2]; - - for (int l3 = 0; l3 < static_cast( p2.next.size() ); l3++) - { - EngineBaseObjLODTier& p3 = p2.next[l3]; - - if ( Math::IsEqual(p3.min, 0.0f ) && - Math::IsEqual(p3.max, oldLimit[0]) ) - { - p3.max = newLimit[0]; - } - else if ( Math::IsEqual(p3.min, oldLimit[0]) && - Math::IsEqual(p3.max, oldLimit[1]) ) - { - p3.min = newLimit[0]; - p3.max = newLimit[1]; - } - else if ( Math::IsEqual(p3.min, oldLimit[1]) && - Math::IsEqual(p3.max, 1000000.0f ) ) - { - p3.min = newLimit[1]; - } - else if ( Math::IsEqual(p3.min, 0.0f ) && - Math::IsEqual(p3.max, oldTerrain) ) - { - p3.max = newTerrain; - } - } - } - } - - m_lastSize = m_size; - m_lastObjectDetail = m_objectDetail; - m_lastClippingDistance = m_clippingDistance; -} - void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); @@ -1016,12 +940,12 @@ void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name) void CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, + int lodLevelMask, EngineTextureMapping mode, float au, float bu, float av, float bv) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max); + EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, lodLevelMask); if (p4 == nullptr) return; @@ -1078,12 +1002,12 @@ void CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state, void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, + int lodLevelMask, EngineTextureMapping mode, float pos, float factor, float tl, float ts, float tt) { assert(objRank >= 0 && objRank < static_cast( m_objects.size() )); - EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, min, max); + EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, lodLevelMask); if (p4 == nullptr) return; @@ -1707,8 +1631,8 @@ int CEngine::DetectObject(Math::Point mouse) { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (p3.min != 0.0f) - continue; // LOD B or C? + if (p3.lodLevel != LOD_Constant && p3.lodLevel != LOD_High) + continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) { @@ -1820,6 +1744,43 @@ bool CEngine::IsVisible(int objRank) return false; } +bool CEngine::IsWithinLODLimit(float distance, LODLevel lodLevel) +{ + float min = 0.0f, max = 0.0f; + + if (lodLevel == LOD_Constant) + { + min = 0.0f; + max = m_terrainVision * m_clippingDistance; + } + else + { + if (lodLevel == LOD_High) + { + min = 0.0f; + max = 100.0f; + } + else if (lodLevel == LOD_Medium) + { + min = 100.0f; + max = 200.0f; + } + else if (lodLevel == LOD_Low) + { + min = 100.0f; + max = 1000000.0f; + } + + min *= m_size.x / 640.0f; + min *= m_objectDetail*2.0f; + + max *= m_size.x / 640.0f; + max *= m_objectDetail*2.0f; + } + + return distance >= min && distance < max; +} + bool CEngine::TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D) { assert(objRank >= 0 && objRank < static_cast(m_objects.size())); @@ -1856,15 +1817,6 @@ void CEngine::SetState(int state, const Color& color) m_lastState = state; m_lastColor = color; - if (m_alphaMode != 1 && (state & ENG_RSTATE_ALPHA)) - { - state &= ~ENG_RSTATE_ALPHA; - - if (m_alphaMode == 2) - state |= ENG_RSTATE_TTEXTURE_BLACK; - } - - if (state & ENG_RSTATE_TTEXTURE_BLACK) // transparent black texture? { m_device->SetRenderState(RENDER_STATE_FOG, false); @@ -2447,33 +2399,6 @@ void CEngine::SetTexture(const Texture& tex, int stage) m_device->SetTexture(stage, tex); } -void CEngine::SetLimitLOD(int rank, float limit) -{ - m_limitLOD[rank] = limit; -} - -float CEngine::GetLimitLOD(int rank, bool last) -{ - float limit = 0.0f; - - if (last) - { - limit = m_limitLOD[rank]; - limit *= m_lastSize.x/640.0f; // limit further if large window! - limit += m_limitLOD[0]*(m_lastObjectDetail*2.0f); - } - else - { - limit = m_limitLOD[rank]; - limit *= m_size.x/640.0f; // limit further if large window! - limit += m_limitLOD[0]*(m_objectDetail*2.0f); - } - - if (limit < 0.0f) limit = 0.0f; - - return limit; -} - void CEngine::SetTerrainVision(float vision) { m_terrainVision = vision; @@ -2709,6 +2634,7 @@ void CEngine::SetClippingDistance(float value) { if (value < 0.5f) value = 0.5f; if (value > 2.0f) value = 2.0f; + m_lastClippingDistance = m_clippingDistance; m_clippingDistance = value; } @@ -2920,7 +2846,6 @@ void CEngine::ApplyChange() m_deepView[1] /= m_lastClippingDistance; SetFocus(m_focus); - ChangeLOD(); m_deepView[0] *= m_clippingDistance; m_deepView[1] *= m_clippingDistance; @@ -3040,8 +2965,7 @@ void CEngine::Draw3DScene() { EngineBaseObjLODTier& p3 = p2.next[l3]; - if ( m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max ) + if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel)) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -3108,8 +3032,7 @@ void CEngine::Draw3DScene() { EngineBaseObjLODTier& p3 = p2.next[l3]; - if ( m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max ) + if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel)) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -3177,8 +3100,7 @@ void CEngine::Draw3DScene() { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max) + if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel)) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) @@ -3330,8 +3252,7 @@ void CEngine::DrawInterface() { EngineBaseObjLODTier& p3 = p2.next[l3]; - if (m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max) + if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel)) continue; for (int l4 = 0; l4 < static_cast( p3.next.size() ); l4++) diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index c9391db..e5c75bc 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -32,6 +32,8 @@ #include "graphics/core/texture.h" #include "graphics/core/vertex.h" +#include "graphics/engine/modelfile.h" + #include "math/intpoint.h" #include "math/matrix.h" #include "math/point.h" @@ -204,12 +206,11 @@ struct EngineBaseObjDataTier */ struct EngineBaseObjLODTier { - float min; - float max; + LODLevel lodLevel; std::vector next; - inline EngineBaseObjLODTier(float min = 0.0f, float max = 0.0f) - : min(min), max(max) {} + inline EngineBaseObjLODTier(LODLevel lodLevel = LOD_Constant) + : lodLevel(lodLevel) {} }; /** @@ -777,12 +778,12 @@ public: EngineTriangleType triangleType, const Material& material, int state, std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate); + LODLevel lodLevel, bool globalUpdate); //! Adds a tier 4 engine object directly void AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer, std::string tex1Name, std::string tex2Name, - float min, float max, bool globalUpdate); + LODLevel lodLevel, bool globalUpdate); // Objects @@ -827,29 +828,26 @@ public: //! Returns the first found tier 4 engine object for the given params or nullptr if not found EngineBaseObjDataTier* FindTriangles(int objRank, const Material& material, - int state, std::string tex1Name, std::string tex2Name, - float min, float max); + int state, std::string tex1Name, std::string tex2Name, + int lodLevelMask); //! Returns a partial list of triangles for given object - int GetPartialTriangles(int objRank, float min, float max, float percent, int maxCount, + int GetPartialTriangles(int objRank, int lodLevelMask, float percent, int maxCount, std::vector& triangles); - //! Updates LOD after parameter or resolution change - void ChangeLOD(); - //! Changes the 2nd texure for given object void ChangeSecondTexture(int objRank, const std::string& tex2Name); //! Changes (recalculates) texture mapping for given object void ChangeTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, + int lodLevelMask, EngineTextureMapping mode, float au, float bu, float av, float bv); //! Changes texture mapping for robot tracks void TrackTextureMapping(int objRank, const Material& mat, int state, const std::string& tex1Name, const std::string& tex2Name, - float min, float max, EngineTextureMapping mode, + int lodLevelMask, EngineTextureMapping mode, float pos, float factor, float tl, float ts, float tt); //! Detects the target object that is selected with the mouse @@ -947,12 +945,6 @@ public: //! Deletes the given texture, unloading it and removing from cache void DeleteTexture(const Texture& tex); - //@{ - //! Border management (distance limits) depends of the resolution (LOD = level-of-detail) - void SetLimitLOD(int rank, float limit); - float GetLimitLOD(int rank, bool last=false); - //@} - //! Defines of the distance field of vision void SetTerrainVision(float vision); @@ -1219,7 +1211,7 @@ protected: //! Creates a new tier 2 object (texture) EngineBaseObjTexTier& AddLevel2(EngineBaseObject& p1, const std::string& tex1Name, const std::string& tex2Name); //! Creates a new tier 3 object (LOD) - EngineBaseObjLODTier& AddLevel3(EngineBaseObjTexTier &p2, float min, float max); + EngineBaseObjLODTier& AddLevel3(EngineBaseObjTexTier &p2, LODLevel lodLevel); //! Creates a new tier 4 object (data) EngineBaseObjDataTier& AddLevel4(EngineBaseObjLODTier &p3, EngineTriangleType type, const Material& mat, int state); @@ -1230,6 +1222,9 @@ protected: //! Tests whether the given object is visible bool IsVisible(int objRank); + //! Checks whether the given distance is within LOD min & max limit + bool IsWithinLODLimit(float distance, LODLevel lodLevel); + //! Detects whether an object is affected by the mouse bool DetectBBox(int objRank, Math::Point mouse); @@ -1304,8 +1299,6 @@ protected: //! Current size of viewport window Math::IntPoint m_size; - //! Previous size of viewport window - Math::IntPoint m_lastSize; //! Base objects (also level 1 tier list) std::vector m_baseObjects; @@ -1356,12 +1349,10 @@ protected: Texture m_foregroundTex; bool m_drawWorld; bool m_drawFront; - float m_limitLOD[2]; float m_particleDensity; float m_clippingDistance; float m_lastClippingDistance; float m_objectDetail; - float m_lastObjectDetail; float m_terrainVision; float m_gadgetQuantity; int m_textureQuality; diff --git a/src/graphics/engine/modelfile.cpp b/src/graphics/engine/modelfile.cpp index a942b08..c9d41f3 100644 --- a/src/graphics/engine/modelfile.cpp +++ b/src/graphics/engine/modelfile.cpp @@ -495,8 +495,7 @@ bool CModelFile::ReadModel(std::istream& stream) triangle.material = t.material; triangle.tex1Name = std::string(t.texName); - triangle.min = t.min; - triangle.max = t.max; + triangle.lodLevel = MinMaxToLodLevel(t.min, t.max); m_triangles.push_back(triangle); } @@ -539,8 +538,7 @@ bool CModelFile::ReadModel(std::istream& stream) triangle.material = t.material; triangle.tex1Name = std::string(t.texName); - triangle.min = t.min; - triangle.max = t.max; + triangle.lodLevel = MinMaxToLodLevel(t.min, t.max); triangle.state = t.state; m_triangles.push_back(triangle); @@ -584,8 +582,7 @@ bool CModelFile::ReadModel(std::istream& stream) triangle.material = t.material; triangle.tex1Name = std::string(t.texName); - triangle.min = t.min; - triangle.max = t.max; + triangle.lodLevel = MinMaxToLodLevel(t.min, t.max); triangle.state = t.state; triangle.variableTex2 = t.texNum2 == 1; @@ -634,7 +631,7 @@ bool CModelFile::ReadModel(std::istream& stream) GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), m_triangles[i].variableTex2 ? "(variable)" : m_triangles[i].tex2Name.c_str()); - GetLogger()->Trace(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); + GetLogger()->Trace(" lod level: %d\n", m_triangles[i].lodLevel); GetLogger()->Trace(" state: %ld\n", m_triangles[i].state); } @@ -685,8 +682,7 @@ bool CModelFile::WriteModel(std::ostream& stream) t.material = m_triangles[i].material; strncpy(t.texName, m_triangles[i].tex1Name.c_str(), 20); - t.min = m_triangles[i].min; - t.max = m_triangles[i].max; + LODLevelToMinMax(m_triangles[i].lodLevel, t.min, t.max); t.state = m_triangles[i].state; int no = 0; @@ -722,6 +718,46 @@ bool CModelFile::WriteModel(std::ostream& stream) return true; } +LODLevel CModelFile::MinMaxToLodLevel(float min, float max) +{ + if (min == 0.0f && max == 100.0f) + return LOD_High; + else if (min == 100.0f && max == 200.0f) + return LOD_Medium; + else if (min == 200.0f && max == 1000000.0f) + return LOD_Low; + else if (min == 0.0f && max == 1000000.0f) + return LOD_Constant; + + return LOD_Constant; +} + +void CModelFile::LODLevelToMinMax(LODLevel lodLevel, float& min, float& max) +{ + switch (lodLevel) + { + case LOD_High: + min = 0.0f; + max = 100.0f; + break; + + case LOD_Medium: + min = 100.0f; + max = 200.0f; + break; + + case LOD_Low: + min = 200.0f; + max = 1000000.0f; + break; + + case LOD_Constant: + min = 0.0f; + max = 1000000.0f; + break; + } +} + /******************************************************* New formats @@ -768,17 +804,15 @@ struct NewModelTriangle1 std::string tex2Name; //! If true, 2nd texture will be taken from current engine setting bool variableTex2; - //! Min LOD threshold - float min; - //! Max LOD threshold - float max; + //! LOD level + int lodLevel; //! Rendering state to be set int state; NewModelTriangle1() { variableTex2 = true; - min = max = 0.0f; + lodLevel = 0; state = 0; } }; @@ -834,8 +868,7 @@ bool CModelFile::ReadTextModel(std::istream& stream) ReadLineValue(stream, "tex1", t.tex1Name) && ReadLineValue(stream, "tex2", t.tex2Name) && ReadLineValue(stream, "var_tex2", varTex2Ch) && - ReadLineValue(stream, "min", t.min) && - ReadLineValue(stream, "max", t.max) && + ReadLineValue(stream, "lod_level", t.lodLevel) && ReadLineValue(stream, "state", t.state); if (!triOk || stream.fail()) @@ -855,10 +888,17 @@ bool CModelFile::ReadTextModel(std::istream& stream) triangle.tex1Name = t.tex1Name; triangle.tex2Name = t.tex2Name; triangle.variableTex2 = t.variableTex2; - triangle.min = t.min; - triangle.max = t.max; triangle.state = t.state; + switch (t.lodLevel) + { + case 0: triangle.lodLevel = LOD_Constant; break; + case 1: triangle.lodLevel = LOD_Low; break; + case 2: triangle.lodLevel = LOD_Medium; break; + case 3: triangle.lodLevel = LOD_High; break; + default: break; + } + m_triangles.push_back(triangle); continue; @@ -886,7 +926,7 @@ bool CModelFile::ReadTextModel(std::istream& stream) GetLogger()->Trace(" mat: d: %s a: %s s: %s\n", d.c_str(), a.c_str(), s.c_str()); GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), m_triangles[i].tex2Name.c_str()); - GetLogger()->Trace(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); + GetLogger()->Trace(" lod level: %d\n", m_triangles[i].lodLevel); GetLogger()->Trace(" state: %ld\n", m_triangles[i].state); } @@ -938,10 +978,16 @@ bool CModelFile::WriteTextModel(std::ostream& stream) t.tex1Name = m_triangles[i].tex1Name; t.tex2Name = m_triangles[i].tex2Name; t.variableTex2 = m_triangles[i].variableTex2; - t.min = m_triangles[i].min; - t.max = m_triangles[i].max; t.state = m_triangles[i].state; + switch (m_triangles[i].lodLevel) + { + case LOD_Constant: t.lodLevel = 0; break; + case LOD_Low: t.lodLevel = 1; break; + case LOD_Medium: t.lodLevel = 2; break; + case LOD_High: t.lodLevel = 3; break; + } + stream << "p1 "; WriteTextVertexTex2(t.p1, stream); stream << "p2 "; @@ -954,8 +1000,7 @@ bool CModelFile::WriteTextModel(std::ostream& stream) stream << "tex1 " << t.tex1Name << std::endl; stream << "tex2 " << t.tex2Name << std::endl; stream << "var_tex2 " << (t.variableTex2 ? 'Y' : 'N') << std::endl; - stream << "min " << t.min << std::endl; - stream << "max " << t.max << std::endl; + stream << "lod_level " << t.lodLevel << std::endl; stream << "state " << t.state << std::endl; stream << std::endl; @@ -1012,9 +1057,8 @@ bool CModelFile::ReadBinaryModel(std::istream& stream) t.tex1Name = IOUtils::ReadBinaryString<1>(stream); t.tex2Name = IOUtils::ReadBinaryString<1>(stream); t.variableTex2 = IOUtils::ReadBinaryBool(stream); - t.min = IOUtils::ReadBinaryFloat(stream); - t.max = IOUtils::ReadBinaryFloat(stream); - t.state = IOUtils::ReadBinary<4, unsigned int>(stream); + t.lodLevel = IOUtils::ReadBinary<4, int>(stream); + t.state = IOUtils::ReadBinary<4, int>(stream); if (stream.fail()) { @@ -1030,10 +1074,17 @@ bool CModelFile::ReadBinaryModel(std::istream& stream) triangle.tex1Name = t.tex1Name; triangle.tex2Name = t.tex2Name; triangle.variableTex2 = t.variableTex2; - triangle.min = t.min; - triangle.max = t.max; triangle.state = t.state; + switch (t.lodLevel) + { + case 0: triangle.lodLevel = LOD_Constant; break; + case 1: triangle.lodLevel = LOD_Low; break; + case 2: triangle.lodLevel = LOD_Medium; break; + case 3: triangle.lodLevel = LOD_High; break; + default: break; + } + m_triangles.push_back(triangle); } } @@ -1059,7 +1110,7 @@ bool CModelFile::ReadBinaryModel(std::istream& stream) GetLogger()->Trace(" mat: d: %s a: %s s: %s\n", d.c_str(), a.c_str(), s.c_str()); GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), m_triangles[i].tex2Name.c_str()); - GetLogger()->Trace(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); + GetLogger()->Trace(" lod level: %d\n", m_triangles[i].lodLevel); GetLogger()->Trace(" state: %ld\n", m_triangles[i].state); } @@ -1106,10 +1157,16 @@ bool CModelFile::WriteBinaryModel(std::ostream& stream) t.tex1Name = m_triangles[i].tex1Name; t.tex2Name = m_triangles[i].tex2Name; t.variableTex2 = m_triangles[i].variableTex2; - t.min = m_triangles[i].min; - t.max = m_triangles[i].max; t.state = m_triangles[i].state; + switch (m_triangles[i].lodLevel) + { + case LOD_Constant: t.lodLevel = 0; break; + case LOD_Low: t.lodLevel = 1; break; + case LOD_Medium: t.lodLevel = 2; break; + case LOD_High: t.lodLevel = 3; break; + } + WriteBinaryVertexTex2(t.p1, stream); WriteBinaryVertexTex2(t.p2, stream); WriteBinaryVertexTex2(t.p3, stream); @@ -1117,9 +1174,8 @@ bool CModelFile::WriteBinaryModel(std::ostream& stream) IOUtils::WriteBinaryString<1>(t.tex1Name, stream); IOUtils::WriteBinaryString<1>(t.tex2Name, stream); IOUtils::WriteBinaryBool(t.variableTex2, stream); - IOUtils::WriteBinaryFloat(t.min, stream); - IOUtils::WriteBinaryFloat(t.max, stream); - IOUtils::WriteBinary<4, unsigned int>(t.state, stream); + IOUtils::WriteBinary<4, int>(t.lodLevel, stream); + IOUtils::WriteBinary<4, int>(t.state, stream); if (stream.fail()) { @@ -1132,10 +1188,6 @@ bool CModelFile::WriteBinaryModel(std::ostream& stream) } -/******************************************************* - Other stuff - *******************************************************/ - const std::vector& CModelFile::GetTriangles() { return m_triangles; @@ -1146,23 +1198,5 @@ int CModelFile::GetTriangleCount() return m_triangles.size(); } -void CModelFile::CreateTriangle(Math::Vector p1, Math::Vector p2, Math::Vector p3, float min, float max) -{ - ModelTriangle triangle; - - Math::Vector n = Math::NormalToPlane(p3, p2, p1); - triangle.p1 = VertexTex2(p1, n); - triangle.p2 = VertexTex2(p2, n); - triangle.p3 = VertexTex2(p3, n); - - triangle.material.diffuse = Color(1.0f, 1.0f, 1.0f, 0.0f); - triangle.material.ambient = Color(0.5f, 0.5f, 0.5f, 0.0f); - - triangle.min = min; - triangle.max = max; - - m_triangles.push_back(triangle); -} - } // namespace Gfx diff --git a/src/graphics/engine/modelfile.h b/src/graphics/engine/modelfile.h index b2b5d87..3a702cb 100644 --- a/src/graphics/engine/modelfile.h +++ b/src/graphics/engine/modelfile.h @@ -39,9 +39,23 @@ namespace Gfx { /** - \struct ModelTriangle - \brief Triangle of a 3D model - */ + * \enum LODLevel + * \brief Level-of-detail + * + * A quantified replacement for older values of min/max. + */ +enum LODLevel +{ + LOD_Constant = -1, //!< triangle is always visible, no matter at what distance + LOD_Low = 1, //!< triangle is visible at farthest distance (lowest quality) + LOD_Medium = 2, //!< triangle is visible at medium distance (medium quality) + LOD_High = 4 //!< triangle is visible at closest distance (highest quality) +}; + +/** + * \struct ModelTriangle + * \brief Triangle of a 3D model + */ struct ModelTriangle { //! 1st vertex @@ -58,17 +72,15 @@ struct ModelTriangle std::string tex2Name; //! If true, 2nd texture will be taken from current engine setting bool variableTex2; - //! Min LOD threshold - float min; - //! Max LOD threshold - float max; + //! LOD level + LODLevel lodLevel; //! Rendering state to be set int state; ModelTriangle() { variableTex2 = true; - min = max = 0.0f; + lodLevel = LOD_Constant; state = 0; } }; @@ -126,8 +138,11 @@ public: const std::vector& GetTriangles(); protected: - //! Adds a triangle to the list - void CreateTriangle(Math::Vector p1, Math::Vector p2, Math::Vector p3, float min, float max); + //@{ + //! @deprecated min, max conversions + LODLevel MinMaxToLodLevel(float min, float max); + void LODLevelToMinMax(LODLevel lodLevel, float& min, float& max); + //@} protected: //! Model triangles diff --git a/src/graphics/engine/modelmanager.cpp b/src/graphics/engine/modelmanager.cpp index 5b17769..051922f 100644 --- a/src/graphics/engine/modelmanager.cpp +++ b/src/graphics/engine/modelmanager.cpp @@ -47,30 +47,8 @@ bool CModelManager::LoadModel(const std::string& fileName, bool mirrored) 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; @@ -96,7 +74,7 @@ bool CModelManager::LoadModel(const std::string& fileName, bool mirrored) m_engine->AddBaseObjTriangles(modelInfo.baseObjRank, vs, ENG_TRIANGLE_TYPE_TRIANGLES, modelInfo.triangles[i].material, state, modelInfo.triangles[i].tex1Name, tex2Name, - min, max, false); + modelInfo.triangles[i].lodLevel, false); } return true; diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index 978471b..e374d6c 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -1397,27 +1397,39 @@ void CPyro::CreateTriangle(CObject* obj, ObjectType oType, int part) int objRank = obj->GetObjectRank(part); if (objRank == -1) return; - float min = 0.0f; - float max = m_engine->GetLimitLOD(0); + int total = m_engine->GetObjectTotalTriangles(objRank); + float percent = 0.10f; if (total < 50) percent = 0.25f; if (total < 20) percent = 0.50f; if (m_type == PT_EGG) percent = 0.30f; - if ( oType == OBJECT_POWER || - oType == OBJECT_ATOMIC || - oType == OBJECT_URANIUM || - oType == OBJECT_TNT || - oType == OBJECT_BOMB ) percent = 0.75f; - if ( oType == OBJECT_MOBILEtg ) percent = 0.50f; - if ( oType == OBJECT_TEEN28 ) percent = 0.75f; - if ( oType == OBJECT_MOTHER ) max = 1000000.0f; - if ( oType == OBJECT_TEEN28 ) max = 1000000.0f; - if ( oType == OBJECT_TEEN31 ) max = 1000000.0f; + if (oType == OBJECT_POWER || + oType == OBJECT_ATOMIC || + oType == OBJECT_URANIUM || + oType == OBJECT_TNT || + oType == OBJECT_BOMB || + oType == OBJECT_TEEN28) + { + percent = 0.75f; + } + else if (oType == OBJECT_MOBILEtg) + { + percent = 0.50f; + } + + LODLevel lodLevel = LOD_High; + + if (oType == OBJECT_MOTHER || + oType == OBJECT_TEEN28 || + oType == OBJECT_TEEN31) + { + lodLevel = LOD_Constant; + } std::vector buffer; - total = m_engine->GetPartialTriangles(objRank, min, max, percent, 100, buffer); + total = m_engine->GetPartialTriangles(objRank, lodLevel, percent, 100, buffer); for (int i = 0; i < total; i++) { diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp index a66b4b0..0be75bc 100644 --- a/src/graphics/engine/terrain.cpp +++ b/src/graphics/engine/terrain.cpp @@ -487,8 +487,7 @@ VertexTex2 CTerrain::GetVertex(int x, int y, int step) +-------------------> x \endverbatim */ bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, - const Material &mat, - float min, float max) + const Material &mat) { int baseObjRank = m_engine->GetObjectBaseRank(objRank); if (baseObjRank == -1) @@ -640,7 +639,7 @@ bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, buffer.vertices.push_back(p2); } - m_engine->AddBaseObjQuick(baseObjRank, buffer, texName1, texName2, min, max, true); + m_engine->AddBaseObjQuick(baseObjRank, buffer, texName1, texName2, LOD_Constant, true); } } } @@ -1170,15 +1169,9 @@ bool CTerrain::CreateSquare(int x, int y) m_objRanks[x+y*m_mosaicCount] = objRank; - float min = 0.0f; - float max = m_vision; - max *= m_engine->GetClippingDistance(); for (int step = 0; step < m_depth; step++) { - CreateMosaic(x, y, 1 << step, objRank, mat, min, max); - min = max; - max *= 2; - if (step == m_depth-1) max = Math::HUGE_NUM; + CreateMosaic(x, y, 1 << step, objRank, mat); } return true; diff --git a/src/graphics/engine/terrain.h b/src/graphics/engine/terrain.h index e17144e..91ddc76 100644 --- a/src/graphics/engine/terrain.h +++ b/src/graphics/engine/terrain.h @@ -330,7 +330,7 @@ protected: //! Calculates a vertex of the terrain VertexTex2 GetVertex(int x, int y, int step); //! Creates all objects of a mosaic - bool CreateMosaic(int ox, int oy, int step, int objRank, const Material& mat, float min, float max); + bool CreateMosaic(int ox, int oy, int step, int objRank, const Material& mat); //! Creates all objects in a mesh square ground bool CreateSquare(int x, int y); diff --git a/src/graphics/engine/test/modelfile_test.cpp b/src/graphics/engine/test/modelfile_test.cpp index 43cd43b..e7078a9 100644 --- a/src/graphics/engine/test/modelfile_test.cpp +++ b/src/graphics/engine/test/modelfile_test.cpp @@ -40,8 +40,7 @@ const char* const TEXT_MODEL = "tex1 lemt.png\n" "tex2\n" "var_tex2 N\n" -"min 200\n" -"max 1e+06\n" +"lod_level 0\n" "state 1024\n" "\n" "p1 c -19 -1 4 n -1 0 0 t1 0.248047 0.123047 t2 0.905224 0.52067\n" @@ -51,8 +50,7 @@ const char* const TEXT_MODEL = "tex1 derrick.png\n" "tex2\n" "var_tex2 Y\n" -"min 200\n" -"max 1e+06\n" +"lod_level 1\n" "state 0\n" ""; @@ -81,8 +79,7 @@ void Init() TRIANGLE_1.material.specular = Gfx::Color(0, 0, 0, 0); TRIANGLE_1.tex1Name = "lemt.png"; TRIANGLE_1.variableTex2 = false; - TRIANGLE_1.min = 200.0f; - TRIANGLE_1.max = 1e+06f; + TRIANGLE_1.lodLevel = Gfx::LOD_Constant; TRIANGLE_1.state = 1024; TRIANGLE_2.p1 = Gfx::VertexTex2(Math::Vector(-19, -1, 4), @@ -102,8 +99,7 @@ void Init() TRIANGLE_2.material.specular = Gfx::Color(0, 0, 0, 0); TRIANGLE_2.tex1Name = "derrick.png"; TRIANGLE_2.variableTex2 = true; - TRIANGLE_2.min = 200.0f; - TRIANGLE_2.max = 1e+06f; + TRIANGLE_2.lodLevel = Gfx::LOD_Low; TRIANGLE_2.state = 0; } @@ -171,10 +167,7 @@ bool CompareTriangles(const Gfx::ModelTriangle& t1, const Gfx::ModelTriangle& t2 if (t1.variableTex2 != t2.variableTex2) return false; - if (!Math::IsEqual(t1.min, t2.min)) - return false; - - if (!Math::IsEqual(t1.max, t2.max)) + if (t1.lodLevel != t2.lodLevel) return false; if (t1.state != t2.state) diff --git a/src/object/auto/autoportico.cpp b/src/object/auto/autoportico.cpp index 3b3bf84..c0be784 100644 --- a/src/object/auto/autoportico.cpp +++ b/src/object/auto/autoportico.cpp @@ -398,7 +398,6 @@ Error CAutoPortico::GetError() void CAutoPortico::UpdateTrackMapping(float left, float right) { Gfx::Material mat; - float limit[2]; int rank; memset( &mat, 0, sizeof(Gfx::Material)); @@ -411,15 +410,12 @@ void CAutoPortico::UpdateTrackMapping(float left, float right) rank = m_object->GetObjectRank(0); - limit[0] = 0.0f; - limit[1] = 1000000.0f; - m_engine->TrackTextureMapping(rank, mat, Gfx::ENG_RSTATE_PART1, "lemt.png", "", - limit[0], limit[1], Gfx::ENG_TEX_MAPPING_X, + Gfx::LOD_Constant, Gfx::ENG_TEX_MAPPING_X, right, 8.0f, 8.0f, 192.0f, 256.0f); m_engine->TrackTextureMapping(rank, mat, Gfx::ENG_RSTATE_PART2, "lemt.png", "", - limit[0], limit[1], Gfx::ENG_TEX_MAPPING_X, + Gfx::LOD_Constant, Gfx::ENG_TEX_MAPPING_X, left, 8.0f, 8.0f, 192.0f, 256.0f); } diff --git a/src/object/brain.cpp b/src/object/brain.cpp index ef7309d..d3c0e0b 100644 --- a/src/object/brain.cpp +++ b/src/object/brain.cpp @@ -1947,6 +1947,7 @@ void CBrain::UpdateInterface(float rTime) if ( power == 0 ) { energy = 0.0f; + limit = 0.0f; } else { diff --git a/src/object/motion/motionvehicle.cpp b/src/object/motion/motionvehicle.cpp index 33e746f..3c95a27 100644 --- a/src/object/motion/motionvehicle.cpp +++ b/src/object/motion/motionvehicle.cpp @@ -1877,52 +1877,33 @@ bool CMotionVehicle::EventFrameCanoni(const Event &event) void CMotionVehicle::UpdateTrackMapping(float left, float right, ObjectType type) { - Gfx::Material mat; - float limit[4]; - int rRank, lRank, i; + Gfx::Material mat; + mat.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f); // white + mat.ambient = Gfx::Color(0.5f, 0.5f, 0.5f); - memset( &mat, 0, sizeof(Gfx::Material) ); - mat.diffuse.r = 1.0f; - mat.diffuse.g = 1.0f; - mat.diffuse.b = 1.0f; // white - mat.ambient.r = 0.5f; - mat.ambient.g = 0.5f; - mat.ambient.b = 0.5f; + int rRank = m_object->GetObjectRank(6); + int lRank = m_object->GetObjectRank(7); - rRank = m_object->GetObjectRank(6); - lRank = m_object->GetObjectRank(7); - - - if ( type == OBJECT_MOBILEdr ) + if (type == OBJECT_MOBILEdr) { - limit[0] = 0.0f; - limit[1] = 1000000.0f; - limit[2] = limit[1]; - limit[3] = m_engine->GetLimitLOD(1); - m_engine->TrackTextureMapping(rRank, mat, Gfx::ENG_RSTATE_PART1, "drawer.png", "", - limit[0], limit[1], Gfx::ENG_TEX_MAPPING_X, + Gfx::LOD_Constant, Gfx::ENG_TEX_MAPPING_X, right, 1.0f, 8.0f, 192.0f, 256.0f); m_engine->TrackTextureMapping(lRank, mat, Gfx::ENG_RSTATE_PART2, "drawer.png", "", - limit[0], limit[1], Gfx::ENG_TEX_MAPPING_X, + Gfx::LOD_Constant, Gfx::ENG_TEX_MAPPING_X, left, 1.0f, 8.0f, 192.0f, 256.0f); } else { - limit[0] = 0.0f; - limit[1] = m_engine->GetLimitLOD(0); - limit[2] = limit[1]; - limit[3] = m_engine->GetLimitLOD(1); - - for ( i=0 ; i<2 ; i++ ) + for (int i = 0; i < 2; i++) { m_engine->TrackTextureMapping(rRank, mat, Gfx::ENG_RSTATE_PART1, "lemt.png", "", - limit[i*2+0], limit[i*2+1], Gfx::ENG_TEX_MAPPING_X, + (i == 0) ? Gfx::LOD_High : Gfx::LOD_Medium, Gfx::ENG_TEX_MAPPING_X, right, 1.0f, 8.0f, 192.0f, 256.0f); m_engine->TrackTextureMapping(lRank, mat, Gfx::ENG_RSTATE_PART2, "lemt.png", "", - limit[i*2+0], limit[i*2+1], Gfx::ENG_TEX_MAPPING_X, + (i == 0) ? Gfx::LOD_High : Gfx::LOD_Medium, Gfx::ENG_TEX_MAPPING_X, left, 1.0f, 8.0f, 192.0f, 256.0f); } } diff --git a/src/object/object.cpp b/src/object/object.cpp index 9615866..e2830c5 100644 --- a/src/object/object.cpp +++ b/src/object/object.cpp @@ -5811,21 +5811,16 @@ void CObject::FlatParent() void CObject::UpdateEnergyMapping() { - Gfx::Material mat; - float a, b, i, s, au, bu; - float limit[6]; - int j; + if (Math::IsEqual(m_energy, m_lastEnergy, 0.01f)) + return; - if ( fabs(m_energy-m_lastEnergy) < 0.01f ) return; m_lastEnergy = m_energy; - memset(&mat, 0, sizeof(mat)); - mat.diffuse.r = 1.0f; - mat.diffuse.g = 1.0f; - mat.diffuse.b = 1.0f; // white - mat.ambient.r = 0.5f; - mat.ambient.g = 0.5f; - mat.ambient.b = 0.5f; + Gfx::Material mat; + mat.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f); // white + mat.ambient = Gfx::Color(0.5f, 0.5f, 0.5f); + + float a = 0.0f, b = 0.0f; if ( m_type == OBJECT_POWER || m_type == OBJECT_ATOMIC ) @@ -5833,35 +5828,30 @@ void CObject::UpdateEnergyMapping() a = 2.0f; b = 0.0f; // dimensions of the battery (according to y) } - if ( m_type == OBJECT_STATION ) + else if ( m_type == OBJECT_STATION ) { a = 10.0f; b = 4.0f; // dimensions of the battery (according to y) } - if ( m_type == OBJECT_ENERGY ) + else if ( m_type == OBJECT_ENERGY ) { a = 9.0f; b = 3.0f; // dimensions of the battery (according to y) } - i = 0.50f+0.25f*m_energy; // origin - s = i+0.25f; // width + float i = 0.50f+0.25f*m_energy; // origin + float s = i+0.25f; // width - au = (s-i)/(b-a); - bu = s-b*(s-i)/(b-a); + float au = (s-i)/(b-a); + float bu = s-b*(s-i)/(b-a); - limit[0] = 0.0f; - limit[1] = m_engine->GetLimitLOD(0); - limit[2] = limit[1]; - limit[3] = m_engine->GetLimitLOD(1); - limit[4] = limit[3]; - limit[5] = 1000000.0f; + Gfx::LODLevel lodLevels[3] = { Gfx::LOD_High, Gfx::LOD_Medium, Gfx::LOD_Low }; - for ( j=0 ; j<3 ; j++ ) + for (int j = 0; j < 3; j++) { m_engine->ChangeTextureMapping(m_objectPart[0].object, mat, Gfx::ENG_RSTATE_PART3, "lemt.png", "", - limit[j*2+0], limit[j*2+1], Gfx::ENG_TEX_MAPPING_1Y, + lodLevels[j], Gfx::ENG_TEX_MAPPING_1Y, au, bu, 1.0f, 0.0f); } } diff --git a/src/tools/convert_model.cpp b/src/tools/convert_model.cpp index 3eecfb1..463b83a 100644 --- a/src/tools/convert_model.cpp +++ b/src/tools/convert_model.cpp @@ -133,6 +133,18 @@ bool ParseArgs(int argc, char *argv[]) return true; } +std::ostream& operator<<(std::ostream& stream, Gfx::LODLevel lodLevel) +{ + switch (lodLevel) + { + case Gfx::LOD_Constant: stream << "constant"; break; + case Gfx::LOD_High: stream << "high"; break; + case Gfx::LOD_Medium: stream << "medium"; break; + case Gfx::LOD_Low: stream << "low"; break; + } + return stream; +} + template void PrintStats(const std::map& stats, int total) { @@ -188,25 +200,25 @@ int main(int argc, char *argv[]) { const std::vector& triangles = model.GetTriangles(); - Math::Vector min( Math::HUGE_NUM, Math::HUGE_NUM, Math::HUGE_NUM); - Math::Vector max(-Math::HUGE_NUM, -Math::HUGE_NUM, -Math::HUGE_NUM); + Math::Vector bboxMin( Math::HUGE_NUM, Math::HUGE_NUM, Math::HUGE_NUM); + Math::Vector bboxMax(-Math::HUGE_NUM, -Math::HUGE_NUM, -Math::HUGE_NUM); std::map texs1, texs2; std::map states; - std::map mins, maxs; + std::map lodLevels; int variableTexs2 = 0; for (int i = 0; i < static_cast( triangles.size() ); ++i) { const Gfx::ModelTriangle& t = triangles[i]; - min.x = Math::Min(t.p1.coord.x, t.p2.coord.x, t.p3.coord.x, min.x); - min.y = Math::Min(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, min.y); - min.z = Math::Min(t.p1.coord.z, t.p2.coord.z, t.p3.coord.z, min.z); + bboxMin.x = Math::Min(t.p1.coord.x, t.p2.coord.x, t.p3.coord.x, bboxMin.x); + bboxMin.y = Math::Min(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, bboxMin.y); + bboxMin.z = Math::Min(t.p1.coord.z, t.p2.coord.z, t.p3.coord.z, bboxMin.z); - max.x = Math::Max(t.p1.coord.x, t.p2.coord.x, t.p3.coord.x, max.x); - max.y = Math::Max(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, max.y); - max.z = Math::Max(t.p1.coord.z, t.p2.coord.z, t.p3.coord.z, max.z); + bboxMax.x = Math::Max(t.p1.coord.x, t.p2.coord.x, t.p3.coord.x, bboxMax.x); + bboxMax.y = Math::Max(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, bboxMax.y); + bboxMax.z = Math::Max(t.p1.coord.z, t.p2.coord.z, t.p3.coord.z, bboxMax.z); texs1[t.tex1Name] += 1; if (! t.tex2Name.empty()) @@ -215,16 +227,15 @@ int main(int argc, char *argv[]) variableTexs2 += 1; states[t.state] += 1; - mins[t.min] += 1; - maxs[t.max] += 1; + lodLevels[t.lodLevel] += 1; } std::cerr << "---- Info ----" << std::endl; std::cerr << "Total triangles: " << triangles.size(); std::cerr << std::endl; std::cerr << "Bounding box:" << std::endl; - std::cerr << " min: [" << min.x << ", " << min.y << ", " << min.z << "]" << std::endl; - std::cerr << " max: [" << max.x << ", " << max.y << ", " << max.z << "]" << std::endl; + std::cerr << " bboxMin: [" << bboxMin.x << ", " << bboxMin.y << ", " << bboxMin.z << "]" << std::endl; + std::cerr << " bboxMax: [" << bboxMax.x << ", " << bboxMax.y << ", " << bboxMax.z << "]" << std::endl; std::cerr << std::endl; std::cerr << "Textures:" << std::endl; std::cerr << " tex1:" << std::endl; @@ -237,10 +248,7 @@ int main(int argc, char *argv[]) PrintStats(states, triangles.size()); std::cerr << std::endl; std::cerr << "LOD:" << std::endl; - std::cerr << " min:" << std::endl; - PrintStats(mins, triangles.size()); - std::cerr << " max:" << std::endl; - PrintStats(maxs, triangles.size()); + PrintStats(lodLevels, triangles.size()); return 0; } -- cgit v1.2.3-1-g7c22