Fixes and refactoring
parent
5574eccebd
commit
3582f107a5
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue