diff --git a/common/lc_meshloader.cpp b/common/lc_meshloader.cpp index e5301f69..234c161c 100644 --- a/common/lc_meshloader.cpp +++ b/common/lc_meshloader.cpp @@ -103,14 +103,14 @@ static void lcTestQuad(int* QuadIndices, const lcVector3* Vertices) const float lcDistanceEpsilon = 0.01f; // Maximum value for 50591.dat const float lcTexCoordEpsilon = 0.01f; -static bool lcCompareVertices(const lcVector3& Position1, const lcVector3& Position2) +static bool lcComparePositions(const lcVector3& Position1, const lcVector3& Position2) { return fabsf(Position1.x - Position2.x) < lcDistanceEpsilon && fabsf(Position1.y - Position2.y) < lcDistanceEpsilon && fabsf(Position1.z - Position2.z) < lcDistanceEpsilon; } -static bool lcCompareVertices(const lcVector3& Position1, const lcVector2& TexCoord1, const lcVector3& Position2, const lcVector2& TexCoord2) +static bool lcCompareTexCoords(const lcVector2& TexCoord1, const lcVector2& TexCoord2) { - return lcCompareVertices(Position1, Position2) && fabsf(TexCoord1.x - TexCoord2.x) < lcTexCoordEpsilon && fabsf(TexCoord1.y - TexCoord2.y) < lcTexCoordEpsilon; + return fabsf(TexCoord1.x - TexCoord2.x) < lcTexCoordEpsilon && fabsf(TexCoord1.y - TexCoord2.y) < lcTexCoordEpsilon; } lcLibraryMeshSection* lcMeshLoaderTypeData::AddSection(lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, lcTexture* Texture) @@ -132,7 +132,7 @@ quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, bool Optimize { lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; - if (lcCompareVertices(Position, Vertex.Position)) + if (lcComparePositions(Position, Vertex.Position)) { Vertex.Usage |= LC_LIBRARY_VERTEX_UNTEXTURED; return VertexIdx; @@ -153,35 +153,44 @@ quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, bool Optimize quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, const lcVector3& Normal, bool Optimize) { + int found = -1; + lcVector3 NewVertexPosition = Position; + if (Optimize) { for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) { lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; - if (lcCompareVertices(Position, Vertex.Position)) + if (lcComparePositions(Position, Vertex.Position)) { + NewVertexPosition = Vertex.Position; + if (Vertex.NormalWeight == 0.0f) { Vertex.Normal = Normal; Vertex.NormalWeight = 1.0f; Vertex.Usage |= LC_LIBRARY_VERTEX_UNTEXTURED; - return VertexIdx; + return VertexIdx; // can be only 1 matching vertex if Vertex.NormalWeight == 0.0f } else if (lcDot(Normal, Vertex.Normal) > 0.707f) { Vertex.Normal = lcNormalize(Vertex.Normal * Vertex.NormalWeight + Normal); Vertex.NormalWeight += 1.0f; Vertex.Usage |= LC_LIBRARY_VERTEX_UNTEXTURED; - return VertexIdx; + if (found < 0) + found = VertexIdx; // save first match } } } } + if (found >= 0) + return found; // return first match + lcMeshLoaderVertex& Vertex = mVertices.Add(); - Vertex.Position = Position; + Vertex.Position = NewVertexPosition; Vertex.Normal = Normal; Vertex.NormalWeight = 1.0f; Vertex.TexCoord = lcVector2(0.0f, 0.0f); @@ -190,22 +199,26 @@ quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, const lcVecto return mVertices.GetSize() - 1; } -quint32 lcMeshLoaderTypeData::AddTexturedVertex(const lcVector3& Position, const lcVector2& TexCoord, bool Optimize) +quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, const lcVector2& TexCoord, bool Optimize) { + lcVector3 NewVertexPosition = Position; + if (Optimize) { for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) { lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; - if (Vertex.Usage & LC_LIBRARY_VERTEX_TEXTURED) + if (lcComparePositions(NewVertexPosition, Vertex.Position)) { - if (lcCompareVertices(Position, TexCoord, Vertex.Position, Vertex.TexCoord)) - return VertexIdx; - } - else - { - if (lcCompareVertices(Position, Vertex.Position)) + NewVertexPosition = Position; + + if (Vertex.Usage & LC_LIBRARY_VERTEX_TEXTURED) + { + if (lcCompareTexCoords(TexCoord, Vertex.TexCoord)) + return VertexIdx; + } + else { Vertex.TexCoord = TexCoord; Vertex.Usage |= LC_LIBRARY_VERTEX_TEXTURED; @@ -217,7 +230,7 @@ quint32 lcMeshLoaderTypeData::AddTexturedVertex(const lcVector3& Position, const lcMeshLoaderVertex& Vertex = mVertices.Add(); - Vertex.Position = Position; + Vertex.Position = NewVertexPosition; Vertex.Normal = lcVector3(0.0f, 0.0f, 0.0f); Vertex.NormalWeight = 0.0f; Vertex.TexCoord = TexCoord; @@ -226,63 +239,93 @@ quint32 lcMeshLoaderTypeData::AddTexturedVertex(const lcVector3& Position, const return mVertices.GetSize() - 1; } -quint32 lcMeshLoaderTypeData::AddTexturedVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize) +quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize) { + int found = -1; + lcVector3 NewVertexPosition = Position; + lcVector2 NewVertexTexCoord = TexCoord; + lcVector3 NewVertexNormal = Normal; + float NewVertexNormalWeight = 1.0f; + if (Optimize) { for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) { lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; - if (Vertex.Usage & LC_LIBRARY_VERTEX_TEXTURED) + if (lcComparePositions(NewVertexPosition, Vertex.Position)) { - if (lcCompareVertices(Position, TexCoord, Vertex.Position, Vertex.TexCoord)) + NewVertexPosition = Vertex.Position; + + if (Vertex.Usage & LC_LIBRARY_VERTEX_TEXTURED) { - if (Vertex.NormalWeight == 0.0f) + if (lcCompareTexCoords(NewVertexTexCoord, Vertex.TexCoord)) { - Vertex.Normal = Normal; - Vertex.NormalWeight = 1.0f; - return VertexIdx; + NewVertexTexCoord = Vertex.TexCoord; + + if (Vertex.NormalWeight == 0.0f) + { + Vertex.Normal = Normal; + Vertex.NormalWeight = 1.0f; + return VertexIdx; // can be only 1 matching vertex if Vertex.NormalWeight == 0.0f + } + else if (lcDot(Normal, Vertex.Normal) > 0.707f) + { + Vertex.Normal = lcNormalize(Vertex.Normal * Vertex.NormalWeight + Normal); + Vertex.NormalWeight += 1.0f; + if (found < 0) + found = VertexIdx; // save first match + } } - else if (lcDot(Normal, Vertex.Normal) > 0.707f) + else { - Vertex.Normal = lcNormalize(Vertex.Normal * Vertex.NormalWeight + Normal); - Vertex.NormalWeight += 1.0f; - return VertexIdx; + if (Vertex.NormalWeight == 0.0f) + { + Vertex.Normal = Normal; + Vertex.NormalWeight = 1.0f; + } + else if (lcDot(Normal, Vertex.Normal) > 0.707f) + { + Vertex.Normal = lcNormalize(Vertex.Normal * Vertex.NormalWeight + Normal); + Vertex.NormalWeight += 1.0f; + NewVertexNormal = Vertex.Normal; + NewVertexNormalWeight = Vertex.NormalWeight; + } } } - } - else - { - if (lcCompareVertices(Position, Vertex.Position)) + else { if (Vertex.NormalWeight == 0.0f) { Vertex.Normal = Normal; Vertex.NormalWeight = 1.0f; - Vertex.TexCoord = TexCoord; + Vertex.TexCoord = NewVertexTexCoord; Vertex.Usage |= LC_LIBRARY_VERTEX_TEXTURED; - return VertexIdx; + return VertexIdx; // can be only 1 matching vertex if Vertex.NormalWeight == 0.0f } else if (lcDot(Normal, Vertex.Normal) > 0.707f) { Vertex.Normal = lcNormalize(Vertex.Normal * Vertex.NormalWeight + Normal); Vertex.NormalWeight += 1.0f; - Vertex.TexCoord = TexCoord; + Vertex.TexCoord = NewVertexTexCoord; Vertex.Usage |= LC_LIBRARY_VERTEX_TEXTURED; - return VertexIdx; + if (found < 0) + found = VertexIdx; // save first match } } } } } + if (found >= 0) + return found; // return first match + lcMeshLoaderVertex& Vertex = mVertices.Add(); - Vertex.Position = Position; - Vertex.Normal = Normal; - Vertex.NormalWeight = 1.0f; - Vertex.TexCoord = TexCoord; + Vertex.Position = NewVertexPosition; + Vertex.Normal = NewVertexNormal; + Vertex.NormalWeight = NewVertexNormalWeight; + Vertex.TexCoord = NewVertexTexCoord; Vertex.Usage = LC_LIBRARY_VERTEX_TEXTURED; return mVertices.GetSize() - 1; @@ -530,7 +573,7 @@ void lcMeshLoaderTypeData::ProcessTexturedLine(int LineType, quint32 ColorCode, for (int IndexIdx = 0; IndexIdx < lcMin(LineType, 4); IndexIdx++) { const lcVector3& Position = Vertices[QuadIndices[IndexIdx]]; - Indices[IndexIdx] = AddTexturedVertex(Position, Normal, TexCoords[QuadIndices[IndexIdx]], Optimize); + Indices[IndexIdx] = AddVertex(Position, Normal, TexCoords[QuadIndices[IndexIdx]], Optimize); } if (LineType == 4) @@ -599,13 +642,13 @@ void lcMeshLoaderTypeData::AddMeshData(const lcMeshLoaderTypeData& Data, const l else { if (DataVertex.NormalWeight == 0.0f) - Index = AddTexturedVertex(Position, DataVertex.TexCoord, true); + Index = AddVertex(Position, DataVertex.TexCoord, true); else { lcVector3 Normal = lcNormalize(lcMul(DataVertex.Normal, NormalTransform)); if (InvertNormals) Normal = -Normal; - Index = AddTexturedVertex(Position, Normal, DataVertex.TexCoord, true); + Index = AddVertex(Position, Normal, DataVertex.TexCoord, true); } mVertices[Index].Usage = DataVertex.Usage; // todo: I think this should be |= @@ -623,13 +666,13 @@ void lcMeshLoaderTypeData::AddMeshData(const lcMeshLoaderTypeData& Data, const l int Index; if (DataVertex.NormalWeight == 0.0f) - Index = AddTexturedVertex(Position, TexCoord, true); + Index = AddVertex(Position, TexCoord, true); else { lcVector3 Normal = lcNormalize(lcMul(DataVertex.Normal, NormalTransform)); if (InvertNormals) Normal = -Normal; - Index = AddTexturedVertex(Position, Normal, TexCoord, true); + Index = AddVertex(Position, Normal, TexCoord, true); } IndexRemap.Add(Index); diff --git a/common/lc_meshloader.h b/common/lc_meshloader.h index f5d8f46b..2e3aab15 100644 --- a/common/lc_meshloader.h +++ b/common/lc_meshloader.h @@ -120,8 +120,8 @@ public: quint32 AddVertex(const lcVector3& Position, bool Optimize); quint32 AddVertex(const lcVector3& Position, const lcVector3& Normal, bool Optimize); - quint32 AddTexturedVertex(const lcVector3& Position, const lcVector2& TexCoord, bool Optimize); - quint32 AddTexturedVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize); + quint32 AddVertex(const lcVector3& Position, const lcVector2& TexCoord, bool Optimize); + quint32 AddVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize); quint32 AddConditionalVertex(const lcVector3 (&Position)[4]); void ProcessLine(int LineType, quint32 ColorCode, bool WindingCCW, lcVector3 (&Vertices)[4], bool Optimize);