Changed model min/max to LOD levels
parent
83a89fc304
commit
a937a7b6ec
10
HOWTO.txt
10
HOWTO.txt
|
@ -37,15 +37,12 @@ How to...
|
||||||
|
|
||||||
Since you're running Linux, you probably know how to do this anyway ;)
|
Since you're running Linux, you probably know how to do this anyway ;)
|
||||||
But just in case, here's what you need:
|
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:
|
Instructions are the same:
|
||||||
$ cmake .
|
$ cmake .
|
||||||
$ make
|
$ make
|
||||||
|
|
||||||
Note #1: If you experience problems with OpenGL's extensions, install GLEW library and enable
|
Note #1: For audio support you need libsndfile and openal.
|
||||||
it in compilation by setting USE_GLEW to 1 in CMakeLists.txt
|
|
||||||
|
|
||||||
Note #2: For audio support you need libsndfile and openal.
|
|
||||||
|
|
||||||
1.3 Other platforms, compilers, etc.
|
1.3 Other platforms, compilers, etc.
|
||||||
|
|
||||||
|
@ -104,9 +101,6 @@ Jak...
|
||||||
$ cmake .
|
$ cmake .
|
||||||
$ make
|
$ 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.
|
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ć.
|
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
2
data
|
@ -1 +1 @@
|
||||||
Subproject commit 5a991a77eb5f476d29b4d4f976be48fdf74a053f
|
Subproject commit 5c27c5e1ebbd1398eeecbfb28abbb457442a549f
|
|
@ -109,13 +109,9 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
|
||||||
m_lookatPt = Math::Vector(0.0f, 0.0f, 1.0f);
|
m_lookatPt = Math::Vector(0.0f, 0.0f, 1.0f);
|
||||||
m_drawWorld = true;
|
m_drawWorld = true;
|
||||||
m_drawFront = false;
|
m_drawFront = false;
|
||||||
m_limitLOD[0] = 100.0f;
|
|
||||||
m_limitLOD[1] = 200.0f;
|
|
||||||
m_particleDensity = 1.0f;
|
m_particleDensity = 1.0f;
|
||||||
m_clippingDistance = 1.0f;
|
|
||||||
m_lastClippingDistance = m_clippingDistance = 1.0f;
|
m_lastClippingDistance = m_clippingDistance = 1.0f;
|
||||||
m_objectDetail = 1.0f;
|
m_objectDetail = 1.0f;
|
||||||
m_lastObjectDetail = m_objectDetail;
|
|
||||||
m_terrainVision = 1000.0f;
|
m_terrainVision = 1000.0f;
|
||||||
m_gadgetQuantity = 1.0f;
|
m_gadgetQuantity = 1.0f;
|
||||||
m_textureQuality = 1;
|
m_textureQuality = 1;
|
||||||
|
@ -130,7 +126,6 @@ CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
|
||||||
m_editIndentValue = 4;
|
m_editIndentValue = 4;
|
||||||
m_tracePrecision = 1.0f;
|
m_tracePrecision = 1.0f;
|
||||||
|
|
||||||
m_alphaMode = 1;
|
|
||||||
|
|
||||||
m_updateGeometry = false;
|
m_updateGeometry = false;
|
||||||
m_updateStaticBuffers = false;
|
m_updateStaticBuffers = false;
|
||||||
|
@ -208,7 +203,7 @@ CText* CEngine::GetText()
|
||||||
|
|
||||||
bool CEngine::Create()
|
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_lightMan = new CLightManager(m_iMan, this);
|
||||||
m_text = new CText(m_iMan, this);
|
m_text = new CText(m_iMan, this);
|
||||||
|
@ -416,11 +411,6 @@ Math::IntPoint CEngine::GetWindowSize()
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Math::IntPoint CEngine::GetLastWindowSize()
|
|
||||||
{
|
|
||||||
return m_lastSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
Math::Point CEngine::WindowToInterfaceCoords(Math::IntPoint pos)
|
Math::Point CEngine::WindowToInterfaceCoords(Math::IntPoint pos)
|
||||||
{
|
{
|
||||||
return Math::Point( static_cast<float>(pos.x) / static_cast<float>(m_size.x),
|
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();
|
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++)
|
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];
|
return p2.next[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
p2.next.push_back(EngineBaseObjLODTier(min, max));
|
p2.next.push_back(EngineBaseObjLODTier(lodLevel));
|
||||||
return p2.next.back();
|
return p2.next.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,17 +560,13 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector<VertexTex2>
|
||||||
EngineTriangleType triangleType,
|
EngineTriangleType triangleType,
|
||||||
const Material& material, int state,
|
const Material& material, int state,
|
||||||
std::string tex1Name, std::string tex2Name,
|
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() ));
|
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];
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
||||||
EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
|
EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
|
||||||
EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max);
|
EngineBaseObjLODTier& p3 = AddLevel3(p2, lodLevel);
|
||||||
EngineBaseObjDataTier& p4 = AddLevel4(p3, triangleType, material, state);
|
EngineBaseObjDataTier& p4 = AddLevel4(p3, triangleType, material, state);
|
||||||
|
|
||||||
p4.vertices.insert(p4.vertices.end(), vertices.begin(), vertices.end());
|
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,
|
void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer,
|
||||||
std::string tex1Name, std::string tex2Name,
|
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() ));
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
||||||
|
|
||||||
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
||||||
EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
|
EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
|
||||||
EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max);
|
EngineBaseObjLODTier& p3 = AddLevel3(p2, lodLevel);
|
||||||
|
|
||||||
p3.next.push_back(buffer);
|
p3.next.push_back(buffer);
|
||||||
|
|
||||||
|
@ -797,7 +783,7 @@ int CEngine::GetObjectTotalTriangles(int objRank)
|
||||||
|
|
||||||
EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& material,
|
EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& material,
|
||||||
int state, std::string tex1Name,
|
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() ));
|
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];
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
||||||
|
|
||||||
if (p3.min != min || p3.max != max)
|
if ((p3.lodLevel & lodLevelMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
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;
|
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)
|
std::vector<EngineTriangle>& triangles)
|
||||||
{
|
{
|
||||||
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
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];
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
||||||
|
|
||||||
if (p3.min != min || p3.max != max)
|
if ((p3.lodLevel & lodLevelMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
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;
|
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)
|
void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name)
|
||||||
{
|
{
|
||||||
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
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,
|
void CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state,
|
||||||
const std::string& tex1Name, const std::string& tex2Name,
|
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)
|
float au, float bu, float av, float bv)
|
||||||
{
|
{
|
||||||
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
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)
|
if (p4 == nullptr)
|
||||||
return;
|
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,
|
void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state,
|
||||||
const std::string& tex1Name, const std::string& tex2Name,
|
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)
|
float pos, float factor, float tl, float ts, float tt)
|
||||||
{
|
{
|
||||||
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
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)
|
if (p4 == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1707,8 +1631,8 @@ int CEngine::DetectObject(Math::Point mouse)
|
||||||
{
|
{
|
||||||
EngineBaseObjLODTier& p3 = p2.next[l3];
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
||||||
|
|
||||||
if (p3.min != 0.0f)
|
if (p3.lodLevel != LOD_Constant && p3.lodLevel != LOD_High)
|
||||||
continue; // LOD B or C?
|
continue;
|
||||||
|
|
||||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
||||||
{
|
{
|
||||||
|
@ -1820,6 +1744,43 @@ bool CEngine::IsVisible(int objRank)
|
||||||
return false;
|
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)
|
bool CEngine::TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D)
|
||||||
{
|
{
|
||||||
assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
|
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_lastState = state;
|
||||||
m_lastColor = color;
|
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?
|
if (state & ENG_RSTATE_TTEXTURE_BLACK) // transparent black texture?
|
||||||
{
|
{
|
||||||
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
||||||
|
@ -2447,33 +2399,6 @@ void CEngine::SetTexture(const Texture& tex, int stage)
|
||||||
m_device->SetTexture(stage, tex);
|
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)
|
void CEngine::SetTerrainVision(float vision)
|
||||||
{
|
{
|
||||||
m_terrainVision = vision;
|
m_terrainVision = vision;
|
||||||
|
@ -2709,6 +2634,7 @@ void CEngine::SetClippingDistance(float value)
|
||||||
{
|
{
|
||||||
if (value < 0.5f) value = 0.5f;
|
if (value < 0.5f) value = 0.5f;
|
||||||
if (value > 2.0f) value = 2.0f;
|
if (value > 2.0f) value = 2.0f;
|
||||||
|
m_lastClippingDistance = m_clippingDistance;
|
||||||
m_clippingDistance = value;
|
m_clippingDistance = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2920,7 +2846,6 @@ void CEngine::ApplyChange()
|
||||||
m_deepView[1] /= m_lastClippingDistance;
|
m_deepView[1] /= m_lastClippingDistance;
|
||||||
|
|
||||||
SetFocus(m_focus);
|
SetFocus(m_focus);
|
||||||
ChangeLOD();
|
|
||||||
|
|
||||||
m_deepView[0] *= m_clippingDistance;
|
m_deepView[0] *= m_clippingDistance;
|
||||||
m_deepView[1] *= m_clippingDistance;
|
m_deepView[1] *= m_clippingDistance;
|
||||||
|
@ -3040,8 +2965,7 @@ void CEngine::Draw3DScene()
|
||||||
{
|
{
|
||||||
EngineBaseObjLODTier& p3 = p2.next[l3];
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
||||||
|
|
||||||
if ( m_objects[objRank].distance < p3.min ||
|
if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
||||||
m_objects[objRank].distance >= p3.max )
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
||||||
|
@ -3108,8 +3032,7 @@ void CEngine::Draw3DScene()
|
||||||
{
|
{
|
||||||
EngineBaseObjLODTier& p3 = p2.next[l3];
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
||||||
|
|
||||||
if ( m_objects[objRank].distance < p3.min ||
|
if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
||||||
m_objects[objRank].distance >= p3.max )
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
||||||
|
@ -3177,8 +3100,7 @@ void CEngine::Draw3DScene()
|
||||||
{
|
{
|
||||||
EngineBaseObjLODTier& p3 = p2.next[l3];
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
||||||
|
|
||||||
if (m_objects[objRank].distance < p3.min ||
|
if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
||||||
m_objects[objRank].distance >= p3.max)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
||||||
|
@ -3330,8 +3252,7 @@ void CEngine::DrawInterface()
|
||||||
{
|
{
|
||||||
EngineBaseObjLODTier& p3 = p2.next[l3];
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
||||||
|
|
||||||
if (m_objects[objRank].distance < p3.min ||
|
if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
||||||
m_objects[objRank].distance >= p3.max)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include "graphics/core/texture.h"
|
#include "graphics/core/texture.h"
|
||||||
#include "graphics/core/vertex.h"
|
#include "graphics/core/vertex.h"
|
||||||
|
|
||||||
|
#include "graphics/engine/modelfile.h"
|
||||||
|
|
||||||
#include "math/intpoint.h"
|
#include "math/intpoint.h"
|
||||||
#include "math/matrix.h"
|
#include "math/matrix.h"
|
||||||
#include "math/point.h"
|
#include "math/point.h"
|
||||||
|
@ -204,12 +206,11 @@ struct EngineBaseObjDataTier
|
||||||
*/
|
*/
|
||||||
struct EngineBaseObjLODTier
|
struct EngineBaseObjLODTier
|
||||||
{
|
{
|
||||||
float min;
|
LODLevel lodLevel;
|
||||||
float max;
|
|
||||||
std::vector<EngineBaseObjDataTier> next;
|
std::vector<EngineBaseObjDataTier> next;
|
||||||
|
|
||||||
inline EngineBaseObjLODTier(float min = 0.0f, float max = 0.0f)
|
inline EngineBaseObjLODTier(LODLevel lodLevel = LOD_Constant)
|
||||||
: min(min), max(max) {}
|
: lodLevel(lodLevel) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -777,12 +778,12 @@ public:
|
||||||
EngineTriangleType triangleType,
|
EngineTriangleType triangleType,
|
||||||
const Material& material, int state,
|
const Material& material, int state,
|
||||||
std::string tex1Name, std::string tex2Name,
|
std::string tex1Name, std::string tex2Name,
|
||||||
float min, float max, bool globalUpdate);
|
LODLevel lodLevel, bool globalUpdate);
|
||||||
|
|
||||||
//! Adds a tier 4 engine object directly
|
//! Adds a tier 4 engine object directly
|
||||||
void AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer,
|
void AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer,
|
||||||
std::string tex1Name, std::string tex2Name,
|
std::string tex1Name, std::string tex2Name,
|
||||||
float min, float max, bool globalUpdate);
|
LODLevel lodLevel, bool globalUpdate);
|
||||||
|
|
||||||
// Objects
|
// Objects
|
||||||
|
|
||||||
|
@ -827,29 +828,26 @@ public:
|
||||||
|
|
||||||
//! Returns the first found tier 4 engine object for the given params or nullptr if not found
|
//! Returns the first found tier 4 engine object for the given params or nullptr if not found
|
||||||
EngineBaseObjDataTier* FindTriangles(int objRank, const Material& material,
|
EngineBaseObjDataTier* FindTriangles(int objRank, const Material& material,
|
||||||
int state, std::string tex1Name, std::string tex2Name,
|
int state, std::string tex1Name, std::string tex2Name,
|
||||||
float min, float max);
|
int lodLevelMask);
|
||||||
|
|
||||||
//! Returns a partial list of triangles for given object
|
//! 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);
|
std::vector<EngineTriangle>& triangles);
|
||||||
|
|
||||||
//! Updates LOD after parameter or resolution change
|
|
||||||
void ChangeLOD();
|
|
||||||
|
|
||||||
//! Changes the 2nd texure for given object
|
//! Changes the 2nd texure for given object
|
||||||
void ChangeSecondTexture(int objRank, const std::string& tex2Name);
|
void ChangeSecondTexture(int objRank, const std::string& tex2Name);
|
||||||
|
|
||||||
//! Changes (recalculates) texture mapping for given object
|
//! Changes (recalculates) texture mapping for given object
|
||||||
void ChangeTextureMapping(int objRank, const Material& mat, int state,
|
void ChangeTextureMapping(int objRank, const Material& mat, int state,
|
||||||
const std::string& tex1Name, const std::string& tex2Name,
|
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);
|
float au, float bu, float av, float bv);
|
||||||
|
|
||||||
//! Changes texture mapping for robot tracks
|
//! Changes texture mapping for robot tracks
|
||||||
void TrackTextureMapping(int objRank, const Material& mat, int state,
|
void TrackTextureMapping(int objRank, const Material& mat, int state,
|
||||||
const std::string& tex1Name, const std::string& tex2Name,
|
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);
|
float pos, float factor, float tl, float ts, float tt);
|
||||||
|
|
||||||
//! Detects the target object that is selected with the mouse
|
//! 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
|
//! Deletes the given texture, unloading it and removing from cache
|
||||||
void DeleteTexture(const Texture& tex);
|
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
|
//! Defines of the distance field of vision
|
||||||
void SetTerrainVision(float vision);
|
void SetTerrainVision(float vision);
|
||||||
|
|
||||||
|
@ -1219,7 +1211,7 @@ protected:
|
||||||
//! Creates a new tier 2 object (texture)
|
//! Creates a new tier 2 object (texture)
|
||||||
EngineBaseObjTexTier& AddLevel2(EngineBaseObject& p1, const std::string& tex1Name, const std::string& tex2Name);
|
EngineBaseObjTexTier& AddLevel2(EngineBaseObject& p1, const std::string& tex1Name, const std::string& tex2Name);
|
||||||
//! Creates a new tier 3 object (LOD)
|
//! 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)
|
//! Creates a new tier 4 object (data)
|
||||||
EngineBaseObjDataTier& AddLevel4(EngineBaseObjLODTier &p3, EngineTriangleType type,
|
EngineBaseObjDataTier& AddLevel4(EngineBaseObjLODTier &p3, EngineTriangleType type,
|
||||||
const Material& mat, int state);
|
const Material& mat, int state);
|
||||||
|
@ -1230,6 +1222,9 @@ protected:
|
||||||
//! Tests whether the given object is visible
|
//! Tests whether the given object is visible
|
||||||
bool IsVisible(int objRank);
|
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
|
//! Detects whether an object is affected by the mouse
|
||||||
bool DetectBBox(int objRank, Math::Point mouse);
|
bool DetectBBox(int objRank, Math::Point mouse);
|
||||||
|
|
||||||
|
@ -1304,8 +1299,6 @@ protected:
|
||||||
|
|
||||||
//! Current size of viewport window
|
//! Current size of viewport window
|
||||||
Math::IntPoint m_size;
|
Math::IntPoint m_size;
|
||||||
//! Previous size of viewport window
|
|
||||||
Math::IntPoint m_lastSize;
|
|
||||||
|
|
||||||
//! Base objects (also level 1 tier list)
|
//! Base objects (also level 1 tier list)
|
||||||
std::vector<EngineBaseObject> m_baseObjects;
|
std::vector<EngineBaseObject> m_baseObjects;
|
||||||
|
@ -1356,12 +1349,10 @@ protected:
|
||||||
Texture m_foregroundTex;
|
Texture m_foregroundTex;
|
||||||
bool m_drawWorld;
|
bool m_drawWorld;
|
||||||
bool m_drawFront;
|
bool m_drawFront;
|
||||||
float m_limitLOD[2];
|
|
||||||
float m_particleDensity;
|
float m_particleDensity;
|
||||||
float m_clippingDistance;
|
float m_clippingDistance;
|
||||||
float m_lastClippingDistance;
|
float m_lastClippingDistance;
|
||||||
float m_objectDetail;
|
float m_objectDetail;
|
||||||
float m_lastObjectDetail;
|
|
||||||
float m_terrainVision;
|
float m_terrainVision;
|
||||||
float m_gadgetQuantity;
|
float m_gadgetQuantity;
|
||||||
int m_textureQuality;
|
int m_textureQuality;
|
||||||
|
|
|
@ -495,8 +495,7 @@ bool CModelFile::ReadModel(std::istream& stream)
|
||||||
|
|
||||||
triangle.material = t.material;
|
triangle.material = t.material;
|
||||||
triangle.tex1Name = std::string(t.texName);
|
triangle.tex1Name = std::string(t.texName);
|
||||||
triangle.min = t.min;
|
triangle.lodLevel = MinMaxToLodLevel(t.min, t.max);
|
||||||
triangle.max = t.max;
|
|
||||||
|
|
||||||
m_triangles.push_back(triangle);
|
m_triangles.push_back(triangle);
|
||||||
}
|
}
|
||||||
|
@ -539,8 +538,7 @@ bool CModelFile::ReadModel(std::istream& stream)
|
||||||
|
|
||||||
triangle.material = t.material;
|
triangle.material = t.material;
|
||||||
triangle.tex1Name = std::string(t.texName);
|
triangle.tex1Name = std::string(t.texName);
|
||||||
triangle.min = t.min;
|
triangle.lodLevel = MinMaxToLodLevel(t.min, t.max);
|
||||||
triangle.max = t.max;
|
|
||||||
triangle.state = t.state;
|
triangle.state = t.state;
|
||||||
|
|
||||||
m_triangles.push_back(triangle);
|
m_triangles.push_back(triangle);
|
||||||
|
@ -584,8 +582,7 @@ bool CModelFile::ReadModel(std::istream& stream)
|
||||||
|
|
||||||
triangle.material = t.material;
|
triangle.material = t.material;
|
||||||
triangle.tex1Name = std::string(t.texName);
|
triangle.tex1Name = std::string(t.texName);
|
||||||
triangle.min = t.min;
|
triangle.lodLevel = MinMaxToLodLevel(t.min, t.max);
|
||||||
triangle.max = t.max;
|
|
||||||
triangle.state = t.state;
|
triangle.state = t.state;
|
||||||
triangle.variableTex2 = t.texNum2 == 1;
|
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(),
|
GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(),
|
||||||
m_triangles[i].variableTex2 ? "(variable)" : m_triangles[i].tex2Name.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);
|
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;
|
t.material = m_triangles[i].material;
|
||||||
strncpy(t.texName, m_triangles[i].tex1Name.c_str(), 20);
|
strncpy(t.texName, m_triangles[i].tex1Name.c_str(), 20);
|
||||||
t.min = m_triangles[i].min;
|
LODLevelToMinMax(m_triangles[i].lodLevel, t.min, t.max);
|
||||||
t.max = m_triangles[i].max;
|
|
||||||
t.state = m_triangles[i].state;
|
t.state = m_triangles[i].state;
|
||||||
|
|
||||||
int no = 0;
|
int no = 0;
|
||||||
|
@ -722,6 +718,46 @@ bool CModelFile::WriteModel(std::ostream& stream)
|
||||||
return true;
|
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
|
New formats
|
||||||
|
@ -768,17 +804,15 @@ struct NewModelTriangle1
|
||||||
std::string tex2Name;
|
std::string tex2Name;
|
||||||
//! If true, 2nd texture will be taken from current engine setting
|
//! If true, 2nd texture will be taken from current engine setting
|
||||||
bool variableTex2;
|
bool variableTex2;
|
||||||
//! Min LOD threshold
|
//! LOD level
|
||||||
float min;
|
int lodLevel;
|
||||||
//! Max LOD threshold
|
|
||||||
float max;
|
|
||||||
//! Rendering state to be set
|
//! Rendering state to be set
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
NewModelTriangle1()
|
NewModelTriangle1()
|
||||||
{
|
{
|
||||||
variableTex2 = true;
|
variableTex2 = true;
|
||||||
min = max = 0.0f;
|
lodLevel = 0;
|
||||||
state = 0;
|
state = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -834,8 +868,7 @@ bool CModelFile::ReadTextModel(std::istream& stream)
|
||||||
ReadLineValue<std::string>(stream, "tex1", t.tex1Name) &&
|
ReadLineValue<std::string>(stream, "tex1", t.tex1Name) &&
|
||||||
ReadLineValue<std::string>(stream, "tex2", t.tex2Name) &&
|
ReadLineValue<std::string>(stream, "tex2", t.tex2Name) &&
|
||||||
ReadLineValue<char>(stream, "var_tex2", varTex2Ch) &&
|
ReadLineValue<char>(stream, "var_tex2", varTex2Ch) &&
|
||||||
ReadLineValue<float>(stream, "min", t.min) &&
|
ReadLineValue<int>(stream, "lod_level", t.lodLevel) &&
|
||||||
ReadLineValue<float>(stream, "max", t.max) &&
|
|
||||||
ReadLineValue<int>(stream, "state", t.state);
|
ReadLineValue<int>(stream, "state", t.state);
|
||||||
|
|
||||||
if (!triOk || stream.fail())
|
if (!triOk || stream.fail())
|
||||||
|
@ -855,10 +888,17 @@ bool CModelFile::ReadTextModel(std::istream& stream)
|
||||||
triangle.tex1Name = t.tex1Name;
|
triangle.tex1Name = t.tex1Name;
|
||||||
triangle.tex2Name = t.tex2Name;
|
triangle.tex2Name = t.tex2Name;
|
||||||
triangle.variableTex2 = t.variableTex2;
|
triangle.variableTex2 = t.variableTex2;
|
||||||
triangle.min = t.min;
|
|
||||||
triangle.max = t.max;
|
|
||||||
triangle.state = t.state;
|
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);
|
m_triangles.push_back(triangle);
|
||||||
|
|
||||||
continue;
|
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(" 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(" 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);
|
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.tex1Name = m_triangles[i].tex1Name;
|
||||||
t.tex2Name = m_triangles[i].tex2Name;
|
t.tex2Name = m_triangles[i].tex2Name;
|
||||||
t.variableTex2 = m_triangles[i].variableTex2;
|
t.variableTex2 = m_triangles[i].variableTex2;
|
||||||
t.min = m_triangles[i].min;
|
|
||||||
t.max = m_triangles[i].max;
|
|
||||||
t.state = m_triangles[i].state;
|
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 ";
|
stream << "p1 ";
|
||||||
WriteTextVertexTex2(t.p1, stream);
|
WriteTextVertexTex2(t.p1, stream);
|
||||||
stream << "p2 ";
|
stream << "p2 ";
|
||||||
|
@ -954,8 +1000,7 @@ bool CModelFile::WriteTextModel(std::ostream& stream)
|
||||||
stream << "tex1 " << t.tex1Name << std::endl;
|
stream << "tex1 " << t.tex1Name << std::endl;
|
||||||
stream << "tex2 " << t.tex2Name << std::endl;
|
stream << "tex2 " << t.tex2Name << std::endl;
|
||||||
stream << "var_tex2 " << (t.variableTex2 ? 'Y' : 'N') << std::endl;
|
stream << "var_tex2 " << (t.variableTex2 ? 'Y' : 'N') << std::endl;
|
||||||
stream << "min " << t.min << std::endl;
|
stream << "lod_level " << t.lodLevel << std::endl;
|
||||||
stream << "max " << t.max << std::endl;
|
|
||||||
stream << "state " << t.state << std::endl;
|
stream << "state " << t.state << std::endl;
|
||||||
|
|
||||||
stream << std::endl;
|
stream << std::endl;
|
||||||
|
@ -1012,9 +1057,8 @@ bool CModelFile::ReadBinaryModel(std::istream& stream)
|
||||||
t.tex1Name = IOUtils::ReadBinaryString<1>(stream);
|
t.tex1Name = IOUtils::ReadBinaryString<1>(stream);
|
||||||
t.tex2Name = IOUtils::ReadBinaryString<1>(stream);
|
t.tex2Name = IOUtils::ReadBinaryString<1>(stream);
|
||||||
t.variableTex2 = IOUtils::ReadBinaryBool(stream);
|
t.variableTex2 = IOUtils::ReadBinaryBool(stream);
|
||||||
t.min = IOUtils::ReadBinaryFloat(stream);
|
t.lodLevel = IOUtils::ReadBinary<4, int>(stream);
|
||||||
t.max = IOUtils::ReadBinaryFloat(stream);
|
t.state = IOUtils::ReadBinary<4, int>(stream);
|
||||||
t.state = IOUtils::ReadBinary<4, unsigned int>(stream);
|
|
||||||
|
|
||||||
if (stream.fail())
|
if (stream.fail())
|
||||||
{
|
{
|
||||||
|
@ -1030,10 +1074,17 @@ bool CModelFile::ReadBinaryModel(std::istream& stream)
|
||||||
triangle.tex1Name = t.tex1Name;
|
triangle.tex1Name = t.tex1Name;
|
||||||
triangle.tex2Name = t.tex2Name;
|
triangle.tex2Name = t.tex2Name;
|
||||||
triangle.variableTex2 = t.variableTex2;
|
triangle.variableTex2 = t.variableTex2;
|
||||||
triangle.min = t.min;
|
|
||||||
triangle.max = t.max;
|
|
||||||
triangle.state = t.state;
|
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);
|
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(" 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(" 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);
|
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.tex1Name = m_triangles[i].tex1Name;
|
||||||
t.tex2Name = m_triangles[i].tex2Name;
|
t.tex2Name = m_triangles[i].tex2Name;
|
||||||
t.variableTex2 = m_triangles[i].variableTex2;
|
t.variableTex2 = m_triangles[i].variableTex2;
|
||||||
t.min = m_triangles[i].min;
|
|
||||||
t.max = m_triangles[i].max;
|
|
||||||
t.state = m_triangles[i].state;
|
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.p1, stream);
|
||||||
WriteBinaryVertexTex2(t.p2, stream);
|
WriteBinaryVertexTex2(t.p2, stream);
|
||||||
WriteBinaryVertexTex2(t.p3, 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.tex1Name, stream);
|
||||||
IOUtils::WriteBinaryString<1>(t.tex2Name, stream);
|
IOUtils::WriteBinaryString<1>(t.tex2Name, stream);
|
||||||
IOUtils::WriteBinaryBool(t.variableTex2, stream);
|
IOUtils::WriteBinaryBool(t.variableTex2, stream);
|
||||||
IOUtils::WriteBinaryFloat(t.min, stream);
|
IOUtils::WriteBinary<4, int>(t.lodLevel, stream);
|
||||||
IOUtils::WriteBinaryFloat(t.max, stream);
|
IOUtils::WriteBinary<4, int>(t.state, stream);
|
||||||
IOUtils::WriteBinary<4, unsigned int>(t.state, stream);
|
|
||||||
|
|
||||||
if (stream.fail())
|
if (stream.fail())
|
||||||
{
|
{
|
||||||
|
@ -1132,10 +1188,6 @@ bool CModelFile::WriteBinaryModel(std::ostream& stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************
|
|
||||||
Other stuff
|
|
||||||
*******************************************************/
|
|
||||||
|
|
||||||
const std::vector<ModelTriangle>& CModelFile::GetTriangles()
|
const std::vector<ModelTriangle>& CModelFile::GetTriangles()
|
||||||
{
|
{
|
||||||
return m_triangles;
|
return m_triangles;
|
||||||
|
@ -1146,23 +1198,5 @@ int CModelFile::GetTriangleCount()
|
||||||
return m_triangles.size();
|
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
|
} // namespace Gfx
|
||||||
|
|
|
@ -39,9 +39,23 @@ namespace Gfx {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\struct ModelTriangle
|
* \enum LODLevel
|
||||||
\brief Triangle of a 3D model
|
* \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
|
struct ModelTriangle
|
||||||
{
|
{
|
||||||
//! 1st vertex
|
//! 1st vertex
|
||||||
|
@ -58,17 +72,15 @@ struct ModelTriangle
|
||||||
std::string tex2Name;
|
std::string tex2Name;
|
||||||
//! If true, 2nd texture will be taken from current engine setting
|
//! If true, 2nd texture will be taken from current engine setting
|
||||||
bool variableTex2;
|
bool variableTex2;
|
||||||
//! Min LOD threshold
|
//! LOD level
|
||||||
float min;
|
LODLevel lodLevel;
|
||||||
//! Max LOD threshold
|
|
||||||
float max;
|
|
||||||
//! Rendering state to be set
|
//! Rendering state to be set
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
ModelTriangle()
|
ModelTriangle()
|
||||||
{
|
{
|
||||||
variableTex2 = true;
|
variableTex2 = true;
|
||||||
min = max = 0.0f;
|
lodLevel = LOD_Constant;
|
||||||
state = 0;
|
state = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -126,8 +138,11 @@ public:
|
||||||
const std::vector<ModelTriangle>& GetTriangles();
|
const std::vector<ModelTriangle>& GetTriangles();
|
||||||
|
|
||||||
protected:
|
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:
|
protected:
|
||||||
//! Model triangles
|
//! Model triangles
|
||||||
|
|
|
@ -47,30 +47,8 @@ bool CModelManager::LoadModel(const std::string& fileName, bool mirrored)
|
||||||
|
|
||||||
std::vector<VertexTex2> vs(3, VertexTex2());
|
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++)
|
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;
|
int state = modelInfo.triangles[i].state;
|
||||||
std::string tex2Name = modelInfo.triangles[i].tex2Name;
|
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,
|
m_engine->AddBaseObjTriangles(modelInfo.baseObjRank, vs, ENG_TRIANGLE_TYPE_TRIANGLES,
|
||||||
modelInfo.triangles[i].material, state,
|
modelInfo.triangles[i].material, state,
|
||||||
modelInfo.triangles[i].tex1Name, tex2Name,
|
modelInfo.triangles[i].tex1Name, tex2Name,
|
||||||
min, max, false);
|
modelInfo.triangles[i].lodLevel, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1397,27 +1397,39 @@ void CPyro::CreateTriangle(CObject* obj, ObjectType oType, int part)
|
||||||
int objRank = obj->GetObjectRank(part);
|
int objRank = obj->GetObjectRank(part);
|
||||||
if (objRank == -1) return;
|
if (objRank == -1) return;
|
||||||
|
|
||||||
float min = 0.0f;
|
|
||||||
float max = m_engine->GetLimitLOD(0);
|
|
||||||
int total = m_engine->GetObjectTotalTriangles(objRank);
|
int total = m_engine->GetObjectTotalTriangles(objRank);
|
||||||
|
|
||||||
float percent = 0.10f;
|
float percent = 0.10f;
|
||||||
if (total < 50) percent = 0.25f;
|
if (total < 50) percent = 0.25f;
|
||||||
if (total < 20) percent = 0.50f;
|
if (total < 20) percent = 0.50f;
|
||||||
if (m_type == PT_EGG) percent = 0.30f;
|
if (m_type == PT_EGG) percent = 0.30f;
|
||||||
|
|
||||||
if ( oType == OBJECT_POWER ||
|
if (oType == OBJECT_POWER ||
|
||||||
oType == OBJECT_ATOMIC ||
|
oType == OBJECT_ATOMIC ||
|
||||||
oType == OBJECT_URANIUM ||
|
oType == OBJECT_URANIUM ||
|
||||||
oType == OBJECT_TNT ||
|
oType == OBJECT_TNT ||
|
||||||
oType == OBJECT_BOMB ) percent = 0.75f;
|
oType == OBJECT_BOMB ||
|
||||||
if ( oType == OBJECT_MOBILEtg ) percent = 0.50f;
|
oType == OBJECT_TEEN28)
|
||||||
if ( oType == OBJECT_TEEN28 ) percent = 0.75f;
|
{
|
||||||
if ( oType == OBJECT_MOTHER ) max = 1000000.0f;
|
percent = 0.75f;
|
||||||
if ( oType == OBJECT_TEEN28 ) max = 1000000.0f;
|
}
|
||||||
if ( oType == OBJECT_TEEN31 ) max = 1000000.0f;
|
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;
|
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++)
|
for (int i = 0; i < total; i++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -487,8 +487,7 @@ VertexTex2 CTerrain::GetVertex(int x, int y, int step)
|
||||||
+-------------------> x
|
+-------------------> x
|
||||||
\endverbatim */
|
\endverbatim */
|
||||||
bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
|
bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
|
||||||
const Material &mat,
|
const Material &mat)
|
||||||
float min, float max)
|
|
||||||
{
|
{
|
||||||
int baseObjRank = m_engine->GetObjectBaseRank(objRank);
|
int baseObjRank = m_engine->GetObjectBaseRank(objRank);
|
||||||
if (baseObjRank == -1)
|
if (baseObjRank == -1)
|
||||||
|
@ -640,7 +639,7 @@ bool CTerrain::CreateMosaic(int ox, int oy, int step, int objRank,
|
||||||
buffer.vertices.push_back(p2);
|
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;
|
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++)
|
for (int step = 0; step < m_depth; step++)
|
||||||
{
|
{
|
||||||
CreateMosaic(x, y, 1 << step, objRank, mat, min, max);
|
CreateMosaic(x, y, 1 << step, objRank, mat);
|
||||||
min = max;
|
|
||||||
max *= 2;
|
|
||||||
if (step == m_depth-1) max = Math::HUGE_NUM;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -330,7 +330,7 @@ protected:
|
||||||
//! Calculates a vertex of the terrain
|
//! Calculates a vertex of the terrain
|
||||||
VertexTex2 GetVertex(int x, int y, int step);
|
VertexTex2 GetVertex(int x, int y, int step);
|
||||||
//! Creates all objects of a mosaic
|
//! 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
|
//! Creates all objects in a mesh square ground
|
||||||
bool CreateSquare(int x, int y);
|
bool CreateSquare(int x, int y);
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,7 @@ const char* const TEXT_MODEL =
|
||||||
"tex1 lemt.png\n"
|
"tex1 lemt.png\n"
|
||||||
"tex2\n"
|
"tex2\n"
|
||||||
"var_tex2 N\n"
|
"var_tex2 N\n"
|
||||||
"min 200\n"
|
"lod_level 0\n"
|
||||||
"max 1e+06\n"
|
|
||||||
"state 1024\n"
|
"state 1024\n"
|
||||||
"\n"
|
"\n"
|
||||||
"p1 c -19 -1 4 n -1 0 0 t1 0.248047 0.123047 t2 0.905224 0.52067\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"
|
"tex1 derrick.png\n"
|
||||||
"tex2\n"
|
"tex2\n"
|
||||||
"var_tex2 Y\n"
|
"var_tex2 Y\n"
|
||||||
"min 200\n"
|
"lod_level 1\n"
|
||||||
"max 1e+06\n"
|
|
||||||
"state 0\n"
|
"state 0\n"
|
||||||
"";
|
"";
|
||||||
|
|
||||||
|
@ -81,8 +79,7 @@ void Init()
|
||||||
TRIANGLE_1.material.specular = Gfx::Color(0, 0, 0, 0);
|
TRIANGLE_1.material.specular = Gfx::Color(0, 0, 0, 0);
|
||||||
TRIANGLE_1.tex1Name = "lemt.png";
|
TRIANGLE_1.tex1Name = "lemt.png";
|
||||||
TRIANGLE_1.variableTex2 = false;
|
TRIANGLE_1.variableTex2 = false;
|
||||||
TRIANGLE_1.min = 200.0f;
|
TRIANGLE_1.lodLevel = Gfx::LOD_Constant;
|
||||||
TRIANGLE_1.max = 1e+06f;
|
|
||||||
TRIANGLE_1.state = 1024;
|
TRIANGLE_1.state = 1024;
|
||||||
|
|
||||||
TRIANGLE_2.p1 = Gfx::VertexTex2(Math::Vector(-19, -1, 4),
|
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.material.specular = Gfx::Color(0, 0, 0, 0);
|
||||||
TRIANGLE_2.tex1Name = "derrick.png";
|
TRIANGLE_2.tex1Name = "derrick.png";
|
||||||
TRIANGLE_2.variableTex2 = true;
|
TRIANGLE_2.variableTex2 = true;
|
||||||
TRIANGLE_2.min = 200.0f;
|
TRIANGLE_2.lodLevel = Gfx::LOD_Low;
|
||||||
TRIANGLE_2.max = 1e+06f;
|
|
||||||
TRIANGLE_2.state = 0;
|
TRIANGLE_2.state = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,10 +167,7 @@ bool CompareTriangles(const Gfx::ModelTriangle& t1, const Gfx::ModelTriangle& t2
|
||||||
if (t1.variableTex2 != t2.variableTex2)
|
if (t1.variableTex2 != t2.variableTex2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!Math::IsEqual(t1.min, t2.min))
|
if (t1.lodLevel != t2.lodLevel)
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!Math::IsEqual(t1.max, t2.max))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (t1.state != t2.state)
|
if (t1.state != t2.state)
|
||||||
|
|
|
@ -398,7 +398,6 @@ Error CAutoPortico::GetError()
|
||||||
void CAutoPortico::UpdateTrackMapping(float left, float right)
|
void CAutoPortico::UpdateTrackMapping(float left, float right)
|
||||||
{
|
{
|
||||||
Gfx::Material mat;
|
Gfx::Material mat;
|
||||||
float limit[2];
|
|
||||||
int rank;
|
int rank;
|
||||||
|
|
||||||
memset( &mat, 0, sizeof(Gfx::Material));
|
memset( &mat, 0, sizeof(Gfx::Material));
|
||||||
|
@ -411,15 +410,12 @@ void CAutoPortico::UpdateTrackMapping(float left, float right)
|
||||||
|
|
||||||
rank = m_object->GetObjectRank(0);
|
rank = m_object->GetObjectRank(0);
|
||||||
|
|
||||||
limit[0] = 0.0f;
|
|
||||||
limit[1] = 1000000.0f;
|
|
||||||
|
|
||||||
m_engine->TrackTextureMapping(rank, mat, Gfx::ENG_RSTATE_PART1, "lemt.png", "",
|
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);
|
right, 8.0f, 8.0f, 192.0f, 256.0f);
|
||||||
|
|
||||||
m_engine->TrackTextureMapping(rank, mat, Gfx::ENG_RSTATE_PART2, "lemt.png", "",
|
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);
|
left, 8.0f, 8.0f, 192.0f, 256.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1947,6 +1947,7 @@ void CBrain::UpdateInterface(float rTime)
|
||||||
if ( power == 0 )
|
if ( power == 0 )
|
||||||
{
|
{
|
||||||
energy = 0.0f;
|
energy = 0.0f;
|
||||||
|
limit = 0.0f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1877,52 +1877,33 @@ bool CMotionVehicle::EventFrameCanoni(const Event &event)
|
||||||
|
|
||||||
void CMotionVehicle::UpdateTrackMapping(float left, float right, ObjectType type)
|
void CMotionVehicle::UpdateTrackMapping(float left, float right, ObjectType type)
|
||||||
{
|
{
|
||||||
Gfx::Material mat;
|
Gfx::Material mat;
|
||||||
float limit[4];
|
mat.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f); // white
|
||||||
int rRank, lRank, i;
|
mat.ambient = Gfx::Color(0.5f, 0.5f, 0.5f);
|
||||||
|
|
||||||
memset( &mat, 0, sizeof(Gfx::Material) );
|
int rRank = m_object->GetObjectRank(6);
|
||||||
mat.diffuse.r = 1.0f;
|
int lRank = m_object->GetObjectRank(7);
|
||||||
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;
|
|
||||||
|
|
||||||
rRank = m_object->GetObjectRank(6);
|
if (type == OBJECT_MOBILEdr)
|
||||||
lRank = m_object->GetObjectRank(7);
|
|
||||||
|
|
||||||
|
|
||||||
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", "",
|
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);
|
right, 1.0f, 8.0f, 192.0f, 256.0f);
|
||||||
|
|
||||||
m_engine->TrackTextureMapping(lRank, mat, Gfx::ENG_RSTATE_PART2, "drawer.png", "",
|
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);
|
left, 1.0f, 8.0f, 192.0f, 256.0f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
limit[0] = 0.0f;
|
for (int i = 0; i < 2; i++)
|
||||||
limit[1] = m_engine->GetLimitLOD(0);
|
|
||||||
limit[2] = limit[1];
|
|
||||||
limit[3] = m_engine->GetLimitLOD(1);
|
|
||||||
|
|
||||||
for ( i=0 ; i<2 ; i++ )
|
|
||||||
{
|
{
|
||||||
m_engine->TrackTextureMapping(rRank, mat, Gfx::ENG_RSTATE_PART1, "lemt.png", "",
|
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);
|
right, 1.0f, 8.0f, 192.0f, 256.0f);
|
||||||
|
|
||||||
m_engine->TrackTextureMapping(lRank, mat, Gfx::ENG_RSTATE_PART2, "lemt.png", "",
|
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);
|
left, 1.0f, 8.0f, 192.0f, 256.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5811,21 +5811,16 @@ void CObject::FlatParent()
|
||||||
|
|
||||||
void CObject::UpdateEnergyMapping()
|
void CObject::UpdateEnergyMapping()
|
||||||
{
|
{
|
||||||
Gfx::Material mat;
|
if (Math::IsEqual(m_energy, m_lastEnergy, 0.01f))
|
||||||
float a, b, i, s, au, bu;
|
return;
|
||||||
float limit[6];
|
|
||||||
int j;
|
|
||||||
|
|
||||||
if ( fabs(m_energy-m_lastEnergy) < 0.01f ) return;
|
|
||||||
m_lastEnergy = m_energy;
|
m_lastEnergy = m_energy;
|
||||||
|
|
||||||
memset(&mat, 0, sizeof(mat));
|
Gfx::Material mat;
|
||||||
mat.diffuse.r = 1.0f;
|
mat.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f); // white
|
||||||
mat.diffuse.g = 1.0f;
|
mat.ambient = Gfx::Color(0.5f, 0.5f, 0.5f);
|
||||||
mat.diffuse.b = 1.0f; // white
|
|
||||||
mat.ambient.r = 0.5f;
|
float a = 0.0f, b = 0.0f;
|
||||||
mat.ambient.g = 0.5f;
|
|
||||||
mat.ambient.b = 0.5f;
|
|
||||||
|
|
||||||
if ( m_type == OBJECT_POWER ||
|
if ( m_type == OBJECT_POWER ||
|
||||||
m_type == OBJECT_ATOMIC )
|
m_type == OBJECT_ATOMIC )
|
||||||
|
@ -5833,35 +5828,30 @@ void CObject::UpdateEnergyMapping()
|
||||||
a = 2.0f;
|
a = 2.0f;
|
||||||
b = 0.0f; // dimensions of the battery (according to y)
|
b = 0.0f; // dimensions of the battery (according to y)
|
||||||
}
|
}
|
||||||
if ( m_type == OBJECT_STATION )
|
else if ( m_type == OBJECT_STATION )
|
||||||
{
|
{
|
||||||
a = 10.0f;
|
a = 10.0f;
|
||||||
b = 4.0f; // dimensions of the battery (according to y)
|
b = 4.0f; // dimensions of the battery (according to y)
|
||||||
}
|
}
|
||||||
if ( m_type == OBJECT_ENERGY )
|
else if ( m_type == OBJECT_ENERGY )
|
||||||
{
|
{
|
||||||
a = 9.0f;
|
a = 9.0f;
|
||||||
b = 3.0f; // dimensions of the battery (according to y)
|
b = 3.0f; // dimensions of the battery (according to y)
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0.50f+0.25f*m_energy; // origin
|
float i = 0.50f+0.25f*m_energy; // origin
|
||||||
s = i+0.25f; // width
|
float s = i+0.25f; // width
|
||||||
|
|
||||||
au = (s-i)/(b-a);
|
float au = (s-i)/(b-a);
|
||||||
bu = s-b*(s-i)/(b-a);
|
float bu = s-b*(s-i)/(b-a);
|
||||||
|
|
||||||
limit[0] = 0.0f;
|
Gfx::LODLevel lodLevels[3] = { Gfx::LOD_High, Gfx::LOD_Medium, Gfx::LOD_Low };
|
||||||
limit[1] = m_engine->GetLimitLOD(0);
|
|
||||||
limit[2] = limit[1];
|
|
||||||
limit[3] = m_engine->GetLimitLOD(1);
|
|
||||||
limit[4] = limit[3];
|
|
||||||
limit[5] = 1000000.0f;
|
|
||||||
|
|
||||||
for ( j=0 ; j<3 ; j++ )
|
for (int j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
m_engine->ChangeTextureMapping(m_objectPart[0].object,
|
m_engine->ChangeTextureMapping(m_objectPart[0].object,
|
||||||
mat, Gfx::ENG_RSTATE_PART3, "lemt.png", "",
|
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);
|
au, bu, 1.0f, 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,18 @@ bool ParseArgs(int argc, char *argv[])
|
||||||
return true;
|
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>
|
template<typename T>
|
||||||
void PrintStats(const std::map<T, int>& stats, int total)
|
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();
|
const std::vector<Gfx::ModelTriangle>& triangles = model.GetTriangles();
|
||||||
|
|
||||||
Math::Vector min( Math::HUGE_NUM, Math::HUGE_NUM, Math::HUGE_NUM);
|
Math::Vector bboxMin( Math::HUGE_NUM, Math::HUGE_NUM, Math::HUGE_NUM);
|
||||||
Math::Vector max(-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<std::string, int> texs1, texs2;
|
||||||
std::map<int, int> states;
|
std::map<int, int> states;
|
||||||
std::map<float, int> mins, maxs;
|
std::map<Gfx::LODLevel, int> lodLevels;
|
||||||
int variableTexs2 = 0;
|
int variableTexs2 = 0;
|
||||||
|
|
||||||
for (int i = 0; i < static_cast<int>( triangles.size() ); ++i)
|
for (int i = 0; i < static_cast<int>( triangles.size() ); ++i)
|
||||||
{
|
{
|
||||||
const Gfx::ModelTriangle& t = triangles[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);
|
bboxMin.x = Math::Min(t.p1.coord.x, t.p2.coord.x, t.p3.coord.x, bboxMin.x);
|
||||||
min.y = Math::Min(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, min.y);
|
bboxMin.y = Math::Min(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, bboxMin.y);
|
||||||
min.z = Math::Min(t.p1.coord.z, t.p2.coord.z, t.p3.coord.z, min.z);
|
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);
|
bboxMax.x = Math::Max(t.p1.coord.x, t.p2.coord.x, t.p3.coord.x, bboxMax.x);
|
||||||
max.y = Math::Max(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, max.y);
|
bboxMax.y = Math::Max(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, bboxMax.y);
|
||||||
max.z = Math::Max(t.p1.coord.z, t.p2.coord.z, t.p3.coord.z, max.z);
|
bboxMax.z = Math::Max(t.p1.coord.z, t.p2.coord.z, t.p3.coord.z, bboxMax.z);
|
||||||
|
|
||||||
texs1[t.tex1Name] += 1;
|
texs1[t.tex1Name] += 1;
|
||||||
if (! t.tex2Name.empty())
|
if (! t.tex2Name.empty())
|
||||||
|
@ -215,16 +227,15 @@ int main(int argc, char *argv[])
|
||||||
variableTexs2 += 1;
|
variableTexs2 += 1;
|
||||||
states[t.state] += 1;
|
states[t.state] += 1;
|
||||||
|
|
||||||
mins[t.min] += 1;
|
lodLevels[t.lodLevel] += 1;
|
||||||
maxs[t.max] += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cerr << "---- Info ----" << std::endl;
|
std::cerr << "---- Info ----" << std::endl;
|
||||||
std::cerr << "Total triangles: " << triangles.size();
|
std::cerr << "Total triangles: " << triangles.size();
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << "Bounding box:" << std::endl;
|
std::cerr << "Bounding box:" << std::endl;
|
||||||
std::cerr << " min: [" << min.x << ", " << min.y << ", " << min.z << "]" << std::endl;
|
std::cerr << " bboxMin: [" << bboxMin.x << ", " << bboxMin.y << ", " << bboxMin.z << "]" << std::endl;
|
||||||
std::cerr << " max: [" << max.x << ", " << max.y << ", " << max.z << "]" << std::endl;
|
std::cerr << " bboxMax: [" << bboxMax.x << ", " << bboxMax.y << ", " << bboxMax.z << "]" << std::endl;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << "Textures:" << std::endl;
|
std::cerr << "Textures:" << std::endl;
|
||||||
std::cerr << " tex1:" << std::endl;
|
std::cerr << " tex1:" << std::endl;
|
||||||
|
@ -237,10 +248,7 @@ int main(int argc, char *argv[])
|
||||||
PrintStats(states, triangles.size());
|
PrintStats(states, triangles.size());
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
std::cerr << "LOD:" << std::endl;
|
std::cerr << "LOD:" << std::endl;
|
||||||
std::cerr << " min:" << std::endl;
|
PrintStats(lodLevels, triangles.size());
|
||||||
PrintStats(mins, triangles.size());
|
|
||||||
std::cerr << " max:" << std::endl;
|
|
||||||
PrintStats(maxs, triangles.size());
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue