Fixes and refactoring

dev-ui
Piotr Dziwinski 2012-12-27 14:18:16 +01:00
parent 5574eccebd
commit 3582f107a5
3 changed files with 122 additions and 239 deletions

View File

@ -459,145 +459,82 @@ int CEngine::GetStatisticTriangle()
Object management
*******************************************************/
EngineBaseObjTexTier& CEngine::AddLevel2(int baseObjRank, const std::string& tex1Name, const std::string& tex2Name)
EngineBaseObjTexTier& CEngine::AddLevel2(EngineBaseObject& p1, const std::string& tex1Name, const std::string& tex2Name)
{
bool unusedPresent = false;
for (int i = 0; i < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); i++)
for (int i = 0; i < static_cast<int>( p1.next.size() ); i++)
{
if (! m_baseObjects[baseObjRank].next[i].used)
{
unusedPresent = true;
continue;
}
if (m_baseObjects[baseObjRank].next[i].tex1Name == tex1Name && m_baseObjects[baseObjRank].next[i].tex2Name == tex2Name)
return m_baseObjects[baseObjRank].next[i];
if (p1.next[i].tex1Name == tex1Name && p1.next[i].tex2Name == tex2Name)
return p1.next[i];
}
if (unusedPresent)
{
for (int i = 0; i < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); i++)
{
if (! m_baseObjects[baseObjRank].next[i].used)
{
m_baseObjects[baseObjRank].next[i].used = true;
m_baseObjects[baseObjRank].next[i].tex1Name = tex1Name;
m_baseObjects[baseObjRank].next[i].tex2Name = tex2Name;
return m_baseObjects[baseObjRank].next[i];
}
}
}
m_baseObjects[baseObjRank].next.push_back(EngineBaseObjTexTier(true, tex1Name, tex2Name));
return m_baseObjects[baseObjRank].next.back();
p1.next.push_back(EngineBaseObjTexTier(tex1Name, tex2Name));
return p1.next.back();
}
EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, float min, float max)
{
bool unusedPresent = false;
for (int i = 0; i < static_cast<int>( p2.next.size() ); i++)
{
if (! p2.next[i].used)
{
unusedPresent = true;
continue;
}
if ( (p2.next[i].min == min) && (p2.next[i].max == max) )
return p2.next[i];
}
if (unusedPresent)
{
for (int i = 0; i < static_cast<int>( p2.next.size() ); i++)
{
if (! p2.next[i].used)
{
p2.next[i].used = true;
p2.next[i].min = min;
p2.next[i].max = max;
return p2.next[i];
}
}
}
p2.next.push_back(EngineBaseObjLODTier(true, min, max));
p2.next.push_back(EngineBaseObjLODTier(min, max));
return p2.next.back();
}
EngineBaseObjDataTier& CEngine::AddLevel4(EngineBaseObjLODTier& p3, EngineTriangleType type,
const Material& material, int state)
{
bool unusedPresent = false;
for (int i = 0; i < static_cast<int>( p3.next.size() ); i++)
{
if (! p3.next[i].used)
{
unusedPresent = true;
continue;
}
if ( (p3.next[i].type == type) && (p3.next[i].material == material) && (p3.next[i].state == state) )
return p3.next[i];
}
if (unusedPresent)
{
for (int i = 0; i < static_cast<int>( p3.next.size() ); i++)
{
if (! p3.next[i].used)
{
p3.next[i].used = true;
p3.next[i].type = type;
p3.next[i].material = material;
p3.next[i].state = state;
return p3.next[i];
}
}
}
p3.next.push_back(EngineBaseObjDataTier(true, type, material, state));
p3.next.push_back(EngineBaseObjDataTier(type, material, state));
return p3.next.back();
}
int CEngine::CreateBaseObject()
{
int i = 0;
for ( ; i < static_cast<int>( m_baseObjects.size() ); i++)
int baseObjRank = 0;
for ( ; baseObjRank < static_cast<int>( m_baseObjects.size() ); baseObjRank++)
{
if (! m_baseObjects[i].used)
if (! m_baseObjects[baseObjRank].used)
{
m_baseObjects[i].LoadDefault();
m_baseObjects[baseObjRank].LoadDefault();
break;
}
}
if (i == static_cast<int>( m_baseObjects.size() ))
if (baseObjRank == static_cast<int>( m_baseObjects.size() ))
m_baseObjects.push_back(EngineBaseObject());
else
m_baseObjects[i].LoadDefault();
m_baseObjects[baseObjRank].LoadDefault();
m_baseObjects[i].used = true;
m_baseObjects[baseObjRank].used = true;
return i;
return baseObjRank;
}
void CEngine::DeleteBaseObject(int baseObjRank)
{
assert(baseObjRank < -1 || baseObjRank >= static_cast<int>( m_baseObjects.size() ));
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
for (int l2 = 0; l2 < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); l2++)
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
if (! p1.used)
return;
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2];
if (! p2.used)
continue;
EngineBaseObjTexTier& p2 = p1.next[l2];
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
@ -607,10 +544,11 @@ void CEngine::DeleteBaseObject(int baseObjRank)
p4.staticBufferId = 0;
}
}
p2.used = false;
p2.next.clear();
}
p1.next.clear();
p1.used = false;
}
void CEngine::DeleteAllBaseObjects()
@ -638,7 +576,8 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector<VertexTex2>
m_lastObjectDetail = m_objectDetail;
m_lastClippingDistance = m_clippingDistance;
EngineBaseObjTexTier& p2 = AddLevel2(baseObjRank, tex1Name, tex2Name);
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max);
EngineBaseObjDataTier& p4 = AddLevel4(p3, triangleType, material, state);
@ -655,22 +594,21 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector<VertexTex2>
{
for (int i = 0; i < static_cast<int>( vertices.size() ); i++)
{
m_baseObjects[baseObjRank].bboxMin.x = Math::Min(vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMin.x);
m_baseObjects[baseObjRank].bboxMin.y = Math::Min(vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMin.y);
m_baseObjects[baseObjRank].bboxMin.z = Math::Min(vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMin.z);
m_baseObjects[baseObjRank].bboxMax.x = Math::Max(vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMax.x);
m_baseObjects[baseObjRank].bboxMax.y = Math::Max(vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMax.y);
m_baseObjects[baseObjRank].bboxMax.z = Math::Max(vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMax.z);
p1.bboxMin.x = Math::Min(vertices[i].coord.x, p1.bboxMin.x);
p1.bboxMin.y = Math::Min(vertices[i].coord.y, p1.bboxMin.y);
p1.bboxMin.z = Math::Min(vertices[i].coord.z, p1.bboxMin.z);
p1.bboxMax.x = Math::Max(vertices[i].coord.x, p1.bboxMax.x);
p1.bboxMax.y = Math::Max(vertices[i].coord.y, p1.bboxMax.y);
p1.bboxMax.z = Math::Max(vertices[i].coord.z, p1.bboxMax.z);
}
m_baseObjects[baseObjRank].radius = Math::Max(m_baseObjects[baseObjRank].bboxMin.Length(),
m_baseObjects[baseObjRank].bboxMax.Length());
p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
}
if (triangleType == ENG_TRIANGLE_TYPE_TRIANGLES)
m_baseObjects[baseObjRank].totalTriangles += vertices.size() / 3;
p1.totalTriangles += vertices.size() / 3;
else
m_baseObjects[baseObjRank].totalTriangles += vertices.size() - 2;
p1.totalTriangles += vertices.size() - 2;
}
void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer,
@ -679,17 +617,15 @@ void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buff
{
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
EngineBaseObjTexTier& p2 = AddLevel2(baseObjRank, tex1Name, tex2Name);
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max);
p3.next.push_back(buffer);
EngineBaseObjDataTier& p4 = p3.next.back();
p4.used = true;
p4.updateStaticBuffer = true;
m_updateStaticBuffers = true;
UpdateStaticBuffer(p4);
if (globalUpdate)
{
@ -699,52 +635,51 @@ void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buff
{
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i++)
{
m_baseObjects[baseObjRank].bboxMin.x = Math::Min(p4.vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMin.x);
m_baseObjects[baseObjRank].bboxMin.y = Math::Min(p4.vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMin.y);
m_baseObjects[baseObjRank].bboxMin.z = Math::Min(p4.vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMin.z);
m_baseObjects[baseObjRank].bboxMax.x = Math::Max(p4.vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMax.x);
m_baseObjects[baseObjRank].bboxMax.y = Math::Max(p4.vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMax.y);
m_baseObjects[baseObjRank].bboxMax.z = Math::Max(p4.vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMax.z);
p1.bboxMin.x = Math::Min(p4.vertices[i].coord.x, p1.bboxMin.x);
p1.bboxMin.y = Math::Min(p4.vertices[i].coord.y, p1.bboxMin.y);
p1.bboxMin.z = Math::Min(p4.vertices[i].coord.z, p1.bboxMin.z);
p1.bboxMax.x = Math::Max(p4.vertices[i].coord.x, p1.bboxMax.x);
p1.bboxMax.y = Math::Max(p4.vertices[i].coord.y, p1.bboxMax.y);
p1.bboxMax.z = Math::Max(p4.vertices[i].coord.z, p1.bboxMax.z);
}
m_baseObjects[baseObjRank].radius = Math::Max(m_baseObjects[baseObjRank].bboxMin.Length(),
m_baseObjects[baseObjRank].bboxMax.Length());
p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
}
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
m_baseObjects[baseObjRank].totalTriangles += p4.vertices.size() / 3;
p1.totalTriangles += p4.vertices.size() / 3;
else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE)
m_baseObjects[baseObjRank].totalTriangles += p4.vertices.size() - 2;
p1.totalTriangles += p4.vertices.size() - 2;
}
int CEngine::CreateObject()
{
int i = 0;
for ( ; i < static_cast<int>( m_objects.size() ); i++)
int objRank = 0;
for ( ; objRank < static_cast<int>( m_objects.size() ); objRank++)
{
if (! m_objects[i].used)
if (! m_objects[objRank].used)
{
m_objects[i].LoadDefault();
m_objects[objRank].LoadDefault();
break;
}
}
if (i == static_cast<int>( m_objects.size() ))
if (objRank == static_cast<int>( m_objects.size() ))
m_objects.push_back(EngineObject());
m_objects[i].used = true;
m_objects[objRank].used = true;
Math::Matrix mat;
mat.LoadIdentity();
SetObjectTransform(i, mat);
SetObjectTransform(objRank, mat);
m_objects[i].drawWorld = true;
m_objects[i].distance = 0.0f;
m_objects[i].shadowRank = -1;
m_objects[objRank].drawWorld = true;
m_objects[objRank].distance = 0.0f;
m_objects[objRank].shadowRank = -1;
return i;
return objRank;
}
void CEngine::DeleteAllObjects()
@ -861,11 +796,11 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
for (int l2 = 0; l2 < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); l2++)
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2];
if (! p2.used)
continue;
EngineBaseObjTexTier& p2 = p1.next[l2];
if (p2.tex1Name != tex1Name)
continue;
@ -873,8 +808,6 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (p3.min != min || p3.max != max)
continue;
@ -882,8 +815,6 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if ( (p4.state & (~(ENG_RSTATE_DUAL_BLACK|ENG_RSTATE_DUAL_WHITE))) != state ||
p4.material != material )
@ -905,23 +836,21 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
int total = m_baseObjects[baseObjRank].totalTriangles;
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
int total = p1.totalTriangles;
int expectedCount = static_cast<int>(percent * total);
triangles.reserve(Math::Min(maxCount, expectedCount));
int actualCount = 0;
for (int l2 = 0; l2 < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); l2++)
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2];
if (! p2.used)
continue;
EngineBaseObjTexTier& p2 = p1.next[l2];
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (p3.min != min || p3.max != max)
continue;
@ -929,8 +858,6 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
{
@ -1006,20 +933,18 @@ void CEngine::ChangeLOD()
for (int baseObjRank = 0; baseObjRank < static_cast<int>( m_baseObjects.size() ); baseObjRank++)
{
if (! m_baseObjects[baseObjRank].used)
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
if (! p1.used)
continue;
for (int l2 = 0; l2 < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); l2++)
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2];
if (! p2.used)
continue;
EngineBaseObjTexTier& p2 = p1.next[l2];
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if ( Math::IsEqual(p3.min, 0.0f ) &&
Math::IsEqual(p3.max, oldLimit[0]) )
@ -1057,21 +982,18 @@ void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name)
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
if (p2.tex2Name == tex2Name)
continue; // already new
EngineBaseObjTexTier& newP2 = AddLevel2(baseObjRank, p2.tex1Name, tex2Name);
EngineBaseObjTexTier& newP2 = AddLevel2(p1, p2.tex1Name, tex2Name);
newP2.next.swap(p2.next);
p2.used = false;
}
}
@ -1143,7 +1065,7 @@ void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state,
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);
if (p4 == nullptr)
return;
@ -1424,16 +1346,18 @@ bool CEngine::GetBBox2D(int objRank, Math::Point &min, Math::Point &max)
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
for (int i = 0; i < 8; i++)
{
Math::Vector p;
if ( i & (1<<0) ) p.x = m_baseObjects[baseObjRank].bboxMin.x;
else p.x = m_baseObjects[baseObjRank].bboxMax.x;
if ( i & (1<<1) ) p.y = m_baseObjects[baseObjRank].bboxMin.y;
else p.y = m_baseObjects[baseObjRank].bboxMax.y;
if ( i & (1<<2) ) p.z = m_baseObjects[baseObjRank].bboxMin.z;
else p.z = m_baseObjects[baseObjRank].bboxMax.z;
if ( i & (1<<0) ) p.x = p1.bboxMin.x;
else p.x = p1.bboxMax.x;
if ( i & (1<<1) ) p.y = p1.bboxMin.y;
else p.y = p1.bboxMax.y;
if ( i & (1<<2) ) p.z = p1.bboxMin.z;
else p.z = p1.bboxMax.z;
Math::Vector pp;
if (TransformPoint(pp, objRank, p))
@ -1598,20 +1522,14 @@ void CEngine::UpdateGeometry()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i++)
{
@ -1664,20 +1582,14 @@ void CEngine::UpdateStaticBuffers()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (! p4.updateStaticBuffer)
continue;
@ -1703,6 +1615,8 @@ bool CEngine::DetectBBox(int objRank, Math::Point mouse)
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
Math::Point min, max;
min.x = 1000000.0f;
min.y = 1000000.0f;
@ -1713,12 +1627,12 @@ bool CEngine::DetectBBox(int objRank, Math::Point mouse)
{
Math::Vector p;
if ( i & (1<<0) ) p.x = m_baseObjects[baseObjRank].bboxMin.x;
else p.x = m_baseObjects[baseObjRank].bboxMax.x;
if ( i & (1<<1) ) p.y = m_baseObjects[baseObjRank].bboxMin.y;
else p.y = m_baseObjects[baseObjRank].bboxMax.y;
if ( i & (1<<2) ) p.z = m_baseObjects[baseObjRank].bboxMin.z;
else p.z = m_baseObjects[baseObjRank].bboxMax.z;
if ( i & (1<<0) ) p.x = p1.bboxMin.x;
else p.x = p1.bboxMax.x;
if ( i & (1<<1) ) p.y = p1.bboxMin.y;
else p.y = p1.bboxMax.y;
if ( i & (1<<2) ) p.z = p1.bboxMin.z;
else p.z = p1.bboxMax.z;
Math::Vector pp;
if ( TransformPoint(pp, objRank, p) )
@ -1762,14 +1676,10 @@ int CEngine::DetectObject(Math::Point mouse)
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (p3.min != 0.0f)
continue; // LOD B or C?
@ -1777,8 +1687,6 @@ int CEngine::DetectObject(Math::Point mouse)
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
{
@ -2273,8 +2181,6 @@ bool CEngine::LoadAllTextures()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
if (! p2.tex1Name.empty())
{
@ -3083,7 +2989,7 @@ void CEngine::Draw3DScene()
int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
if (! p1.used)
continue;
@ -3091,18 +2997,13 @@ void CEngine::Draw3DScene()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
// Should be loaded by now
SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if ( m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max )
@ -3111,8 +3012,6 @@ void CEngine::Draw3DScene()
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
SetMaterial(p4.material);
SetState(p4.state);
@ -3163,18 +3062,13 @@ void CEngine::Draw3DScene()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
// Should be loaded by now
SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if ( m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max )
@ -3183,8 +3077,6 @@ void CEngine::Draw3DScene()
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (m_objects[objRank].transparency != 0.0f) // transparent ?
{
@ -3236,18 +3128,13 @@ void CEngine::Draw3DScene()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
// Should be loaded by now
SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max)
@ -3256,8 +3143,6 @@ void CEngine::Draw3DScene()
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (m_objects[objRank].transparency == 0.0f)
continue;
@ -3393,8 +3278,6 @@ void CEngine::DrawInterface()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1);
@ -3402,8 +3285,6 @@ void CEngine::DrawInterface()
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{
EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max)
@ -3412,8 +3293,6 @@ void CEngine::DrawInterface()
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{
EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
SetMaterial(p4.material);
SetState(p4.state);

View File

@ -185,7 +185,6 @@ enum EngineObjectType
*/
struct EngineBaseObjDataTier
{
bool used;
EngineTriangleType type;
Material material;
int state;
@ -193,11 +192,10 @@ struct EngineBaseObjDataTier
unsigned int staticBufferId;
bool updateStaticBuffer;
inline EngineBaseObjDataTier(bool used = false,
EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES,
inline EngineBaseObjDataTier(EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES,
const Material& material = Material(),
int state = ENG_RSTATE_NORMAL)
: used(used), type(type), material(material), state(state), staticBufferId(0), updateStaticBuffer(false) {}
: type(type), material(material), state(state), staticBufferId(0), updateStaticBuffer(false) {}
};
/**
@ -206,13 +204,12 @@ struct EngineBaseObjDataTier
*/
struct EngineBaseObjLODTier
{
bool used;
float min;
float max;
std::vector<EngineBaseObjDataTier> next;
inline EngineBaseObjLODTier(bool used = false, float min = 0.0f, float max = 0.0f)
: used(used), min(min), max(max) {}
inline EngineBaseObjLODTier(float min = 0.0f, float max = 0.0f)
: min(min), max(max) {}
};
/**
@ -221,16 +218,14 @@ struct EngineBaseObjLODTier
*/
struct EngineBaseObjTexTier
{
bool used;
std::string tex1Name;
Texture tex1;
std::string tex2Name;
Texture tex2;
std::vector<EngineBaseObjLODTier> next;
inline EngineBaseObjTexTier(bool used = false, const std::string& tex1Name = "",
const std::string& tex2Name = "")
: used(used), tex1Name(tex1Name), tex2Name(tex2Name) {}
inline EngineBaseObjTexTier(const std::string& tex1Name = "", const std::string& tex2Name = "")
: tex1Name(tex1Name), tex2Name(tex2Name) {}
};
/**
@ -624,27 +619,36 @@ struct EngineMouse
*
* Objects are uniquely identified by object rank obtained at object creation. Creating an
* object equals to allocating space for EngineObject structure which holds object parameters.
* Object's geometric data is stored in a separate structure - a 4-tier tree which splits
* the information of each geometric triangle.
*
* Object's geometric data is stored as a separate object -- base engine object. Each object
* must reference a valid base engine object. This many-to-one association allows to share
* same geometric data (e.g. from same model) across objects. Base engine objects are identified
* by unique rank obtained upon their creation.
*
* Base engine object data is stored in a 4-tier tree which splits the data describing triangles.
*
* The 4 tiers contain the following information:
* - level 1 (EngineObjLevel1) - two textures (names and structs) applied to triangles,
* - level 2 (EngineObjLevel2) - object rank
* - level 3 (EngineObjLevel3) - minumum and maximum LOD (=level of detail)
* - level 4 (EngineObjLevel4) - type of object*, material, render state and the actual triangle data
* - level 1 (EngineBaseObject) - geometric statistics
* - level 2 (EngineBaseObjTexTier) - two textures (names and structs) applied to triangles,
* - level 3 (EngineBaseObjLODTier) - minumum and maximum LOD (=level of detail)
* - level 4 (EngineBaseObjDataTier) - type of object*, material, render state and the actual vertex data
*
* NOTE: type of object in this context means only the internal type in 3D engine. It is not related
* *NOTE: type of object in this context means only the internal type in 3D engine. It is not related
* to CObject types.
*
* Last tier containing vertex data contains also an ID of static buffer holding the data.
* The static buffer is created and updated with new data as needed.
*
* Such tiered structure complicates loops over all object data, but saves a lot of memory and
* optimizes the rendering process (for instance, switching of textures is an expensive operation).
* optimizes the rendering process.
*
* \section Shadows Shadows
*
* Each engine object can be associated with a shadow (EngineShadow). Like objects, shadows are
* identified by their rank obtained upon creation.
*
* ...
* Shadows are drawn as circular spots on the ground, except for shadows for worms, which have
* special mode for them.
*
* \section RenderStates Render States
*
@ -1213,7 +1217,7 @@ protected:
void DrawStats();
//! Creates a new tier 2 object (texture)
EngineBaseObjTexTier& AddLevel2(int baseObjRank, 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)
EngineBaseObjLODTier& AddLevel3(EngineBaseObjTexTier &p2, float min, float max);
//! Creates a new tier 4 object (data)

View File

@ -1151,7 +1151,7 @@ void CGLDevice::DrawStaticBuffer(unsigned int bufferId)
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, normal));
glActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, texCoord));
}