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 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>( p1.next.size() ); i++)
for (int i = 0; i < static_cast<int>( m_baseObjects[baseObjRank].next.size() ); i++)
{ {
if (! m_baseObjects[baseObjRank].next[i].used) if (p1.next[i].tex1Name == tex1Name && p1.next[i].tex2Name == tex2Name)
{ return p1.next[i];
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 (unusedPresent) p1.next.push_back(EngineBaseObjTexTier(tex1Name, tex2Name));
{ return p1.next.back();
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();
} }
EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, float min, float max) EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, float min, float max)
{ {
bool unusedPresent = false;
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].used)
{
unusedPresent = true;
continue;
}
if ( (p2.next[i].min == min) && (p2.next[i].max == max) ) if ( (p2.next[i].min == min) && (p2.next[i].max == max) )
return p2.next[i]; return p2.next[i];
} }
if (unusedPresent) p2.next.push_back(EngineBaseObjLODTier(min, max));
{
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));
return p2.next.back(); return p2.next.back();
} }
EngineBaseObjDataTier& CEngine::AddLevel4(EngineBaseObjLODTier& p3, EngineTriangleType type, EngineBaseObjDataTier& CEngine::AddLevel4(EngineBaseObjLODTier& p3, EngineTriangleType type,
const Material& material, int state) const Material& material, int state)
{ {
bool unusedPresent = false;
for (int i = 0; i < static_cast<int>( p3.next.size() ); i++) 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) ) if ( (p3.next[i].type == type) && (p3.next[i].material == material) && (p3.next[i].state == state) )
return p3.next[i]; return p3.next[i];
} }
if (unusedPresent) p3.next.push_back(EngineBaseObjDataTier(type, material, state));
{
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));
return p3.next.back(); return p3.next.back();
} }
int CEngine::CreateBaseObject() int CEngine::CreateBaseObject()
{ {
int i = 0; int baseObjRank = 0;
for ( ; i < static_cast<int>( m_baseObjects.size() ); i++) 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; break;
} }
} }
if (i == static_cast<int>( m_baseObjects.size() )) if (baseObjRank == static_cast<int>( m_baseObjects.size() ))
m_baseObjects.push_back(EngineBaseObject()); m_baseObjects.push_back(EngineBaseObject());
else 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) 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]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
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++)
{ {
@ -607,10 +544,11 @@ void CEngine::DeleteBaseObject(int baseObjRank)
p4.staticBufferId = 0; p4.staticBufferId = 0;
} }
} }
p2.used = false;
p2.next.clear();
} }
p1.next.clear();
p1.used = false;
} }
void CEngine::DeleteAllBaseObjects() void CEngine::DeleteAllBaseObjects()
@ -638,7 +576,8 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector<VertexTex2>
m_lastObjectDetail = m_objectDetail; m_lastObjectDetail = m_objectDetail;
m_lastClippingDistance = m_clippingDistance; 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); EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max);
EngineBaseObjDataTier& p4 = AddLevel4(p3, triangleType, material, state); 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++) 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); p1.bboxMin.x = Math::Min(vertices[i].coord.x, p1.bboxMin.x);
m_baseObjects[baseObjRank].bboxMin.y = Math::Min(vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMin.y); p1.bboxMin.y = Math::Min(vertices[i].coord.y, p1.bboxMin.y);
m_baseObjects[baseObjRank].bboxMin.z = Math::Min(vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMin.z); p1.bboxMin.z = Math::Min(vertices[i].coord.z, p1.bboxMin.z);
m_baseObjects[baseObjRank].bboxMax.x = Math::Max(vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMax.x); p1.bboxMax.x = Math::Max(vertices[i].coord.x, p1.bboxMax.x);
m_baseObjects[baseObjRank].bboxMax.y = Math::Max(vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMax.y); p1.bboxMax.y = Math::Max(vertices[i].coord.y, p1.bboxMax.y);
m_baseObjects[baseObjRank].bboxMax.z = Math::Max(vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMax.z); p1.bboxMax.z = Math::Max(vertices[i].coord.z, p1.bboxMax.z);
} }
m_baseObjects[baseObjRank].radius = Math::Max(m_baseObjects[baseObjRank].bboxMin.Length(), p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
m_baseObjects[baseObjRank].bboxMax.Length());
} }
if (triangleType == ENG_TRIANGLE_TYPE_TRIANGLES) if (triangleType == ENG_TRIANGLE_TYPE_TRIANGLES)
m_baseObjects[baseObjRank].totalTriangles += vertices.size() / 3; p1.totalTriangles += vertices.size() / 3;
else else
m_baseObjects[baseObjRank].totalTriangles += vertices.size() - 2; p1.totalTriangles += vertices.size() - 2;
} }
void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer, 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() )); 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); EngineBaseObjLODTier& p3 = AddLevel3(p2, min, max);
p3.next.push_back(buffer); p3.next.push_back(buffer);
EngineBaseObjDataTier& p4 = p3.next.back(); EngineBaseObjDataTier& p4 = p3.next.back();
p4.used = true; UpdateStaticBuffer(p4);
p4.updateStaticBuffer = true;
m_updateStaticBuffers = true;
if (globalUpdate) 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++) 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); p1.bboxMin.x = Math::Min(p4.vertices[i].coord.x, p1.bboxMin.x);
m_baseObjects[baseObjRank].bboxMin.y = Math::Min(p4.vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMin.y); p1.bboxMin.y = Math::Min(p4.vertices[i].coord.y, p1.bboxMin.y);
m_baseObjects[baseObjRank].bboxMin.z = Math::Min(p4.vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMin.z); p1.bboxMin.z = Math::Min(p4.vertices[i].coord.z, p1.bboxMin.z);
m_baseObjects[baseObjRank].bboxMax.x = Math::Max(p4.vertices[i].coord.x, m_baseObjects[baseObjRank].bboxMax.x); p1.bboxMax.x = Math::Max(p4.vertices[i].coord.x, p1.bboxMax.x);
m_baseObjects[baseObjRank].bboxMax.y = Math::Max(p4.vertices[i].coord.y, m_baseObjects[baseObjRank].bboxMax.y); p1.bboxMax.y = Math::Max(p4.vertices[i].coord.y, p1.bboxMax.y);
m_baseObjects[baseObjRank].bboxMax.z = Math::Max(p4.vertices[i].coord.z, m_baseObjects[baseObjRank].bboxMax.z); p1.bboxMax.z = Math::Max(p4.vertices[i].coord.z, p1.bboxMax.z);
} }
m_baseObjects[baseObjRank].radius = Math::Max(m_baseObjects[baseObjRank].bboxMin.Length(), p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
m_baseObjects[baseObjRank].bboxMax.Length());
} }
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) 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) 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 CEngine::CreateObject()
{ {
int i = 0; int objRank = 0;
for ( ; i < static_cast<int>( m_objects.size() ); i++) 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; break;
} }
} }
if (i == static_cast<int>( m_objects.size() )) if (objRank == static_cast<int>( m_objects.size() ))
m_objects.push_back(EngineObject()); m_objects.push_back(EngineObject());
m_objects[i].used = true; m_objects[objRank].used = true;
Math::Matrix mat; Math::Matrix mat;
mat.LoadIdentity(); mat.LoadIdentity();
SetObjectTransform(i, mat); SetObjectTransform(objRank, mat);
m_objects[i].drawWorld = true; m_objects[objRank].drawWorld = true;
m_objects[i].distance = 0.0f; m_objects[objRank].distance = 0.0f;
m_objects[i].shadowRank = -1; m_objects[objRank].shadowRank = -1;
return i; return objRank;
} }
void CEngine::DeleteAllObjects() void CEngine::DeleteAllObjects()
@ -861,11 +796,11 @@ EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& mater
int baseObjRank = m_objects[objRank].baseObjRank; int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && 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];
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = m_baseObjects[baseObjRank].next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
if (p2.tex1Name != tex1Name) if (p2.tex1Name != tex1Name)
continue; 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++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (p3.min != min || p3.max != max) if (p3.min != min || p3.max != max)
continue; 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++) for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
EngineBaseObjDataTier& p4 = p3.next[l4]; EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if ( (p4.state & (~(ENG_RSTATE_DUAL_BLACK|ENG_RSTATE_DUAL_WHITE))) != state || if ( (p4.state & (~(ENG_RSTATE_DUAL_BLACK|ENG_RSTATE_DUAL_WHITE))) != state ||
p4.material != material ) p4.material != material )
@ -905,23 +836,21 @@ int CEngine::GetPartialTriangles(int objRank, float min, float max, float percen
int baseObjRank = m_objects[objRank].baseObjRank; int baseObjRank = m_objects[objRank].baseObjRank;
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() )); 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); int expectedCount = static_cast<int>(percent * total);
triangles.reserve(Math::Min(maxCount, expectedCount)); triangles.reserve(Math::Min(maxCount, expectedCount));
int actualCount = 0; 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]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (p3.min != min || p3.max != max) if (p3.min != min || p3.max != max)
continue; 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++) for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
EngineBaseObjDataTier& p4 = p3.next[l4]; EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) 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++) 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; 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]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if ( Math::IsEqual(p3.min, 0.0f ) && if ( Math::IsEqual(p3.min, 0.0f ) &&
Math::IsEqual(p3.max, oldLimit[0]) ) 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; int baseObjRank = m_objects[objRank].baseObjRank;
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];
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++) for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = p1.next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
if (p2.tex2Name == tex2Name) if (p2.tex2Name == tex2Name)
continue; // already new continue; // already new
EngineBaseObjTexTier& newP2 = AddLevel2(baseObjRank, p2.tex1Name, tex2Name); EngineBaseObjTexTier& newP2 = AddLevel2(p1, p2.tex1Name, tex2Name);
newP2.next.swap(p2.next); 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) 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, min, max);
if (p4 == nullptr) if (p4 == nullptr)
return; return;
@ -1424,16 +1346,18 @@ bool CEngine::GetBBox2D(int objRank, Math::Point &min, Math::Point &max)
int baseObjRank = m_objects[objRank].baseObjRank; int baseObjRank = m_objects[objRank].baseObjRank;
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];
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
Math::Vector p; Math::Vector p;
if ( i & (1<<0) ) p.x = m_baseObjects[baseObjRank].bboxMin.x; if ( i & (1<<0) ) p.x = p1.bboxMin.x;
else p.x = m_baseObjects[baseObjRank].bboxMax.x; else p.x = p1.bboxMax.x;
if ( i & (1<<1) ) p.y = m_baseObjects[baseObjRank].bboxMin.y; if ( i & (1<<1) ) p.y = p1.bboxMin.y;
else p.y = m_baseObjects[baseObjRank].bboxMax.y; else p.y = p1.bboxMax.y;
if ( i & (1<<2) ) p.z = m_baseObjects[baseObjRank].bboxMin.z; if ( i & (1<<2) ) p.z = p1.bboxMin.z;
else p.z = m_baseObjects[baseObjRank].bboxMax.z; else p.z = p1.bboxMax.z;
Math::Vector pp; Math::Vector pp;
if (TransformPoint(pp, objRank, p)) if (TransformPoint(pp, objRank, p))
@ -1598,20 +1522,14 @@ void CEngine::UpdateGeometry()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++) for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = p1.next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
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++)
{ {
EngineBaseObjDataTier& p4 = p3.next[l4]; EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i++) 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++) for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = p1.next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
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++)
{ {
EngineBaseObjDataTier& p4 = p3.next[l4]; EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (! p4.updateStaticBuffer) if (! p4.updateStaticBuffer)
continue; continue;
@ -1703,6 +1615,8 @@ bool CEngine::DetectBBox(int objRank, Math::Point mouse)
int baseObjRank = m_objects[objRank].baseObjRank; int baseObjRank = m_objects[objRank].baseObjRank;
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];
Math::Point min, max; Math::Point min, max;
min.x = 1000000.0f; min.x = 1000000.0f;
min.y = 1000000.0f; min.y = 1000000.0f;
@ -1713,12 +1627,12 @@ bool CEngine::DetectBBox(int objRank, Math::Point mouse)
{ {
Math::Vector p; Math::Vector p;
if ( i & (1<<0) ) p.x = m_baseObjects[baseObjRank].bboxMin.x; if ( i & (1<<0) ) p.x = p1.bboxMin.x;
else p.x = m_baseObjects[baseObjRank].bboxMax.x; else p.x = p1.bboxMax.x;
if ( i & (1<<1) ) p.y = m_baseObjects[baseObjRank].bboxMin.y; if ( i & (1<<1) ) p.y = p1.bboxMin.y;
else p.y = m_baseObjects[baseObjRank].bboxMax.y; else p.y = p1.bboxMax.y;
if ( i & (1<<2) ) p.z = m_baseObjects[baseObjRank].bboxMin.z; if ( i & (1<<2) ) p.z = p1.bboxMin.z;
else p.z = m_baseObjects[baseObjRank].bboxMax.z; else p.z = p1.bboxMax.z;
Math::Vector pp; Math::Vector pp;
if ( TransformPoint(pp, objRank, p) ) 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++) for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = p1.next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (p3.min != 0.0f) if (p3.min != 0.0f)
continue; // LOD B or C? 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++) for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
EngineBaseObjDataTier& p4 = p3.next[l4]; EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES) 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++) for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = p1.next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
if (! p2.tex1Name.empty()) if (! p2.tex1Name.empty())
{ {
@ -3083,7 +2989,7 @@ void CEngine::Draw3DScene()
int baseObjRank = m_objects[objRank].baseObjRank; int baseObjRank = m_objects[objRank].baseObjRank;
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];
if (! p1.used) if (! p1.used)
continue; continue;
@ -3091,18 +2997,13 @@ void CEngine::Draw3DScene()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++) for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = p1.next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
// Should be loaded by now
SetTexture(p2.tex1, 0); SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1); SetTexture(p2.tex2, 1);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if ( m_objects[objRank].distance < p3.min || if ( m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max ) 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++) for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
EngineBaseObjDataTier& p4 = p3.next[l4]; EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
SetMaterial(p4.material); SetMaterial(p4.material);
SetState(p4.state); SetState(p4.state);
@ -3163,18 +3062,13 @@ void CEngine::Draw3DScene()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++) for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = p1.next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
// Should be loaded by now
SetTexture(p2.tex1, 0); SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1); SetTexture(p2.tex2, 1);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if ( m_objects[objRank].distance < p3.min || if ( m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max ) 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++) for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
EngineBaseObjDataTier& p4 = p3.next[l4]; EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (m_objects[objRank].transparency != 0.0f) // transparent ? 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++) for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = p1.next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
// Should be loaded by now
SetTexture(p2.tex1, 0); SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1); SetTexture(p2.tex2, 1);
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (m_objects[objRank].distance < p3.min || if (m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max) 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++) for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
EngineBaseObjDataTier& p4 = p3.next[l4]; EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
if (m_objects[objRank].transparency == 0.0f) if (m_objects[objRank].transparency == 0.0f)
continue; continue;
@ -3393,8 +3278,6 @@ void CEngine::DrawInterface()
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++) for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{ {
EngineBaseObjTexTier& p2 = p1.next[l2]; EngineBaseObjTexTier& p2 = p1.next[l2];
if (! p2.used)
continue;
SetTexture(p2.tex1, 0); SetTexture(p2.tex1, 0);
SetTexture(p2.tex2, 1); SetTexture(p2.tex2, 1);
@ -3402,8 +3285,6 @@ void CEngine::DrawInterface()
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
{ {
EngineBaseObjLODTier& p3 = p2.next[l3]; EngineBaseObjLODTier& p3 = p2.next[l3];
if (! p3.used)
continue;
if (m_objects[objRank].distance < p3.min || if (m_objects[objRank].distance < p3.min ||
m_objects[objRank].distance >= p3.max) 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++) for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
{ {
EngineBaseObjDataTier& p4 = p3.next[l4]; EngineBaseObjDataTier& p4 = p3.next[l4];
if (! p4.used)
continue;
SetMaterial(p4.material); SetMaterial(p4.material);
SetState(p4.state); SetState(p4.state);

View File

@ -185,7 +185,6 @@ enum EngineObjectType
*/ */
struct EngineBaseObjDataTier struct EngineBaseObjDataTier
{ {
bool used;
EngineTriangleType type; EngineTriangleType type;
Material material; Material material;
int state; int state;
@ -193,11 +192,10 @@ struct EngineBaseObjDataTier
unsigned int staticBufferId; unsigned int staticBufferId;
bool updateStaticBuffer; bool updateStaticBuffer;
inline EngineBaseObjDataTier(bool used = false, inline EngineBaseObjDataTier(EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES,
EngineTriangleType type = ENG_TRIANGLE_TYPE_TRIANGLES,
const Material& material = Material(), const Material& material = Material(),
int state = ENG_RSTATE_NORMAL) 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 struct EngineBaseObjLODTier
{ {
bool used;
float min; float min;
float max; float max;
std::vector<EngineBaseObjDataTier> next; std::vector<EngineBaseObjDataTier> next;
inline EngineBaseObjLODTier(bool used = false, float min = 0.0f, float max = 0.0f) inline EngineBaseObjLODTier(float min = 0.0f, float max = 0.0f)
: used(used), min(min), max(max) {} : min(min), max(max) {}
}; };
/** /**
@ -221,16 +218,14 @@ struct EngineBaseObjLODTier
*/ */
struct EngineBaseObjTexTier struct EngineBaseObjTexTier
{ {
bool used;
std::string tex1Name; std::string tex1Name;
Texture tex1; Texture tex1;
std::string tex2Name; std::string tex2Name;
Texture tex2; Texture tex2;
std::vector<EngineBaseObjLODTier> next; std::vector<EngineBaseObjLODTier> next;
inline EngineBaseObjTexTier(bool used = false, const std::string& tex1Name = "", inline EngineBaseObjTexTier(const std::string& tex1Name = "", const std::string& tex2Name = "")
const std::string& tex2Name = "") : tex1Name(tex1Name), tex2Name(tex2Name) {}
: used(used), tex1Name(tex1Name), tex2Name(tex2Name) {}
}; };
/** /**
@ -624,27 +619,36 @@ struct EngineMouse
* *
* Objects are uniquely identified by object rank obtained at object creation. Creating an * 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 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: * The 4 tiers contain the following information:
* - level 1 (EngineObjLevel1) - two textures (names and structs) applied to triangles, * - level 1 (EngineBaseObject) - geometric statistics
* - level 2 (EngineObjLevel2) - object rank * - level 2 (EngineBaseObjTexTier) - two textures (names and structs) applied to triangles,
* - level 3 (EngineObjLevel3) - minumum and maximum LOD (=level of detail) * - level 3 (EngineBaseObjLODTier) - minumum and maximum LOD (=level of detail)
* - level 4 (EngineObjLevel4) - type of object*, material, render state and the actual triangle data * - 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. * 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 * 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 * \section Shadows Shadows
* *
* Each engine object can be associated with a shadow (EngineShadow). Like objects, shadows are * Each engine object can be associated with a shadow (EngineShadow). Like objects, shadows are
* identified by their rank obtained upon creation. * 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 * \section RenderStates Render States
* *
@ -1213,7 +1217,7 @@ protected:
void DrawStats(); void DrawStats();
//! Creates a new tier 2 object (texture) //! 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) //! Creates a new tier 3 object (LOD)
EngineBaseObjLODTier& AddLevel3(EngineBaseObjTexTier &p2, float min, float max); EngineBaseObjLODTier& AddLevel3(EngineBaseObjTexTier &p2, float min, float max);
//! Creates a new tier 4 object (data) //! Creates a new tier 4 object (data)

View File

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