diff --git a/common/lc_array.h b/common/lc_array.h index 03af47cc..80d52d6a 100644 --- a/common/lc_array.h +++ b/common/lc_array.h @@ -78,6 +78,11 @@ public: mLength = NewSize; } + void SetGrow(int Grow) + { + mGrow = Grow; + } + void AllocGrow(int Grow) { if ((mLength + Grow) > mAlloc) diff --git a/common/lc_context.cpp b/common/lc_context.cpp index 0de9b37d..8a2a48cb 100644 --- a/common/lc_context.cpp +++ b/common/lc_context.cpp @@ -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& 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& 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) diff --git a/common/lc_library.cpp b/common/lc_library.cpp index f598b80f..67ed9495 100644 --- a/common/lc_library.cpp +++ b/common/lc_library.cpp @@ -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,59 +917,130 @@ 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& Sections = MeshData.mSections[MeshDataIdx]; - Section->mColor = lcGetColorIndex(Section->mColor); - NumIndices += Section->mIndices.GetSize(); + for (int SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++) + { + lcLibraryMeshSection* Section = Sections[SectionIdx]; + Section->mColor = lcGetColorIndex(Section->mColor); + } + + BaseVertices[MeshDataIdx] = NumVertices; + NumVertices += MeshData.mVertices[MeshDataIdx].GetSize(); + BaseTexturedVertices[MeshDataIdx] = NumTexturedVertices; + NumTexturedVertices += MeshData.mTexturedVertices[MeshDataIdx].GetSize(); } - MeshData.mSections.Sort(LibraryMeshSectionCompare); + lcuint16 NumSections[LC_NUM_MESH_LODS]; + int NumIndices = 0; - Mesh->Create(MeshData.mSections.GetSize(), MeshData.mVertices.GetSize(), MeshData.mTexturedVertices.GetSize(), NumIndices); + lcArray MergeSections[LC_NUM_MESH_LODS]; + + for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) + { + const lcArray& SharedSections = MeshData.mSections[LC_MESHDATA_SHARED]; + const lcArray& 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++) { - lcVertex& DstVertex = *DstVerts++; + const lcArray& Vertices = MeshData.mVertices[MeshDataIdx]; - const lcVector3& SrcPosition = MeshData.mVertices[VertexIdx].Position; - lcVector3& DstPosition = DstVertex.Position; + for (int VertexIdx = 0; VertexIdx < Vertices.GetSize(); VertexIdx++) + { + lcVertex& DstVertex = *DstVerts++; - DstPosition = lcVector3(SrcPosition.x, SrcPosition.z, -SrcPosition.y); + const lcVector3& SrcPosition = Vertices[VertexIdx].Position; + lcVector3& DstPosition = DstVertex.Position; - Min.x = lcMin(Min.x, DstPosition.x); - Min.y = lcMin(Min.y, DstPosition.y); - Min.z = lcMin(Min.z, DstPosition.z); - Max.x = lcMax(Max.x, DstPosition.x); - Max.y = lcMax(Max.y, DstPosition.y); - Max.z = lcMax(Max.z, DstPosition.z); + DstPosition = lcVector3(SrcPosition.x, SrcPosition.z, -SrcPosition.y); + + Min.x = lcMin(Min.x, DstPosition.x); + Min.y = lcMin(Min.y, DstPosition.y); + Min.z = lcMin(Min.z, DstPosition.z); + Max.x = lcMax(Max.x, DstPosition.x); + 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++) { - lcVertexTextured& DstVertex = *DstTexturedVerts++; - lcVertexTextured& SrcVertex = MeshData.mTexturedVertices[VertexIdx]; + const lcArray& TexturedVertices = MeshData.mTexturedVertices[MeshDataIdx]; - const lcVector3& SrcPosition = SrcVertex.Position; - lcVector3& DstPosition = DstVertex.Position; + for (int VertexIdx = 0; VertexIdx < TexturedVertices.GetSize(); VertexIdx++) + { + lcVertexTextured& DstVertex = *DstTexturedVerts++; + lcVertexTextured& SrcVertex = TexturedVertices[VertexIdx]; - DstPosition = lcVector3(SrcPosition.x, SrcPosition.z, -SrcPosition.y); - DstVertex.TexCoord = SrcVertex.TexCoord; + const lcVector3& SrcPosition = SrcVertex.Position; + lcVector3& DstPosition = DstVertex.Position; - Min.x = lcMin(Min.x, DstPosition.x); - Min.y = lcMin(Min.y, DstPosition.y); - Min.z = lcMin(Min.z, DstPosition.z); - Max.x = lcMax(Max.x, DstPosition.x); - Max.y = lcMax(Max.y, DstPosition.y); - Max.z = lcMax(Max.z, DstPosition.z); + DstPosition = lcVector3(SrcPosition.x, SrcPosition.z, -SrcPosition.y); + DstVertex.TexCoord = SrcVertex.TexCoord; + + Min.x = lcMin(Min.x, DstPosition.x); + Min.y = lcMin(Min.y, DstPosition.y); + Min.z = lcMin(Min.z, DstPosition.z); + Max.x = lcMax(Max.x, DstPosition.x); + Max.y = lcMax(Max.y, DstPosition.y); + Max.z = lcMax(Max.z, DstPosition.z); + } } Info->m_fDimensions[0] = Max.x; @@ -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,13 +1304,42 @@ 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)) - return false; + 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 { @@ -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& TextureStack, lcLibraryMeshData& MeshData) +bool lcPiecesLibrary::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray& 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& 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& 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& 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& 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,260 +1915,284 @@ 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(); - lcArray IndexRemap(VertexCount); - const float DistanceEpsilon = 0.05f; - - if (!TextureMap) + for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) { - mVertices.AllocGrow(VertexCount); + int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex; + const lcArray& DataVertices = Data.mVertices[MeshDataIdx]; + lcArray& Vertices = mVertices[DestIndex]; + lcArray& TexturedVertices = mTexturedVertices[DestIndex]; - for (int SrcVertexIdx = 0; SrcVertexIdx < VertexCount; SrcVertexIdx++) + int VertexCount = DataVertices.GetSize(); + lcArray IndexRemap(VertexCount); + const float DistanceEpsilon = 0.05f; + + if (!TextureMap) { - lcVector3 Position = lcMul31(Data.mVertices[SrcVertexIdx].Position, Transform); - int Index = -1; + Vertices.AllocGrow(VertexCount); - for (int DstVertexIdx = mVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--) + for (int SrcVertexIdx = 0; SrcVertexIdx < VertexCount; SrcVertexIdx++) { - lcVertex& DstVertex = mVertices[DstVertexIdx]; + lcVector3 Position = lcMul31(DataVertices[SrcVertexIdx].Position, Transform); + int Index = -1; -// if (Vertex == mVertices[DstVertexIdx]) - if (fabsf(Position.x - DstVertex.Position.x) < DistanceEpsilon && fabsf(Position.y - DstVertex.Position.y) < DistanceEpsilon && fabsf(Position.z - DstVertex.Position.z) < DistanceEpsilon) + for (int DstVertexIdx = Vertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--) { - Index = DstVertexIdx; - break; + lcVertex& DstVertex = Vertices[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; + break; + } } - } - if (Index == -1) - { - Index = mVertices.GetSize(); - lcVertex& DstVertex = mVertices.Add(); - DstVertex.Position = Position; - } - - IndexRemap.Add(Index); - } - } - else - { - mTexturedVertices.AllocGrow(VertexCount); - - for (int SrcVertexIdx = 0; SrcVertexIdx < VertexCount; SrcVertexIdx++) - { - lcVertex& SrcVertex = Data.mVertices[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--) - { - lcVertexTextured& DstVertex = 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) + if (Index == -1) { - Index = DstVertexIdx; - break; + Index = Vertices.GetSize(); + lcVertex& DstVertex = Vertices.Add(); + DstVertex.Position = Position; } + + IndexRemap.Add(Index); } - - if (Index == -1) - { - Index = mTexturedVertices.GetSize(); - lcVertexTextured& DstVertex = mTexturedVertices.Add(); - DstVertex.Position = Position; - DstVertex.TexCoord = TexCoord; - } - - IndexRemap.Add(Index); - } - } - - int TexturedVertexCount = Data.mTexturedVertices.GetSize(); - lcArray TexturedIndexRemap(TexturedVertexCount); - - if (TexturedVertexCount) - { - mTexturedVertices.AllocGrow(TexturedVertexCount); - - for (int SrcVertexIdx = 0; SrcVertexIdx < TexturedVertexCount; SrcVertexIdx++) - { - lcVertexTextured& SrcVertex = Data.mTexturedVertices[SrcVertexIdx]; - lcVector3 Position = lcMul31(SrcVertex.Position, Transform); - int Index = -1; - - for (int DstVertexIdx = mTexturedVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--) - { - lcVertexTextured& DstVertex = 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) - { - Index = DstVertexIdx; - break; - } - } - - if (Index == -1) - { - Index = mTexturedVertices.GetSize(); - lcVertexTextured& DstVertex = mTexturedVertices.Add(); - DstVertex.Position = Position; - DstVertex.TexCoord = SrcVertex.TexCoord; - } - - TexturedIndexRemap.Add(Index); - } - } - - for (int SrcSectionIdx = 0; SrcSectionIdx < Data.mSections.GetSize(); SrcSectionIdx++) - { - lcLibraryMeshSection* SrcSection = Data.mSections[SrcSectionIdx]; - lcLibraryMeshSection* DstSection = NULL; - lcuint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor; - lcTexture* Texture; - - if (SrcSection->mTexture) - Texture = SrcSection->mTexture; - else if (TextureMap) - Texture = TextureMap->Texture; - else - Texture = NULL; - - for (int DstSectionIdx = 0; DstSectionIdx < mSections.GetSize(); DstSectionIdx++) - { - lcLibraryMeshSection* Section = mSections[DstSectionIdx]; - - if (Section->mColor == ColorCode && Section->mPrimitiveType == SrcSection->mPrimitiveType && Section->mTexture == Texture) - { - DstSection = Section; - break; - } - } - - if (!DstSection) - { - DstSection = new lcLibraryMeshSection(SrcSection->mPrimitiveType, ColorCode, Texture); - - mSections.Add(DstSection); - } - - DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); - - if (!SrcSection->mTexture) - { - for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) - DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx]]); } else { - for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) - DstSection->mIndices.Add(TexturedIndexRemap[SrcSection->mIndices[IndexIdx]]); + TexturedVertices.AllocGrow(VertexCount); + + for (int SrcVertexIdx = 0; SrcVertexIdx < VertexCount; 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 = TexturedVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--) + { + lcVertexTextured& DstVertex = TexturedVertices[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) + { + Index = DstVertexIdx; + break; + } + } + + if (Index == -1) + { + Index = TexturedVertices.GetSize(); + lcVertexTextured& DstVertex = TexturedVertices.Add(); + DstVertex.Position = Position; + DstVertex.TexCoord = TexCoord; + } + + IndexRemap.Add(Index); + } + } + + const lcArray& DataTexturedVertices = Data.mTexturedVertices[MeshDataIdx]; + int TexturedVertexCount = DataTexturedVertices.GetSize(); + lcArray TexturedIndexRemap(TexturedVertexCount); + + if (TexturedVertexCount) + { + TexturedVertices.AllocGrow(TexturedVertexCount); + + for (int SrcVertexIdx = 0; SrcVertexIdx < TexturedVertexCount; SrcVertexIdx++) + { + lcVertexTextured& SrcVertex = DataTexturedVertices[SrcVertexIdx]; + lcVector3 Position = lcMul31(SrcVertex.Position, Transform); + int Index = -1; + + for (int DstVertexIdx = TexturedVertices.GetSize() - 1; DstVertexIdx >= 0; DstVertexIdx--) + { + lcVertexTextured& DstVertex = TexturedVertices[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) + { + Index = DstVertexIdx; + break; + } + } + + if (Index == -1) + { + Index = TexturedVertices.GetSize(); + lcVertexTextured& DstVertex = TexturedVertices.Add(); + DstVertex.Position = Position; + DstVertex.TexCoord = SrcVertex.TexCoord; + } + + TexturedIndexRemap.Add(Index); + } + } + + const lcArray& DataSections = Data.mSections[MeshDataIdx]; + lcArray& Sections = mSections[DestIndex]; + + for (int SrcSectionIdx = 0; SrcSectionIdx < DataSections.GetSize(); SrcSectionIdx++) + { + lcLibraryMeshSection* SrcSection = DataSections[SrcSectionIdx]; + lcLibraryMeshSection* DstSection = NULL; + lcuint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor; + lcTexture* Texture; + + if (SrcSection->mTexture) + Texture = SrcSection->mTexture; + else if (TextureMap) + Texture = TextureMap->Texture; + else + Texture = NULL; + + for (int DstSectionIdx = 0; DstSectionIdx < Sections.GetSize(); DstSectionIdx++) + { + lcLibraryMeshSection* Section = Sections[DstSectionIdx]; + + if (Section->mColor == ColorCode && Section->mPrimitiveType == SrcSection->mPrimitiveType && Section->mTexture == Texture) + { + DstSection = Section; + break; + } + } + + if (!DstSection) + { + DstSection = new lcLibraryMeshSection(SrcSection->mPrimitiveType, ColorCode, Texture); + + Sections.Add(DstSection); + } + + DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); + + if (!SrcSection->mTexture) + { + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx]]); + } + else + { + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + 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) { - lcuint32 BaseIndex; - - if (!TextureMap) + for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) { - BaseIndex = mVertices.GetSize(); + int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex; + const lcArray& DataVertices = Data.mVertices[MeshDataIdx]; + lcArray& Vertices = mVertices[DestIndex]; + lcArray& TexturedVertices = mTexturedVertices[DestIndex]; + lcuint32 BaseIndex; - mVertices.AllocGrow(Data.mVertices.GetSize()); - - for (int SrcVertexIdx = 0; SrcVertexIdx < Data.mVertices.GetSize(); SrcVertexIdx++) + if (!TextureMap) { - lcVertex& Vertex = mVertices.Add(); - Vertex.Position = lcMul31(Data.mVertices[SrcVertexIdx].Position, Transform); - } - } - else - { - BaseIndex = mTexturedVertices.GetSize(); + BaseIndex = Vertices.GetSize(); - mTexturedVertices.AllocGrow(Data.mVertices.GetSize()); + Vertices.AllocGrow(DataVertices.GetSize()); - for (int SrcVertexIdx = 0; SrcVertexIdx < Data.mVertices.GetSize(); SrcVertexIdx++) - { - lcVertex& SrcVertex = Data.mVertices[SrcVertexIdx]; - lcVertexTextured& DstVertex = mTexturedVertices.Add(); - - 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); - - DstVertex.Position = Position; - DstVertex.TexCoord = TexCoord; - } - } - - int TexturedVertexCount = Data.mTexturedVertices.GetSize(); - lcuint32 BaseTexturedIndex = mTexturedVertices.GetSize(); - - if (TexturedVertexCount) - { - mTexturedVertices.AllocGrow(TexturedVertexCount); - - for (int SrcVertexIdx = 0; SrcVertexIdx < TexturedVertexCount; SrcVertexIdx++) - { - lcVertexTextured& SrcVertex = Data.mTexturedVertices[SrcVertexIdx]; - lcVertexTextured& DstVertex = mTexturedVertices.Add(); - DstVertex.Position = lcMul31(SrcVertex.Position, Transform); - DstVertex.TexCoord = SrcVertex.TexCoord; - } - } - - for (int SrcSectionIdx = 0; SrcSectionIdx < Data.mSections.GetSize(); SrcSectionIdx++) - { - lcLibraryMeshSection* SrcSection = Data.mSections[SrcSectionIdx]; - lcLibraryMeshSection* DstSection = NULL; - lcuint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor; - lcTexture* Texture; - - if (SrcSection->mTexture) - Texture = SrcSection->mTexture; - else if (TextureMap) - Texture = TextureMap->Texture; - else - Texture = NULL; - - for (int DstSectionIdx = 0; DstSectionIdx < mSections.GetSize(); DstSectionIdx++) - { - lcLibraryMeshSection* Section = mSections[DstSectionIdx]; - - if (Section->mColor == ColorCode && Section->mPrimitiveType == SrcSection->mPrimitiveType && Section->mTexture == Texture) + for (int SrcVertexIdx = 0; SrcVertexIdx < DataVertices.GetSize(); SrcVertexIdx++) { - DstSection = Section; - break; + lcVertex& Vertex = Vertices.Add(); + Vertex.Position = lcMul31(DataVertices[SrcVertexIdx].Position, Transform); + } + } + else + { + BaseIndex = TexturedVertices.GetSize(); + + TexturedVertices.AllocGrow(DataVertices.GetSize()); + + for (int SrcVertexIdx = 0; SrcVertexIdx < DataVertices.GetSize(); SrcVertexIdx++) + { + 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, + lcDot3(lcVector3(Position.x, Position.y, Position.z), TextureMap->Params[1]) + TextureMap->Params[1].w); + + DstVertex.Position = Position; + DstVertex.TexCoord = TexCoord; } } - if (!DstSection) - { - DstSection = new lcLibraryMeshSection(SrcSection->mPrimitiveType, ColorCode, Texture); + const lcArray& DataTexturedVertices = Data.mTexturedVertices[MeshDataIdx]; - mSections.Add(DstSection); + int TexturedVertexCount = DataTexturedVertices.GetSize(); + lcuint32 BaseTexturedIndex = TexturedVertices.GetSize(); + + if (TexturedVertexCount) + { + TexturedVertices.AllocGrow(TexturedVertexCount); + + for (int SrcVertexIdx = 0; SrcVertexIdx < TexturedVertexCount; SrcVertexIdx++) + { + lcVertexTextured& SrcVertex = DataTexturedVertices[SrcVertexIdx]; + lcVertexTextured& DstVertex = TexturedVertices.Add(); + DstVertex.Position = lcMul31(SrcVertex.Position, Transform); + DstVertex.TexCoord = SrcVertex.TexCoord; + } } - DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); + const lcArray& DataSections = Data.mSections[MeshDataIdx]; + lcArray& Sections = mSections[DestIndex]; - if (!SrcSection->mTexture) + for (int SrcSectionIdx = 0; SrcSectionIdx < DataSections.GetSize(); SrcSectionIdx++) { - for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) - DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx]); - } - else - { - for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) - DstSection->mIndices.Add(BaseTexturedIndex + SrcSection->mIndices[IndexIdx]); + lcLibraryMeshSection* SrcSection = DataSections[SrcSectionIdx]; + lcLibraryMeshSection* DstSection = NULL; + lcuint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor; + lcTexture* Texture; + + if (SrcSection->mTexture) + Texture = SrcSection->mTexture; + else if (TextureMap) + Texture = TextureMap->Texture; + else + Texture = NULL; + + for (int DstSectionIdx = 0; DstSectionIdx < Sections.GetSize(); DstSectionIdx++) + { + lcLibraryMeshSection* Section = Sections[DstSectionIdx]; + + if (Section->mColor == ColorCode && Section->mPrimitiveType == SrcSection->mPrimitiveType && Section->mTexture == Texture) + { + DstSection = Section; + break; + } + } + + if (!DstSection) + { + DstSection = new lcLibraryMeshSection(SrcSection->mPrimitiveType, ColorCode, Texture); + + Sections.Add(DstSection); + } + + DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); + + if (!SrcSection->mTexture) + { + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx]); + } + else + { + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + DstSection->mIndices.Add(BaseTexturedIndex + SrcSection->mIndices[IndexIdx]); + } } } } diff --git a/common/lc_library.h b/common/lc_library.h index bce9a913..e5467d2d 100644 --- a/common/lc_library.h +++ b/common/lc_library.h @@ -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 mSections; - lcArray mVertices; - lcArray mTexturedVertices; + lcArray mSections[LC_NUM_MESHDATA_TYPES]; + lcArray mVertices[LC_NUM_MESHDATA_TYPES]; + lcArray 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& TextureStack, lcLibraryMeshData& MeshData); + bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, lcuint32 CurrentColorCode, lcArray& TextureStack, lcLibraryMeshData& MeshData, lcMeshDataType MeshDataType); void CreateMesh(PieceInfo* Info, lcLibraryMeshData& MeshData); void UpdateBuffers(lcContext* Context); diff --git a/common/lc_mesh.cpp b/common/lc_mesh.cpp index 24a98f66..3d972f2f 100644 --- a/common/lc_mesh.cpp +++ b/common/lc_mesh.cpp @@ -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,45 +297,51 @@ 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]; - - lcuint32 ColorCode, IndexOffset; - lcuint16 Triangles, Length; - - if (!File.ReadU32(&ColorCode, 1) || !File.ReadU32(&IndexOffset, 1) || !File.ReadU32(&NumIndices, 1) || !File.ReadU16(&Triangles, 1)) - return false; - - Section.ColorIndex = lcGetColorIndex(ColorCode); - Section.IndexOffset = IndexOffset; - Section.NumIndices = NumIndices; - Section.PrimitiveType = Triangles ? GL_TRIANGLES : GL_LINES; - - if (!File.ReadU16(&Length, 1)) - return false; - - if (Length) + for (int SectionIdx = 0; SectionIdx < mLods[LodIdx].NumSections; SectionIdx++) { - if (Length >= LC_TEXTURE_NAME_LEN) + lcMeshSection& Section = mLods[LodIdx].Sections[SectionIdx]; + + lcuint32 ColorCode, IndexOffset; + lcuint16 Triangles, Length; + + if (!File.ReadU32(&ColorCode, 1) || !File.ReadU32(&IndexOffset, 1) || !File.ReadU32(&NumIndices, 1) || !File.ReadU16(&Triangles, 1)) return false; - char FileName[LC_TEXTURE_NAME_LEN]; + Section.ColorIndex = lcGetColorIndex(ColorCode); + Section.IndexOffset = IndexOffset; + Section.NumIndices = NumIndices; + Section.PrimitiveType = Triangles ? GL_TRIANGLES : GL_LINES; - File.ReadBuffer(FileName, Length); - FileName[Length] = 0; + if (!File.ReadU16(&Length, 1)) + return false; - Section.Texture = lcGetPiecesLibrary()->FindTexture(FileName); + if (Length) + { + if (Length >= LC_TEXTURE_NAME_LEN) + return false; + + char FileName[LC_TEXTURE_NAME_LEN]; + + File.ReadBuffer(FileName, Length); + FileName[Length] = 0; + + Section.Texture = lcGetPiecesLibrary()->FindTexture(FileName); + } + else + Section.Texture = NULL; } - else - Section.Texture = NULL; } File.ReadFloats((float*)mVertexData, 3 * mNumVertices + 5 * mNumTexturedVertices); @@ -339,28 +359,34 @@ 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]; - - File.WriteU32(lcGetColorCode(Section.ColorIndex)); - File.WriteU32(Section.IndexOffset); - File.WriteU32(Section.NumIndices); - File.WriteU16(Section.PrimitiveType == GL_TRIANGLES ? 1 : 0); - - if (Section.Texture) + for (int SectionIdx = 0; SectionIdx < mLods[LodIdx].NumSections; SectionIdx++) { - int Length = strlen(Section.Texture->mName); - File.WriteU16(Length); - File.WriteBuffer(Section.Texture->mName, Length); + lcMeshSection& Section = mLods[LodIdx].Sections[SectionIdx]; + + File.WriteU32(lcGetColorCode(Section.ColorIndex)); + File.WriteU32(Section.IndexOffset); + File.WriteU32(Section.NumIndices); + File.WriteU16(Section.PrimitiveType == GL_TRIANGLES ? 1 : 0); + + if (Section.Texture) + { + int Length = strlen(Section.Texture->mName); + File.WriteU16(Length); + File.WriteBuffer(Section.Texture->mName, Length); + } + else + File.WriteU16(0); } - else - File.WriteU16(0); } File.WriteFloats((float*)mVertexData, 3 * mNumVertices + 5 * mNumTexturedVertices); @@ -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; +} diff --git a/common/lc_mesh.h b/common/lc_mesh.h index 4e38ca9c..218fd5b8 100644 --- a/common/lc_mesh.h +++ b/common/lc_mesh.h @@ -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; }; diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index 5576cd6a..521de3b4 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -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,12 +127,15 @@ 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(); + if (Section.Texture) + Section.Texture->Release(); + } } delete mMesh; @@ -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,13 +319,7 @@ 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) diff --git a/common/project.cpp b/common/project.cpp index 136d3dcd..92e6f918 100644 --- a/common/project.cpp +++ b/common/project.cpp @@ -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;