Changed model min/max to LOD levels

dev-ui
Piotr Dziwinski 2013-01-27 11:43:53 +01:00
parent 83a89fc304
commit a937a7b6ec
16 changed files with 284 additions and 377 deletions

View File

@ -37,15 +37,12 @@ How to...
Since you're running Linux, you probably know how to do this anyway ;)
But just in case, here's what you need:
gcc compiler (with gcc-g++), cmake, libraries with header files: SDL, SDL_image, SDL_ttf, libpng, boost
gcc compiler (with gcc-g++), cmake, libraries with header files: GLEW, SDL, SDL_image, SDL_ttf, libpng, boost
Instructions are the same:
$ cmake .
$ make
Note #1: If you experience problems with OpenGL's extensions, install GLEW library and enable
it in compilation by setting USE_GLEW to 1 in CMakeLists.txt
Note #2: For audio support you need libsndfile and openal.
Note #1: For audio support you need libsndfile and openal.
1.3 Other platforms, compilers, etc.
@ -104,9 +101,6 @@ Jak...
$ cmake .
$ make
Uwaga: Jeśli natrafisz na problemy z rozszerzeniami OpenGL, zainstaluj bibliotekę GLEW i włącz ją
przy kompilacji, ustawiając USE_GLEW na 1 w CMakeLists.txt
1.3 Inne platformy, kompilatory, etc.
Nie sprawdzaliśmy jeszcze innych platform, ale kod nie jest jakoś specjalnie związany z danym kompilatorem czy platformą, więc w teorii powinien zadziałać.

2
data

@ -1 +1 @@
Subproject commit 5a991a77eb5f476d29b4d4f976be48fdf74a053f
Subproject commit 5c27c5e1ebbd1398eeecbfb28abbb457442a549f

View File

@ -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<float>(pos.x) / static_cast<float>(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<int>( 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<VertexTex2>
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<int>( 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<VertexTex2>
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<int>( 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<int>( 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<int>( 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<EngineTriangle>& triangles)
{
assert(objRank >= 0 && objRank < static_cast<int>( 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<int>( 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<int>( m_baseObjects.size() ); baseObjRank++)
{
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
if (! p1.used)
continue;
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
for (int l3 = 0; l3 < static_cast<int>( 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<int>( 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<int>( 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<int>( 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<int>( 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<int>(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<int>( 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<int>( 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<int>( 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<int>( p3.next.size() ); l4++)

View File

@ -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<EngineBaseObjDataTier> 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<EngineTriangle>& 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<EngineBaseObject> 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;

View File

@ -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<std::string>(stream, "tex1", t.tex1Name) &&
ReadLineValue<std::string>(stream, "tex2", t.tex2Name) &&
ReadLineValue<char>(stream, "var_tex2", varTex2Ch) &&
ReadLineValue<float>(stream, "min", t.min) &&
ReadLineValue<float>(stream, "max", t.max) &&
ReadLineValue<int>(stream, "lod_level", t.lodLevel) &&
ReadLineValue<int>(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<ModelTriangle>& 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

View File

@ -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<ModelTriangle>& 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

View File

@ -47,30 +47,8 @@ bool CModelManager::LoadModel(const std::string& fileName, bool mirrored)
std::vector<VertexTex2> 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<int>( 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;

View File

@ -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<EngineTriangle> 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++)
{

View File

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

View File

@ -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);

View File

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

View File

@ -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);
}

View File

@ -1947,6 +1947,7 @@ void CBrain::UpdateInterface(float rTime)
if ( power == 0 )
{
energy = 0.0f;
limit = 0.0f;
}
else
{

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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<typename T>
void PrintStats(const std::map<T, int>& stats, int total)
{
@ -188,25 +200,25 @@ int main(int argc, char *argv[])
{
const std::vector<Gfx::ModelTriangle>& 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<std::string, int> texs1, texs2;
std::map<int, int> states;
std::map<float, int> mins, maxs;
std::map<Gfx::LODLevel, int> lodLevels;
int variableTexs2 = 0;
for (int i = 0; i < static_cast<int>( 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;
}