Added mesh LOD.

This commit is contained in:
leo 2015-05-24 04:36:25 +00:00
parent 77424ccf16
commit 307ed62ceb
8 changed files with 684 additions and 389 deletions

View file

@ -78,6 +78,11 @@ public:
mLength = NewSize;
}
void SetGrow(int Grow)
{
mGrow = Grow;
}
void AllocGrow(int Grow)
{
if ((mLength + Grow) > mAlloc)

View file

@ -29,10 +29,10 @@ static int lcTranslucentRenderMeshCompare(const void* Elem1, const void* Elem2)
lcRenderMesh* Mesh2 = (lcRenderMesh*)Elem2;
if (Mesh1->Distance < Mesh2->Distance)
return -1;
return 1;
if (Mesh1->Distance > Mesh2->Distance)
return 1;
return -1;
return 0;
}
@ -44,6 +44,7 @@ lcScene::lcScene()
void lcScene::Begin(const lcMatrix44& ViewMatrix)
{
mViewMatrix = ViewMatrix;
mOpaqueMeshes.RemoveAll();
mTranslucentMeshes.RemoveAll();
mInterfaceObjects.RemoveAll();
@ -962,13 +963,14 @@ void lcContext::DrawOpaqueMeshes(const lcArray<lcRenderMesh>& OpaqueMeshes)
{
lcRenderMesh& RenderMesh = OpaqueMeshes[MeshIdx];
lcMesh* Mesh = RenderMesh.Mesh;
int LodIndex = RenderMesh.LodIndex;
BindMesh(Mesh);
SetWorldMatrix(RenderMesh.WorldMatrix);
for (int SectionIdx = 0; SectionIdx < Mesh->mNumSections; SectionIdx++)
for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LodIndex].NumSections; SectionIdx++)
{
lcMeshSection* Section = &Mesh->mSections[SectionIdx];
lcMeshSection* Section = &Mesh->mLods[LodIndex].Sections[SectionIdx];
int ColorIndex = Section->ColorIndex;
if (Section->PrimitiveType == GL_TRIANGLES)
@ -1038,13 +1040,14 @@ void lcContext::DrawTranslucentMeshes(const lcArray<lcRenderMesh>& TranslucentMe
{
lcRenderMesh& RenderMesh = TranslucentMeshes[MeshIdx];
lcMesh* Mesh = RenderMesh.Mesh;
int LodIndex = RenderMesh.LodIndex;
BindMesh(Mesh);
SetWorldMatrix(RenderMesh.WorldMatrix);
for (int SectionIdx = 0; SectionIdx < Mesh->mNumSections; SectionIdx++)
for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LodIndex].NumSections; SectionIdx++)
{
lcMeshSection* Section = &Mesh->mSections[SectionIdx];
lcMeshSection* Section = &Mesh->mLods[LodIndex].Sections[SectionIdx];
int ColorIndex = Section->ColorIndex;
if (Section->PrimitiveType != GL_TRIANGLES)

View file

@ -819,8 +819,17 @@ void lcPiecesLibrary::SaveCacheFile()
mSaveCache = false;
}
int LibraryMeshSectionCompare(lcLibraryMeshSection* const& a, lcLibraryMeshSection* const& b)
struct lcMergeSection
{
lcLibraryMeshSection* Shared;
lcLibraryMeshSection* Lod;
};
static int LibraryMeshSectionCompare(lcMergeSection const& First, lcMergeSection const& Second)
{
lcLibraryMeshSection* a = First.Lod ? First.Lod : First.Shared;
lcLibraryMeshSection* b = Second.Lod ? Second.Lod : Second.Shared;
if (a->mPrimitiveType != b->mPrimitiveType)
{
int PrimitiveOrder[LC_MESH_NUM_PRIMITIVE_TYPES] =
@ -868,7 +877,7 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info)
return false;
const char* OldLocale = setlocale(LC_NUMERIC, "C");
bool Ret = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData);
bool Ret = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED);
setlocale(LC_NUMERIC, OldLocale);
if (!Ret)
@ -889,7 +898,7 @@ bool lcPiecesLibrary::LoadPiece(PieceInfo* Info)
return false;
const char* OldLocale = setlocale(LC_NUMERIC, "C");
bool Ret = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData);
bool Ret = ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED);
setlocale(LC_NUMERIC, OldLocale);
if (!Ret)
@ -908,28 +917,93 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
{
lcMesh* Mesh = new lcMesh();
int NumIndices = 0;
int BaseVertices[LC_NUM_MESHDATA_TYPES];
int BaseTexturedVertices[LC_NUM_MESHDATA_TYPES];
int NumVertices = 0;
int NumTexturedVertices = 0;
for (int SectionIdx = 0; SectionIdx < MeshData.mSections.GetSize(); SectionIdx++)
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
{
lcLibraryMeshSection* Section = MeshData.mSections[SectionIdx];
lcArray<lcLibraryMeshSection*>& Sections = MeshData.mSections[MeshDataIdx];
for (int SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++)
{
lcLibraryMeshSection* Section = Sections[SectionIdx];
Section->mColor = lcGetColorIndex(Section->mColor);
NumIndices += Section->mIndices.GetSize();
}
MeshData.mSections.Sort(LibraryMeshSectionCompare);
BaseVertices[MeshDataIdx] = NumVertices;
NumVertices += MeshData.mVertices[MeshDataIdx].GetSize();
BaseTexturedVertices[MeshDataIdx] = NumTexturedVertices;
NumTexturedVertices += MeshData.mTexturedVertices[MeshDataIdx].GetSize();
}
Mesh->Create(MeshData.mSections.GetSize(), MeshData.mVertices.GetSize(), MeshData.mTexturedVertices.GetSize(), NumIndices);
lcuint16 NumSections[LC_NUM_MESH_LODS];
int NumIndices = 0;
lcArray<lcMergeSection> MergeSections[LC_NUM_MESH_LODS];
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
{
const lcArray<lcLibraryMeshSection*>& SharedSections = MeshData.mSections[LC_MESHDATA_SHARED];
const lcArray<lcLibraryMeshSection*>& Sections = MeshData.mSections[LodIdx];
for (int SharedSectionIdx = 0; SharedSectionIdx < SharedSections.GetSize(); SharedSectionIdx++)
{
lcLibraryMeshSection* SharedSection = SharedSections[SharedSectionIdx];
NumIndices += SharedSection->mIndices.GetSize();
lcMergeSection& MergeSection = MergeSections[LodIdx].Add();
MergeSection.Shared = SharedSection;
MergeSection.Lod = NULL;
}
for (int SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++)
{
lcLibraryMeshSection* Section = Sections[SectionIdx];
bool Found = false;
NumIndices += Section->mIndices.GetSize();
for (int SharedSectionIdx = 0; SharedSectionIdx < SharedSections.GetSize(); SharedSectionIdx++)
{
lcLibraryMeshSection* SharedSection = SharedSections[SharedSectionIdx];
if (SharedSection->mColor == Section->mColor && SharedSection->mPrimitiveType == Section->mPrimitiveType && SharedSection->mTexture == Section->mTexture)
{
lcMergeSection& MergeSection = MergeSections[LodIdx][SharedSectionIdx];
MergeSection.Lod = Section;
Found = true;
break;
}
}
if (!Found)
{
lcMergeSection& MergeSection = MergeSections[LodIdx].Add();
MergeSection.Shared = NULL;
MergeSection.Lod = Section;
}
}
NumSections[LodIdx] = MergeSections[LodIdx].GetSize();
MergeSections[LodIdx].Sort(LibraryMeshSectionCompare);
}
Mesh->Create(NumSections, NumVertices, NumTexturedVertices, NumIndices);
lcVertex* DstVerts = (lcVertex*)Mesh->mVertexData;
lcVector3 Min(FLT_MAX, FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX, -FLT_MAX);
for (int VertexIdx = 0; VertexIdx < MeshData.mVertices.GetSize(); VertexIdx++)
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
{
const lcArray<lcVertex>& Vertices = MeshData.mVertices[MeshDataIdx];
for (int VertexIdx = 0; VertexIdx < Vertices.GetSize(); VertexIdx++)
{
lcVertex& DstVertex = *DstVerts++;
const lcVector3& SrcPosition = MeshData.mVertices[VertexIdx].Position;
const lcVector3& SrcPosition = Vertices[VertexIdx].Position;
lcVector3& DstPosition = DstVertex.Position;
DstPosition = lcVector3(SrcPosition.x, SrcPosition.z, -SrcPosition.y);
@ -941,13 +1015,18 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
Max.y = lcMax(Max.y, DstPosition.y);
Max.z = lcMax(Max.z, DstPosition.z);
}
}
lcVertexTextured* DstTexturedVerts = (lcVertexTextured*)DstVerts;
for (int VertexIdx = 0; VertexIdx < MeshData.mTexturedVertices.GetSize(); VertexIdx++)
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
{
const lcArray<lcVertexTextured>& TexturedVertices = MeshData.mTexturedVertices[MeshDataIdx];
for (int VertexIdx = 0; VertexIdx < TexturedVertices.GetSize(); VertexIdx++)
{
lcVertexTextured& DstVertex = *DstTexturedVerts++;
lcVertexTextured& SrcVertex = MeshData.mTexturedVertices[VertexIdx];
lcVertexTextured& SrcVertex = TexturedVertices[VertexIdx];
const lcVector3& SrcPosition = SrcVertex.Position;
lcVector3& DstPosition = DstVertex.Position;
@ -962,6 +1041,7 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
Max.y = lcMax(Max.y, DstPosition.y);
Max.z = lcMax(Max.z, DstPosition.z);
}
}
Info->m_fDimensions[0] = Max.x;
Info->m_fDimensions[1] = Max.y;
@ -969,9 +1049,103 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
Info->m_fDimensions[3] = Min.x;
Info->m_fDimensions[4] = Min.y;
Info->m_fDimensions[5] = Min.z;
Mesh->mRadius = lcLength((Max - Min) / 2.0f);
NumIndices = 0;
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
{
for (int SectionIdx = 0; SectionIdx < MergeSections[LodIdx].GetSize(); SectionIdx++)
{
lcMergeSection& MergeSection = MergeSections[LodIdx][SectionIdx];
lcMeshSection& DstSection = Mesh->mLods[LodIdx].Sections[SectionIdx];
lcLibraryMeshSection* SetupSection = MergeSection.Shared ? MergeSection.Shared : MergeSection.Lod;
DstSection.ColorIndex = SetupSection->mColor;
DstSection.PrimitiveType = (SetupSection->mPrimitiveType == LC_MESH_TRIANGLES || SetupSection->mPrimitiveType == LC_MESH_TEXTURED_TRIANGLES) ? GL_TRIANGLES : GL_LINES;
DstSection.NumIndices = 0;
DstSection.Texture = SetupSection->mTexture;
if (DstSection.Texture)
DstSection.Texture->AddRef();
if (Mesh->mNumVertices < 0x10000)
{
DstSection.IndexOffset = NumIndices * 2;
lcuint16* Index = (lcuint16*)Mesh->mIndexData + NumIndices;
if (MergeSection.Shared)
{
lcuint16 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LC_MESHDATA_SHARED] : BaseVertices[LC_MESHDATA_SHARED];
lcLibraryMeshSection* SrcSection = MergeSection.Shared;
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
DstSection.NumIndices += SrcSection->mIndices.GetSize();
}
if (MergeSection.Lod)
{
lcuint16 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LodIdx] : BaseVertices[LodIdx];
lcLibraryMeshSection* SrcSection = MergeSection.Lod;
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
DstSection.NumIndices += SrcSection->mIndices.GetSize();
}
}
else
{
DstSection.IndexOffset = NumIndices * 4;
lcuint32* Index = (lcuint32*)Mesh->mIndexData + NumIndices;
if (MergeSection.Shared)
{
lcuint32 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LC_MESHDATA_SHARED] : BaseVertices[LC_MESHDATA_SHARED];
lcLibraryMeshSection* SrcSection = MergeSection.Shared;
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
DstSection.NumIndices += SrcSection->mIndices.GetSize();
}
if (MergeSection.Lod)
{
lcuint32 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LodIdx] : BaseVertices[LodIdx];
lcLibraryMeshSection* SrcSection = MergeSection.Shared;
for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++)
*Index++ = BaseVertex + SrcSection->mIndices[IndexIdx];
DstSection.NumIndices += SrcSection->mIndices.GetSize();
}
}
if (DstSection.PrimitiveType == GL_TRIANGLES)
{
if (DstSection.ColorIndex == gDefaultColor)
Info->mFlags |= LC_PIECE_HAS_DEFAULT;
else
{
if (lcIsColorTranslucent(DstSection.ColorIndex))
Info->mFlags |= LC_PIECE_HAS_TRANSLUCENT;
else
Info->mFlags |= LC_PIECE_HAS_SOLID;
}
}
else
Info->mFlags |= LC_PIECE_HAS_LINES;
NumIndices += DstSection.NumIndices;
}
}
/*
for (int SectionIdx = 0; SectionIdx < MeshData.mSections.GetSize(); SectionIdx++)
{
lcMeshSection& DstSection = Mesh->mSections[SectionIdx];
@ -1021,7 +1195,7 @@ void lcPiecesLibrary::CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData)
NumIndices += DstSection.NumIndices;
}
*/
Info->SetMesh(Mesh);
}
@ -1130,15 +1304,44 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
if (mZipFiles[LC_ZIPFILE_OFFICIAL])
{
int LowPrimitiveIndex = -1;
if (Primitive->mStud && strncmp(Primitive->mName, "8/", 2))
{
char Name[LC_PIECE_NAME_LEN];
strcpy(Name, "8/");
strcat(Name, Primitive->mName);
LowPrimitiveIndex = FindPrimitiveIndex(Name);
}
lcMemFile PrimFile;
if (!mZipFiles[Primitive->mZipFileType]->ExtractFile(Primitive->mZipFileIndex, PrimFile))
return false;
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData))
if (LowPrimitiveIndex == -1)
{
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED))
return false;
}
else
{
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_HIGH))
return false;
lcLibraryPrimitive* LowPrimitive = mPrimitives[LowPrimitiveIndex];
if (!mZipFiles[LowPrimitive->mZipFileType]->ExtractFile(LowPrimitive->mZipFileIndex, PrimFile))
return false;
TextureStack.RemoveAll();
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_LOW))
return false;
}
}
else
{
char Name[LC_PIECE_NAME_LEN];
strcpy(Name, Primitive->mName);
@ -1155,7 +1358,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
if (!PrimFile.Open(FileName, "rt"))
return false;
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData))
if (!ReadMeshData(PrimFile, lcMatrix44Identity(), 16, TextureStack, Primitive->mMeshData, LC_MESHDATA_SHARED))
return false;
}
@ -1164,7 +1367,7 @@ bool lcPiecesLibrary::LoadPrimitive(int PrimitiveIndex)
return true;
}
bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData)
bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType)
{
char Buffer[1024];
char* Line;
@ -1368,9 +1571,9 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
continue;
if (Primitive->mStud)
MeshData.AddMeshDataNoDuplicateCheck(Primitive->mMeshData, IncludeTransform, ColorCode, TextureMap);
MeshData.AddMeshDataNoDuplicateCheck(Primitive->mMeshData, IncludeTransform, ColorCode, TextureMap, MeshDataType);
else if (!Primitive->mSubFile)
MeshData.AddMeshData(Primitive->mMeshData, IncludeTransform, ColorCode, TextureMap);
MeshData.AddMeshData(Primitive->mMeshData, IncludeTransform, ColorCode, TextureMap, MeshDataType);
else
{
if (mZipFiles[LC_ZIPFILE_OFFICIAL])
@ -1380,7 +1583,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
if (!mZipFiles[Primitive->mZipFileType]->ExtractFile(Primitive->mZipFileIndex, IncludeFile))
continue;
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData))
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType))
continue;
}
else
@ -1399,7 +1602,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
if (!IncludeFile.Open(FileName, "rt"))
continue;
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData))
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType))
continue;
}
}
@ -1420,7 +1623,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
if (!mZipFiles[Info->mZipFileType]->ExtractFile(Info->mZipFileIndex, IncludeFile))
break;
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData))
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType))
break;
}
else
@ -1436,7 +1639,7 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
if (!IncludeFile.Open(FileName, "rt"))
break;
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData))
if (!ReadMeshData(IncludeFile, IncludeTransform, ColorCode, TextureStack, MeshData, MeshDataType))
break;
}
@ -1454,13 +1657,13 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
if (TextureMap)
{
MeshData.AddTexturedLine(LineType, ColorCode, *TextureMap, Points);
MeshData.AddTexturedLine(MeshDataType, LineType, ColorCode, *TextureMap, Points);
if (TextureMap->Next)
TextureStack.RemoveIndex(TextureStack.GetSize() - 1);
}
else
MeshData.AddLine(LineType, ColorCode, Points);
MeshData.AddLine(MeshDataType, LineType, ColorCode, Points);
} break;
case 3:
@ -1474,13 +1677,13 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
if (TextureMap)
{
MeshData.AddTexturedLine(LineType, ColorCode, *TextureMap, Points);
MeshData.AddTexturedLine(MeshDataType, LineType, ColorCode, *TextureMap, Points);
if (TextureMap->Next)
TextureStack.RemoveIndex(TextureStack.GetSize() - 1);
}
else
MeshData.AddLine(LineType, ColorCode, Points);
MeshData.AddLine(MeshDataType, LineType, ColorCode, Points);
} break;
case 4:
@ -1495,13 +1698,13 @@ bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransf
if (TextureMap)
{
MeshData.AddTexturedLine(LineType, ColorCode, *TextureMap, Points);
MeshData.AddTexturedLine(MeshDataType, LineType, ColorCode, *TextureMap, Points);
if (TextureMap->Next)
TextureStack.RemoveIndex(TextureStack.GetSize() - 1);
}
else
MeshData.AddLine(LineType, ColorCode, Points);
MeshData.AddLine(MeshDataType, LineType, ColorCode, Points);
} break;
}
}
@ -1548,25 +1751,26 @@ void lcLibraryMeshData::TestQuad(int* QuadIndices, const lcVector3* Vertices)
}
}
void lcLibraryMeshData::AddLine(int LineType, lcuint32 ColorCode, const lcVector3* Vertices)
void lcLibraryMeshData::AddLine(lcMeshDataType MeshDataType, int LineType, lcuint32 ColorCode, const lcVector3* Vertices)
{
lcLibraryMeshSection* Section = NULL;
int SectionIdx;
LC_MESH_PRIMITIVE_TYPE PrimitiveType = (LineType == 2) ? LC_MESH_LINES : LC_MESH_TRIANGLES;
lcArray<lcLibraryMeshSection*>& Sections = mSections[MeshDataType];
for (SectionIdx = 0; SectionIdx < mSections.GetSize(); SectionIdx++)
for (SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++)
{
Section = mSections[SectionIdx];
Section = Sections[SectionIdx];
if (Section->mColor == ColorCode && Section->mPrimitiveType == PrimitiveType && Section->mTexture == NULL)
break;
}
if (SectionIdx == mSections.GetSize())
if (SectionIdx == Sections.GetSize())
{
Section = new lcLibraryMeshSection(PrimitiveType, ColorCode, NULL);
mSections.Add(Section);
Sections.Add(Section);
}
int QuadIndices[4] = { 0, 1, 2, 3 };
@ -1579,10 +1783,11 @@ void lcLibraryMeshData::AddLine(int LineType, lcuint32 ColorCode, const lcVector
for (int IndexIdx = 0; IndexIdx < LineType; IndexIdx++)
{
const lcVector3& Position = Vertices[QuadIndices[IndexIdx]];
lcArray<lcVertex>& VertexArray = mVertices[MeshDataType];
for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--)
for (int VertexIdx = VertexArray.GetSize() - 1; VertexIdx >= 0; VertexIdx--)
{
lcVertex& DstVertex = mVertices[VertexIdx];
lcVertex& DstVertex = VertexArray[VertexIdx];
if (Position == DstVertex.Position)
{
@ -1593,8 +1798,8 @@ void lcLibraryMeshData::AddLine(int LineType, lcuint32 ColorCode, const lcVector
if (Indices[IndexIdx] == -1)
{
Indices[IndexIdx] = mVertices.GetSize();
lcVertex& DstVertex = mVertices.Add();
Indices[IndexIdx] = VertexArray.GetSize();
lcVertex& DstVertex = VertexArray.Add();
DstVertex.Position = Position;
}
}
@ -1627,25 +1832,26 @@ void lcLibraryMeshData::AddLine(int LineType, lcuint32 ColorCode, const lcVector
}
}
void lcLibraryMeshData::AddTexturedLine(int LineType, lcuint32 ColorCode, const lcLibraryTextureMap& Map, const lcVector3* Vertices)
void lcLibraryMeshData::AddTexturedLine(lcMeshDataType MeshDataType, int LineType, lcuint32 ColorCode, const lcLibraryTextureMap& Map, const lcVector3* Vertices)
{
lcLibraryMeshSection* Section = NULL;
int SectionIdx;
LC_MESH_PRIMITIVE_TYPE PrimitiveType = (LineType == 2) ? LC_MESH_TEXTURED_LINES : LC_MESH_TEXTURED_TRIANGLES;
lcArray<lcLibraryMeshSection*>& Sections = mSections[MeshDataType];
for (SectionIdx = 0; SectionIdx < mSections.GetSize(); SectionIdx++)
for (SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++)
{
Section = mSections[SectionIdx];
Section = Sections[SectionIdx];
if (Section->mColor == ColorCode && Section->mPrimitiveType == PrimitiveType && Section->mTexture == Map.Texture)
break;
}
if (SectionIdx == mSections.GetSize())
if (SectionIdx == Sections.GetSize())
{
Section = new lcLibraryMeshSection(PrimitiveType, ColorCode, Map.Texture);
mSections.Add(Section);
Sections.Add(Section);
}
int QuadIndices[4] = { 0, 1, 2, 3 };
@ -1660,10 +1866,11 @@ void lcLibraryMeshData::AddTexturedLine(int LineType, lcuint32 ColorCode, const
const lcVector3& Position = Vertices[QuadIndices[IndexIdx]];
lcVector2 TexCoord(lcDot3(lcVector3(Position.x, Position.y, Position.z), Map.Params[0]) + Map.Params[0].w,
lcDot3(lcVector3(Position.x, Position.y, Position.z), Map.Params[1]) + Map.Params[1].w);
lcArray<lcVertexTextured>& VertexArray = mTexturedVertices[MeshDataType];
for (int VertexIdx = mTexturedVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--)
for (int VertexIdx = VertexArray.GetSize() - 1; VertexIdx >= 0; VertexIdx--)
{
lcVertexTextured& DstVertex = mTexturedVertices[VertexIdx];
lcVertexTextured& DstVertex = VertexArray[VertexIdx];
if (Position == DstVertex.Position && TexCoord == DstVertex.TexCoord)
{
@ -1674,8 +1881,8 @@ void lcLibraryMeshData::AddTexturedLine(int LineType, lcuint32 ColorCode, const
if (Indices[IndexIdx] == -1)
{
Indices[IndexIdx] = mTexturedVertices.GetSize();
lcVertexTextured& DstVertex = mTexturedVertices.Add();
Indices[IndexIdx] = VertexArray.GetSize();
lcVertexTextured& DstVertex = VertexArray.Add();
DstVertex.Position = Position;
DstVertex.TexCoord = TexCoord;
}
@ -1708,26 +1915,33 @@ void lcLibraryMeshData::AddTexturedLine(int LineType, lcuint32 ColorCode, const
}
}
void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap)
void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex)
{
int VertexCount = Data.mVertices.GetSize();
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
{
int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex;
const lcArray<lcVertex>& DataVertices = Data.mVertices[MeshDataIdx];
lcArray<lcVertex>& Vertices = mVertices[DestIndex];
lcArray<lcVertexTextured>& TexturedVertices = mTexturedVertices[DestIndex];
int VertexCount = DataVertices.GetSize();
lcArray<lcuint32> IndexRemap(VertexCount);
const float DistanceEpsilon = 0.05f;
if (!TextureMap)
{
mVertices.AllocGrow(VertexCount);
Vertices.AllocGrow(VertexCount);
for (int SrcVertexIdx = 0; SrcVertexIdx < VertexCount; SrcVertexIdx++)
{
lcVector3 Position = lcMul31(Data.mVertices[SrcVertexIdx].Position, Transform);
lcVector3 Position = lcMul31(DataVertices[SrcVertexIdx].Position, Transform);
int Index = -1;
for (int DstVertexIdx = mVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--)
for (int DstVertexIdx = Vertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--)
{
lcVertex& DstVertex = mVertices[DstVertexIdx];
lcVertex& DstVertex = Vertices[DstVertexIdx];
// if (Vertex == mVertices[DstVertexIdx])
// if (Vertex == Vertices[DstVertexIdx])
if (fabsf(Position.x - DstVertex.Position.x) < DistanceEpsilon && fabsf(Position.y - DstVertex.Position.y) < DistanceEpsilon && fabsf(Position.z - DstVertex.Position.z) < DistanceEpsilon)
{
Index = DstVertexIdx;
@ -1737,8 +1951,8 @@ void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatri
if (Index == -1)
{
Index = mVertices.GetSize();
lcVertex& DstVertex = mVertices.Add();
Index = Vertices.GetSize();
lcVertex& DstVertex = Vertices.Add();
DstVertex.Position = Position;
}
@ -1747,21 +1961,21 @@ void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatri
}
else
{
mTexturedVertices.AllocGrow(VertexCount);
TexturedVertices.AllocGrow(VertexCount);
for (int SrcVertexIdx = 0; SrcVertexIdx < VertexCount; SrcVertexIdx++)
{
lcVertex& SrcVertex = Data.mVertices[SrcVertexIdx];
lcVertex& SrcVertex = DataVertices[SrcVertexIdx];
lcVector3 Position = lcMul31(SrcVertex.Position, Transform);
lcVector2 TexCoord(lcDot3(lcVector3(Position.x, Position.y, Position.z), TextureMap->Params[0]) + TextureMap->Params[0].w,
lcDot3(lcVector3(Position.x, Position.y, Position.z), TextureMap->Params[1]) + TextureMap->Params[1].w);
int Index = -1;
for (int DstVertexIdx = mTexturedVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--)
for (int DstVertexIdx = TexturedVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--)
{
lcVertexTextured& DstVertex = mTexturedVertices[DstVertexIdx];
lcVertexTextured& DstVertex = TexturedVertices[DstVertexIdx];
// if (Vertex == mTexturedVertices[DstVertexIdx])
// if (Vertex == mTexturedVertices[DstVertexIdx])
if (fabsf(Position.x - DstVertex.Position.x) < DistanceEpsilon && fabsf(Position.y - DstVertex.Position.y) < DistanceEpsilon && fabsf(Position.z - DstVertex.Position.z) < DistanceEpsilon &&
fabsf(TexCoord.x - DstVertex.TexCoord.x) < 0.01f && fabsf(TexCoord.y - DstVertex.TexCoord.y) < 0.01f)
{
@ -1772,8 +1986,8 @@ void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatri
if (Index == -1)
{
Index = mTexturedVertices.GetSize();
lcVertexTextured& DstVertex = mTexturedVertices.Add();
Index = TexturedVertices.GetSize();
lcVertexTextured& DstVertex = TexturedVertices.Add();
DstVertex.Position = Position;
DstVertex.TexCoord = TexCoord;
}
@ -1782,24 +1996,25 @@ void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatri
}
}
int TexturedVertexCount = Data.mTexturedVertices.GetSize();
const lcArray<lcVertexTextured>& DataTexturedVertices = Data.mTexturedVertices[MeshDataIdx];
int TexturedVertexCount = DataTexturedVertices.GetSize();
lcArray<lcuint32> TexturedIndexRemap(TexturedVertexCount);
if (TexturedVertexCount)
{
mTexturedVertices.AllocGrow(TexturedVertexCount);
TexturedVertices.AllocGrow(TexturedVertexCount);
for (int SrcVertexIdx = 0; SrcVertexIdx < TexturedVertexCount; SrcVertexIdx++)
{
lcVertexTextured& SrcVertex = Data.mTexturedVertices[SrcVertexIdx];
lcVertexTextured& SrcVertex = DataTexturedVertices[SrcVertexIdx];
lcVector3 Position = lcMul31(SrcVertex.Position, Transform);
int Index = -1;
for (int DstVertexIdx = mTexturedVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--)
for (int DstVertexIdx = TexturedVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--)
{
lcVertexTextured& DstVertex = mTexturedVertices[DstVertexIdx];
lcVertexTextured& DstVertex = TexturedVertices[DstVertexIdx];
// if (Vertex == mTexturedVertices[DstVertexIdx])
// if (Vertex == mTexturedVertices[DstVertexIdx])
if (fabsf(Position.x - DstVertex.Position.x) < 0.1f && fabsf(Position.y - DstVertex.Position.y) < 0.1f && fabsf(Position.z - DstVertex.Position.z) < 0.1f &&
fabsf(SrcVertex.TexCoord.x - DstVertex.TexCoord.x) < 0.01f && fabsf(SrcVertex.TexCoord.y - DstVertex.TexCoord.y) < 0.01f)
{
@ -1810,8 +2025,8 @@ void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatri
if (Index == -1)
{
Index = mTexturedVertices.GetSize();
lcVertexTextured& DstVertex = mTexturedVertices.Add();
Index = TexturedVertices.GetSize();
lcVertexTextured& DstVertex = TexturedVertices.Add();
DstVertex.Position = Position;
DstVertex.TexCoord = SrcVertex.TexCoord;
}
@ -1820,9 +2035,12 @@ void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatri
}
}
for (int SrcSectionIdx = 0; SrcSectionIdx < Data.mSections.GetSize(); SrcSectionIdx++)
const lcArray<lcLibraryMeshSection*>& DataSections = Data.mSections[MeshDataIdx];
lcArray<lcLibraryMeshSection*>& Sections = mSections[DestIndex];
for (int SrcSectionIdx = 0; SrcSectionIdx < DataSections.GetSize(); SrcSectionIdx++)
{
lcLibraryMeshSection* SrcSection = Data.mSections[SrcSectionIdx];
lcLibraryMeshSection* SrcSection = DataSections[SrcSectionIdx];
lcLibraryMeshSection* DstSection = NULL;
lcuint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor;
lcTexture* Texture;
@ -1834,9 +2052,9 @@ void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatri
else
Texture = NULL;
for (int DstSectionIdx = 0; DstSectionIdx < mSections.GetSize(); DstSectionIdx++)
for (int DstSectionIdx = 0; DstSectionIdx < Sections.GetSize(); DstSectionIdx++)
{
lcLibraryMeshSection* Section = mSections[DstSectionIdx];
lcLibraryMeshSection* Section = Sections[DstSectionIdx];
if (Section->mColor == ColorCode && Section->mPrimitiveType == SrcSection->mPrimitiveType && Section->mTexture == Texture)
{
@ -1849,7 +2067,7 @@ void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatri
{
DstSection = new lcLibraryMeshSection(SrcSection->mPrimitiveType, ColorCode, Texture);
mSections.Add(DstSection);
Sections.Add(DstSection);
}
DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize());
@ -1865,34 +2083,41 @@ void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatri
DstSection->mIndices.Add(TexturedIndexRemap[SrcSection->mIndices[IndexIdx]]);
}
}
}
}
void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap)
void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex)
{
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
{
int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex;
const lcArray<lcVertex>& DataVertices = Data.mVertices[MeshDataIdx];
lcArray<lcVertex>& Vertices = mVertices[DestIndex];
lcArray<lcVertexTextured>& TexturedVertices = mTexturedVertices[DestIndex];
lcuint32 BaseIndex;
if (!TextureMap)
{
BaseIndex = mVertices.GetSize();
BaseIndex = Vertices.GetSize();
mVertices.AllocGrow(Data.mVertices.GetSize());
Vertices.AllocGrow(DataVertices.GetSize());
for (int SrcVertexIdx = 0; SrcVertexIdx < Data.mVertices.GetSize(); SrcVertexIdx++)
for (int SrcVertexIdx = 0; SrcVertexIdx < DataVertices.GetSize(); SrcVertexIdx++)
{
lcVertex& Vertex = mVertices.Add();
Vertex.Position = lcMul31(Data.mVertices[SrcVertexIdx].Position, Transform);
lcVertex& Vertex = Vertices.Add();
Vertex.Position = lcMul31(DataVertices[SrcVertexIdx].Position, Transform);
}
}
else
{
BaseIndex = mTexturedVertices.GetSize();
BaseIndex = TexturedVertices.GetSize();
mTexturedVertices.AllocGrow(Data.mVertices.GetSize());
TexturedVertices.AllocGrow(DataVertices.GetSize());
for (int SrcVertexIdx = 0; SrcVertexIdx < Data.mVertices.GetSize(); SrcVertexIdx++)
for (int SrcVertexIdx = 0; SrcVertexIdx < DataVertices.GetSize(); SrcVertexIdx++)
{
lcVertex& SrcVertex = Data.mVertices[SrcVertexIdx];
lcVertexTextured& DstVertex = mTexturedVertices.Add();
lcVertex& SrcVertex = DataVertices[SrcVertexIdx];
lcVertexTextured& DstVertex = TexturedVertices.Add();
lcVector3 Position = lcMul31(SrcVertex.Position, Transform);
lcVector2 TexCoord(lcDot3(lcVector3(Position.x, Position.y, Position.z), TextureMap->Params[0]) + TextureMap->Params[0].w,
@ -1903,25 +2128,30 @@ void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Dat
}
}
int TexturedVertexCount = Data.mTexturedVertices.GetSize();
lcuint32 BaseTexturedIndex = mTexturedVertices.GetSize();
const lcArray<lcVertexTextured>& DataTexturedVertices = Data.mTexturedVertices[MeshDataIdx];
int TexturedVertexCount = DataTexturedVertices.GetSize();
lcuint32 BaseTexturedIndex = TexturedVertices.GetSize();
if (TexturedVertexCount)
{
mTexturedVertices.AllocGrow(TexturedVertexCount);
TexturedVertices.AllocGrow(TexturedVertexCount);
for (int SrcVertexIdx = 0; SrcVertexIdx < TexturedVertexCount; SrcVertexIdx++)
{
lcVertexTextured& SrcVertex = Data.mTexturedVertices[SrcVertexIdx];
lcVertexTextured& DstVertex = mTexturedVertices.Add();
lcVertexTextured& SrcVertex = DataTexturedVertices[SrcVertexIdx];
lcVertexTextured& DstVertex = TexturedVertices.Add();
DstVertex.Position = lcMul31(SrcVertex.Position, Transform);
DstVertex.TexCoord = SrcVertex.TexCoord;
}
}
for (int SrcSectionIdx = 0; SrcSectionIdx < Data.mSections.GetSize(); SrcSectionIdx++)
const lcArray<lcLibraryMeshSection*>& DataSections = Data.mSections[MeshDataIdx];
lcArray<lcLibraryMeshSection*>& Sections = mSections[DestIndex];
for (int SrcSectionIdx = 0; SrcSectionIdx < DataSections.GetSize(); SrcSectionIdx++)
{
lcLibraryMeshSection* SrcSection = Data.mSections[SrcSectionIdx];
lcLibraryMeshSection* SrcSection = DataSections[SrcSectionIdx];
lcLibraryMeshSection* DstSection = NULL;
lcuint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor;
lcTexture* Texture;
@ -1933,9 +2163,9 @@ void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Dat
else
Texture = NULL;
for (int DstSectionIdx = 0; DstSectionIdx < mSections.GetSize(); DstSectionIdx++)
for (int DstSectionIdx = 0; DstSectionIdx < Sections.GetSize(); DstSectionIdx++)
{
lcLibraryMeshSection* Section = mSections[DstSectionIdx];
lcLibraryMeshSection* Section = Sections[DstSectionIdx];
if (Section->mColor == ColorCode && Section->mPrimitiveType == SrcSection->mPrimitiveType && Section->mTexture == Texture)
{
@ -1948,7 +2178,7 @@ void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Dat
{
DstSection = new lcLibraryMeshSection(SrcSection->mPrimitiveType, ColorCode, Texture);
mSections.Add(DstSection);
Sections.Add(DstSection);
}
DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize());
@ -1964,6 +2194,7 @@ void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Dat
DstSection->mIndices.Add(BaseTexturedIndex + SrcSection->mIndices[IndexIdx]);
}
}
}
}
bool lcPiecesLibrary::PieceInCategory(PieceInfo* Info, const String& CategoryKeywords) const

View file

@ -55,30 +55,39 @@ struct lcLibraryTextureMap
bool Next;
};
enum lcMeshDataType
{
LC_MESHDATA_HIGH,
LC_MESHDATA_LOW,
LC_MESHDATA_SHARED,
LC_NUM_MESHDATA_TYPES
};
class lcLibraryMeshData
{
public:
lcLibraryMeshData()
: mVertices(1024, 1024)
{
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
mVertices[MeshDataIdx].SetGrow(1024);
}
~lcLibraryMeshData()
{
for (int SectionIdx = 0; SectionIdx < mSections.GetSize(); SectionIdx++)
delete mSections[SectionIdx];
for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++)
mSections[MeshDataIdx].DeleteAll();
}
void AddLine(int LineType, lcuint32 ColorCode, const lcVector3* Vertices);
void AddTexturedLine(int LineType, lcuint32 ColorCode, const lcLibraryTextureMap& Map, const lcVector3* Vertices);
void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap);
void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap);
void AddLine(lcMeshDataType MeshDataType, int LineType, lcuint32 ColorCode, const lcVector3* Vertices);
void AddTexturedLine(lcMeshDataType MeshDataType, int LineType, lcuint32 ColorCode, const lcLibraryTextureMap& Map, const lcVector3* Vertices);
void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex);
void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, lcuint32 CurrentColorCode, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex);
void TestQuad(int* QuadIndices, const lcVector3* Vertices);
void ResequenceQuad(int* QuadIndices, int a, int b, int c, int d);
lcArray<lcLibraryMeshSection*> mSections;
lcArray<lcVertex> mVertices;
lcArray<lcVertexTextured> mTexturedVertices;
lcArray<lcLibraryMeshSection*> mSections[LC_NUM_MESHDATA_TYPES];
lcArray<lcVertex> mVertices[LC_NUM_MESHDATA_TYPES];
lcArray<lcVertexTextured> mTexturedVertices[LC_NUM_MESHDATA_TYPES];
};
class lcLibraryPrimitive
@ -149,7 +158,7 @@ public:
mNumOfficialPieces = mPieces.GetSize();
}
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData);
bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray<lcLibraryTextureMap>& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType);
void CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData);
void UpdateBuffers(lcContext* Context);

View file

@ -11,8 +11,12 @@ lcMesh* gPlaceholderMesh;
lcMesh::lcMesh()
{
mSections = NULL;
mNumSections = 0;
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
{
mLods[LodIdx].Sections = NULL;
mLods[LodIdx].NumSections = 0;
}
mNumVertices = 0;
mNumTexturedVertices = 0;
mIndexType = 0;
@ -28,13 +32,18 @@ lcMesh::~lcMesh()
{
free(mVertexData);
free(mIndexData);
delete[] mSections;
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
delete[] mLods[LodIdx].Sections;
}
void lcMesh::Create(int NumSections, int NumVertices, int NumTexturedVertices, int NumIndices)
void lcMesh::Create(lcuint16 NumSections[LC_NUM_MESH_LODS], int NumVertices, int NumTexturedVertices, int NumIndices)
{
mSections = new lcMeshSection[NumSections];
mNumSections = NumSections;
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
{
if (NumSections[LodIdx])
mLods[LodIdx].Sections = new lcMeshSection[NumSections[LodIdx]];
mLods[LodIdx].NumSections = NumSections[LodIdx];
}
mNumVertices = NumVertices;
mNumTexturedVertices = NumTexturedVertices;
@ -57,10 +66,15 @@ void lcMesh::Create(int NumSections, int NumVertices, int NumTexturedVertices, i
void lcMesh::CreateBox()
{
Create(2, 8, 0, 36 + 24);
lcuint16 NumSections[LC_NUM_MESH_LODS];
memset(NumSections, 0, sizeof(NumSections));
NumSections[LC_MESH_LOD_HIGH] = 2;
Create(NumSections, 8, 0, 36 + 24);
lcVector3 Min(-10.0f, -10.0f, -24.0f);
lcVector3 Max(10.0f, 10.0f, 4.0f);
mRadius = lcLength((Max - Min) / 2.0f);
float* Verts = (float*)mVertexData;
lcuint16* Indices = (lcuint16*)mIndexData;
@ -74,7 +88,7 @@ void lcMesh::CreateBox()
*Verts++ = Max[0]; *Verts++ = Max[1]; *Verts++ = Max[2];
*Verts++ = Max[0]; *Verts++ = Min[1]; *Verts++ = Max[2];
lcMeshSection* Section = &mSections[0];
lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[0];
Section->ColorIndex = gDefaultColor;
Section->IndexOffset = 0;
Section->NumIndices = 36;
@ -99,7 +113,7 @@ void lcMesh::CreateBox()
*Indices++ = 1; *Indices++ = 2; *Indices++ = 6;
*Indices++ = 1; *Indices++ = 6; *Indices++ = 5;
Section = &mSections[1];
Section = &mLods[LC_MESH_LOD_HIGH].Sections[1];
Section->ColorIndex = gEdgeColor;
Section->IndexOffset = 36 * 2;
Section->NumIndices = 24;
@ -122,9 +136,9 @@ bool lcMesh::MinIntersectDist(const lcVector3& Start, const lcVector3& End, floa
float* Verts = (float*)mVertexData;
bool Hit = false;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
@ -161,9 +175,9 @@ bool lcMesh::IntersectsPlanes(const lcVector4 Planes[6])
{
float* Verts = (float*)mVertexData;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
@ -196,9 +210,9 @@ void lcMesh::ExportPOVRay(lcFile& File, const char* MeshName, const char* ColorT
float* Verts = (float*)mVertexData;
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
@ -239,9 +253,9 @@ void lcMesh::ExportWavefrontIndices(lcFile& File, int DefaultColorIndex, int Ver
{
char Line[1024];
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
for (int SectionIdx = 0; SectionIdx < mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{
lcMeshSection* Section = &mSections[SectionIdx];
lcMeshSection* Section = &mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
@ -283,16 +297,21 @@ bool lcMesh::FileLoad(lcFile& File)
return false;
lcuint32 NumVertices, NumTexturedVertices, NumIndices;
lcuint16 NumSections;
lcuint16 NumLods, NumSections[LC_NUM_MESH_LODS];
if (!File.ReadU16(&NumSections, 1) || !File.ReadU32(&NumVertices, 1) || !File.ReadU32(&NumTexturedVertices, 1) || !File.ReadU32(&NumIndices, 1))
if (!File.ReadU32(&NumVertices, 1) || !File.ReadU32(&NumTexturedVertices, 1) || !File.ReadU32(&NumIndices, 1))
return false;
if (!File.ReadU16(&NumLods, 1) || NumLods != LC_NUM_MESH_LODS || !File.ReadU16(NumSections, LC_NUM_MESH_LODS))
return false;
Create(NumSections, NumVertices, NumTexturedVertices, NumIndices);
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
{
lcMeshSection& Section = mSections[SectionIdx];
for (int SectionIdx = 0; SectionIdx < mLods[LodIdx].NumSections; SectionIdx++)
{
lcMeshSection& Section = mLods[LodIdx].Sections[SectionIdx];
lcuint32 ColorCode, IndexOffset;
lcuint16 Triangles, Length;
@ -323,6 +342,7 @@ bool lcMesh::FileLoad(lcFile& File)
else
Section.Texture = NULL;
}
}
File.ReadFloats((float*)mVertexData, 3 * mNumVertices + 5 * mNumTexturedVertices);
if (mIndexType == GL_UNSIGNED_SHORT)
@ -339,14 +359,19 @@ void lcMesh::FileSave(lcFile& File)
File.WriteU32(LC_MESH_FILE_ID);
File.WriteU32(LC_MESH_FILE_VERSION);
File.WriteU16(mNumSections);
File.WriteU32(mNumVertices);
File.WriteU32(mNumTexturedVertices);
File.WriteU32(mIndexDataSize / (mIndexType == GL_UNSIGNED_SHORT ? 2 : 4));
for (int SectionIdx = 0; SectionIdx < mNumSections; SectionIdx++)
File.WriteU16(LC_NUM_MESH_LODS);
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
File.WriteU16(mLods[LodIdx].NumSections);
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
{
lcMeshSection& Section = mSections[SectionIdx];
for (int SectionIdx = 0; SectionIdx < mLods[LodIdx].NumSections; SectionIdx++)
{
lcMeshSection& Section = mLods[LodIdx].Sections[SectionIdx];
File.WriteU32(lcGetColorCode(Section.ColorIndex));
File.WriteU32(Section.IndexOffset);
@ -362,6 +387,7 @@ void lcMesh::FileSave(lcFile& File)
else
File.WriteU16(0);
}
}
File.WriteFloats((float*)mVertexData, 3 * mNumVertices + 5 * mNumTexturedVertices);
if (mIndexType == GL_UNSIGNED_SHORT)
@ -369,3 +395,11 @@ void lcMesh::FileSave(lcFile& File)
else
File.WriteU32((lcuint32*)mIndexData, mIndexDataSize / 4);
}
int lcMesh::GetLodIndex(float Distance) const
{
if (mLods[LC_MESH_LOD_LOW].NumSections && (Distance - mRadius) > 250.0f)
return LC_MESH_LOD_LOW;
else
return LC_MESH_LOD_HIGH;
}

View file

@ -5,7 +5,7 @@
#include "lc_math.h"
#define LC_MESH_FILE_ID LC_FOURCC('M', 'E', 'S', 'H')
#define LC_MESH_FILE_VERSION 0x0100
#define LC_MESH_FILE_VERSION 0x0110
struct lcVertex
{
@ -27,13 +27,26 @@ struct lcMeshSection
lcTexture* Texture;
};
struct lcMeshLod
{
lcMeshSection* Sections;
int NumSections;
};
enum
{
LC_MESH_LOD_HIGH,
LC_MESH_LOD_LOW,
LC_NUM_MESH_LODS
};
class lcMesh
{
public:
lcMesh();
~lcMesh();
void Create(int NumSections, int NumVertices, int NumTexturedVertices, int NumIndices);
void Create(lcuint16 NumSections[LC_NUM_MESH_LODS], int NumVertices, int NumTexturedVertices, int NumIndices);
void CreateBox();
bool FileLoad(lcFile& File);
@ -55,8 +68,10 @@ public:
bool IntersectsPlanes(const lcVector4 Planes[6]);
bool IntersectsPlanes(const lcVector4 Planes[6]);
lcMeshSection* mSections;
int mNumSections;
int GetLodIndex(float Distance) const;
lcMeshLod mLods[LC_NUM_MESH_LODS];
float mRadius;
void* mVertexData;
int mVertexDataSize;
@ -83,6 +98,7 @@ struct lcRenderMesh
lcMesh* Mesh;
float Distance;
int ColorIndex;
int LodIndex;
lcRenderMeshState State;
};

View file

@ -82,7 +82,7 @@ void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh)
PieceFile.Seek(0, SEEK_SET);
const char* OldLocale = setlocale(LC_NUMERIC, "C");
bool Ret = lcGetPiecesLibrary()->ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData);
bool Ret = lcGetPiecesLibrary()->ReadMeshData(PieceFile, lcMatrix44Identity(), 16, TextureStack, MeshData, LC_MESHDATA_SHARED);
setlocale(LC_NUMERIC, OldLocale);
if (Ret)
@ -127,13 +127,16 @@ void PieceInfo::Unload()
{
if (mMesh)
{
for (int SectionIdx = 0; SectionIdx < mMesh->mNumSections; SectionIdx++)
for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++)
{
lcMeshSection& Section = mMesh->mSections[SectionIdx];
for (int SectionIdx = 0; SectionIdx < mMesh->mLods[LodIdx].NumSections; SectionIdx++)
{
lcMeshSection& Section = mMesh->mLods[LodIdx].Sections[SectionIdx];
if (Section.Texture)
Section.Texture->Release();
}
}
delete mMesh;
mMesh = NULL;
@ -287,16 +290,14 @@ void PieceInfo::AddRenderMesh(lcScene& Scene)
RenderMesh.Mesh = mMesh;
RenderMesh.ColorIndex = gDefaultColor;
RenderMesh.State = LC_RENDERMESH_NONE;
RenderMesh.Distance = fabsf(Scene.mViewMatrix.r[3].z);
RenderMesh.LodIndex = mMesh->GetLodIndex(RenderMesh.Distance);
if (mFlags & (LC_PIECE_HAS_SOLID | LC_PIECE_HAS_DEFAULT | LC_PIECE_HAS_LINES))
Scene.mOpaqueMeshes.Add(RenderMesh);
if (mFlags & LC_PIECE_HAS_TRANSLUCENT)
{
RenderMesh.Distance = Scene.mViewMatrix.r[3].z;
Scene.mTranslucentMeshes.Add(RenderMesh);
}
}
void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, int ColorIndex, bool Focused, bool Selected)
@ -309,6 +310,8 @@ void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, i
RenderMesh.Mesh = (mFlags & LC_PIECE_PLACEHOLDER) ? gPlaceholderMesh : mMesh;
RenderMesh.ColorIndex = ColorIndex;
RenderMesh.State = Focused ? LC_RENDERMESH_FOCUSED : (Selected ? LC_RENDERMESH_SELECTED : LC_RENDERMESH_NONE);
RenderMesh.Distance = fabsf(lcMul31(WorldMatrix[3], Scene.mViewMatrix).z);
RenderMesh.LodIndex = mMesh->GetLodIndex(RenderMesh.Distance);
bool Translucent = lcIsColorTranslucent(ColorIndex);
@ -316,14 +319,8 @@ void PieceInfo::AddRenderMeshes(lcScene& Scene, const lcMatrix44& WorldMatrix, i
Scene.mOpaqueMeshes.Add(RenderMesh);
if ((mFlags & LC_PIECE_HAS_TRANSLUCENT) || ((mFlags & LC_PIECE_HAS_DEFAULT) && Translucent))
{
lcVector3 Pos = lcMul31(WorldMatrix[3], Scene.mViewMatrix);
RenderMesh.Distance = Pos[2];
Scene.mTranslucentMeshes.Add(RenderMesh);
}
}
if (mFlags & LC_PIECE_MODEL)
mModel->SubModelAddRenderMeshes(Scene, WorldMatrix, ColorIndex, Focused, Selected);

View file

@ -765,9 +765,9 @@ void Project::Export3DStudio(const QString& FileName)
int NumTriangles = 0;
for (int SectionIdx = 0; SectionIdx < Mesh->mNumSections; SectionIdx++)
for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{
lcMeshSection* Section = &Mesh->mSections[SectionIdx];
lcMeshSection* Section = &Mesh->mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
@ -777,9 +777,9 @@ void Project::Export3DStudio(const QString& FileName)
File.WriteU16(NumTriangles);
for (int SectionIdx = 0; SectionIdx < Mesh->mNumSections; SectionIdx++)
for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{
lcMeshSection* Section = &Mesh->mSections[SectionIdx];
lcMeshSection* Section = &Mesh->mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;
@ -797,9 +797,9 @@ void Project::Export3DStudio(const QString& FileName)
NumTriangles = 0;
for (int SectionIdx = 0; SectionIdx < Mesh->mNumSections; SectionIdx++)
for (int SectionIdx = 0; SectionIdx < Mesh->mLods[LC_MESH_LOD_HIGH].NumSections; SectionIdx++)
{
lcMeshSection* Section = &Mesh->mSections[SectionIdx];
lcMeshSection* Section = &Mesh->mLods[LC_MESH_LOD_HIGH].Sections[SectionIdx];
if (Section->PrimitiveType != GL_TRIANGLES)
continue;