From c3ad14ac0461c5d07ea76de50ca09ead1c66b080 Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Sat, 6 Mar 2021 18:54:24 -0800 Subject: [PATCH] Conditional line shader. --- common/lc_context.cpp | 58 +- common/lc_context.h | 2 + common/lc_library.h | 2 +- common/lc_mesh.cpp | 36 +- common/lc_mesh.h | 11 +- common/lc_meshloader.cpp | 993 ++++++++++-------- common/lc_meshloader.h | 107 +- common/lc_scene.cpp | 58 +- common/lc_synth.cpp | 16 +- common/pieceinf.cpp | 2 +- leocad.qrc | 2 + .../shaders/unlit_color_conditional_ps.glsl | 8 + .../shaders/unlit_color_conditional_vs.glsl | 30 + 13 files changed, 763 insertions(+), 562 deletions(-) create mode 100644 resources/shaders/unlit_color_conditional_ps.glsl create mode 100644 resources/shaders/unlit_color_conditional_vs.glsl diff --git a/common/lc_context.cpp b/common/lc_context.cpp index ac4adfb3..1012e5b2 100644 --- a/common/lc_context.cpp +++ b/common/lc_context.cpp @@ -164,26 +164,28 @@ void lcContext::CreateShaderPrograms() const char* const VertexShaders[] = { - ":/resources/shaders/unlit_color_vs.glsl", // UnlitColor - ":/resources/shaders/unlit_texture_modulate_vs.glsl", // UnlitTextureModulate - ":/resources/shaders/unlit_texture_decal_vs.glsl", // UnlitTextureDecal - ":/resources/shaders/unlit_vertex_color_vs.glsl", // UnlitVertexColor - ":/resources/shaders/unlit_view_sphere_vs.glsl", // UnlitViewSphere - ":/resources/shaders/fakelit_color_vs.glsl", // FakeLitColor - ":/resources/shaders/fakelit_texture_decal_vs.glsl" // FakeLitTextureDecal + ":/resources/shaders/unlit_color_vs.glsl", // UnlitColor + ":/resources/shaders/unlit_color_conditional_vs.glsl", // UnlitColorConditional + ":/resources/shaders/unlit_texture_modulate_vs.glsl", // UnlitTextureModulate + ":/resources/shaders/unlit_texture_decal_vs.glsl", // UnlitTextureDecal + ":/resources/shaders/unlit_vertex_color_vs.glsl", // UnlitVertexColor + ":/resources/shaders/unlit_view_sphere_vs.glsl", // UnlitViewSphere + ":/resources/shaders/fakelit_color_vs.glsl", // FakeLitColor + ":/resources/shaders/fakelit_texture_decal_vs.glsl" // FakeLitTextureDecal }; LC_ARRAY_SIZE_CHECK(VertexShaders, lcMaterialType::Count); const char* const FragmentShaders[] = { - ":/resources/shaders/unlit_color_ps.glsl", // UnlitColor - ":/resources/shaders/unlit_texture_modulate_ps.glsl", // UnlitTextureModulate - ":/resources/shaders/unlit_texture_decal_ps.glsl", // UnlitTextureDecal - ":/resources/shaders/unlit_vertex_color_ps.glsl", // UnlitVertexColor - ":/resources/shaders/unlit_view_sphere_ps.glsl", // UnlitViewSphere - ":/resources/shaders/fakelit_color_ps.glsl", // FakeLitColor - ":/resources/shaders/fakelit_texture_decal_ps.glsl" // FakeLitTextureDecal + ":/resources/shaders/unlit_color_ps.glsl", // UnlitColor + ":/resources/shaders/unlit_color_conditional_ps.glsl", // UnlitColorConditional + ":/resources/shaders/unlit_texture_modulate_ps.glsl", // UnlitTextureModulate + ":/resources/shaders/unlit_texture_decal_ps.glsl", // UnlitTextureDecal + ":/resources/shaders/unlit_vertex_color_ps.glsl", // UnlitVertexColor + ":/resources/shaders/unlit_view_sphere_ps.glsl", // UnlitViewSphere + ":/resources/shaders/fakelit_color_ps.glsl", // FakeLitColor + ":/resources/shaders/fakelit_texture_decal_ps.glsl" // FakeLitTextureDecal }; LC_ARRAY_SIZE_CHECK(FragmentShaders, lcMaterialType::Count); @@ -483,6 +485,7 @@ void lcContext::SetMaterial(lcMaterialType MaterialType) break; case lcMaterialType::UnlitColor: + case lcMaterialType::UnlitColorConditional: case lcMaterialType::UnlitVertexColor: case lcMaterialType::FakeLitColor: if (mTextureEnabled) @@ -891,6 +894,33 @@ void lcContext::SetVertexFormatPosition(int PositionSize) } } +void lcContext::SetVertexFormatConditional(int BufferOffset) +{ + const int VertexSize = 12 * sizeof(float); + char* VertexBufferPointer = mVertexBufferPointer + BufferOffset; + + if (gSupportsShaderObjects) + { + if (mVertexBufferOffset != VertexBufferPointer) + { + glVertexAttribPointer(0, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer); + glVertexAttribPointer(1, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 3 * sizeof(float)); + glVertexAttribPointer(2, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 6 * sizeof(float)); + glVertexAttribPointer(3, 3, GL_FLOAT, false, VertexSize, VertexBufferPointer + 9 * sizeof(float)); + + mVertexBufferOffset = VertexBufferPointer; + + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + glEnableVertexAttribArray(3); + + mNormalEnabled = true; // todo: store state using an array + mTexCoordEnabled = true; + mColorEnabled = true; + } + } +} + void lcContext::SetVertexFormat(int BufferOffset, int PositionSize, int NormalSize, int TexCoordSize, int ColorSize, bool EnableNormals) { const int VertexSize = (PositionSize + TexCoordSize) * sizeof(float) + NormalSize * sizeof(quint32) + ColorSize; diff --git a/common/lc_context.h b/common/lc_context.h index 13fade49..e4e27087 100644 --- a/common/lc_context.h +++ b/common/lc_context.h @@ -48,6 +48,7 @@ public: enum class lcMaterialType { UnlitColor, + UnlitColorConditional, UnlitTextureModulate, UnlitTextureDecal, UnlitVertexColor, @@ -191,6 +192,7 @@ public: void SetVertexFormat(int BufferOffset, int PositionSize, int NormalSize, int TexCoordSize, int ColorSize, bool EnableNormals); void SetVertexFormatPosition(int PositionSize); + void SetVertexFormatConditional(int BufferOffset); void DrawPrimitives(GLenum Mode, GLint First, GLsizei Count); void DrawIndexedPrimitives(GLenum Mode, GLsizei Count, GLenum Type, int Offset); diff --git a/common/lc_library.h b/common/lc_library.h index 670dd3cd..b79d25da 100644 --- a/common/lc_library.h +++ b/common/lc_library.h @@ -76,7 +76,7 @@ public: void Unload() { mState = lcPrimitiveState::NotLoaded; - mMeshData.RemoveAll(); + mMeshData.Clear(); } QString mFileName; diff --git a/common/lc_mesh.cpp b/common/lc_mesh.cpp index b1b8169d..ad6d29c5 100644 --- a/common/lc_mesh.cpp +++ b/common/lc_mesh.cpp @@ -8,7 +8,7 @@ #include "lc_library.h" #define LC_MESH_FILE_ID LC_FOURCC('M', 'E', 'S', 'H') -#define LC_MESH_FILE_VERSION 0x0118 +#define LC_MESH_FILE_VERSION 0x0120 lcMesh* gPlaceholderMesh; @@ -39,7 +39,7 @@ lcMesh::~lcMesh() delete[] mLods[LodIdx].Sections; } -void lcMesh::Create(quint16 NumSections[LC_NUM_MESH_LODS], int NumVertices, int NumTexturedVertices, int NumIndices) +void lcMesh::Create(quint16(&NumSections)[LC_NUM_MESH_LODS], int VertexCount, int TexturedVertexCount, int ConditionalVertexCount, int IndexCount) { for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { @@ -48,20 +48,21 @@ void lcMesh::Create(quint16 NumSections[LC_NUM_MESH_LODS], int NumVertices, int mLods[LodIdx].NumSections = NumSections[LodIdx]; } - mNumVertices = NumVertices; - mNumTexturedVertices = NumTexturedVertices; - mVertexDataSize = NumVertices * sizeof(lcVertex) + NumTexturedVertices * sizeof(lcVertexTextured); + mNumVertices = VertexCount; + mNumTexturedVertices = TexturedVertexCount; + mConditionalVertexCount = ConditionalVertexCount; + mVertexDataSize = VertexCount * sizeof(lcVertex) + TexturedVertexCount * sizeof(lcVertexTextured) + ConditionalVertexCount * sizeof(lcVertexConditional); mVertexData = malloc(mVertexDataSize); - if (NumVertices < 0x10000 && NumTexturedVertices < 0x10000) + if (VertexCount < 0x10000 && TexturedVertexCount < 0x10000 && ConditionalVertexCount < 0x10000) { mIndexType = GL_UNSIGNED_SHORT; - mIndexDataSize = NumIndices * sizeof(GLushort); + mIndexDataSize = IndexCount * sizeof(GLushort); } else { mIndexType = GL_UNSIGNED_INT; - mIndexDataSize = NumIndices * sizeof(GLuint); + mIndexDataSize = IndexCount * sizeof(GLuint); } mIndexData = malloc(mIndexDataSize); @@ -73,7 +74,7 @@ void lcMesh::CreateBox() memset(NumSections, 0, sizeof(NumSections)); NumSections[LC_MESH_LOD_HIGH] = 2; - Create(NumSections, 24, 0, 36 + 24); + Create(NumSections, 24, 0, 0, 36 + 24); lcVector3 Min(-10.0f, -10.0f, -24.0f); lcVector3 Max(10.0f, 10.0f, 4.0f); @@ -378,16 +379,16 @@ bool lcMesh::FileLoad(lcMemFile& File) mBoundingBox.Max = File.ReadVector3(); mRadius = File.ReadFloat(); - quint32 NumVertices, NumTexturedVertices, NumIndices; + quint32 VertexCount, TexturedVertexCount, ConditionalVertexCount, IndexCount; quint16 NumLods, NumSections[LC_NUM_MESH_LODS]; - if (!File.ReadU32(&NumVertices, 1) || !File.ReadU32(&NumTexturedVertices, 1) || !File.ReadU32(&NumIndices, 1)) + if (!File.ReadU32(&VertexCount, 1) || !File.ReadU32(&TexturedVertexCount, 1) || !File.ReadU32(&ConditionalVertexCount, 1) || !File.ReadU32(&IndexCount, 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); + Create(NumSections, VertexCount, TexturedVertexCount, ConditionalVertexCount, IndexCount); for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { @@ -398,12 +399,12 @@ bool lcMesh::FileLoad(lcMemFile& File) quint32 ColorCode, IndexOffset; quint16 PrimtiveType, Length; - if (!File.ReadU32(&ColorCode, 1) || !File.ReadU32(&IndexOffset, 1) || !File.ReadU32(&NumIndices, 1) || !File.ReadU16(&PrimtiveType, 1)) + if (!File.ReadU32(&ColorCode, 1) || !File.ReadU32(&IndexOffset, 1) || !File.ReadU32(&IndexCount, 1) || !File.ReadU16(&PrimtiveType, 1)) return false; Section.ColorIndex = lcGetColorIndex(ColorCode); Section.IndexOffset = IndexOffset; - Section.NumIndices = NumIndices; + Section.NumIndices = IndexCount; Section.PrimitiveType = (lcMeshPrimitiveType)PrimtiveType; Section.BoundingBox.Min = File.ReadVector3(); Section.BoundingBox.Max = File.ReadVector3(); @@ -429,7 +430,8 @@ bool lcMesh::FileLoad(lcMemFile& File) } } - File.ReadBuffer(mVertexData, mNumVertices * sizeof(lcVertex) + mNumTexturedVertices * sizeof(lcVertexTextured)); + File.ReadBuffer(mVertexData, mNumVertices * sizeof(lcVertex) + mNumTexturedVertices * sizeof(lcVertexTextured) + mConditionalVertexCount * sizeof(lcVertexConditional)); + if (mIndexType == GL_UNSIGNED_SHORT) File.ReadU16((quint16*)mIndexData, mIndexDataSize / 2); else @@ -450,6 +452,7 @@ bool lcMesh::FileSave(lcMemFile& File) File.WriteU32(mNumVertices); File.WriteU32(mNumTexturedVertices); + File.WriteU32(mConditionalVertexCount); File.WriteU32(mIndexDataSize / (mIndexType == GL_UNSIGNED_SHORT ? 2 : 4)); File.WriteU16(LC_NUM_MESH_LODS); @@ -481,7 +484,8 @@ bool lcMesh::FileSave(lcMemFile& File) } } - File.WriteBuffer(mVertexData, mNumVertices * sizeof(lcVertex) + mNumTexturedVertices * sizeof(lcVertexTextured)); + File.WriteBuffer(mVertexData, mNumVertices * sizeof(lcVertex) + mNumTexturedVertices * sizeof(lcVertexTextured) + mConditionalVertexCount * sizeof(lcVertexConditional)); + if (mIndexType == GL_UNSIGNED_SHORT) File.WriteU16((quint16*)mIndexData, mIndexDataSize / 2); else diff --git a/common/lc_mesh.h b/common/lc_mesh.h index 594a66ba..9e90d716 100644 --- a/common/lc_mesh.h +++ b/common/lc_mesh.h @@ -24,6 +24,14 @@ struct lcVertexTextured lcVector2 TexCoord; }; +struct lcVertexConditional +{ + lcVector3 Position1; + lcVector3 Position2; + lcVector3 Position3; + lcVector3 Position4; +}; + struct lcMeshSection { int ColorIndex; @@ -72,7 +80,7 @@ public: lcMesh& operator=(const lcMesh&) = delete; lcMesh& operator=(lcMesh&&) = delete; - void Create(quint16 NumSections[LC_NUM_MESH_LODS], int NumVertices, int NumTexturedVertices, int NumIndices); + void Create(quint16 (&NumSections)[LC_NUM_MESH_LODS], int VertexCount, int TexturedVertexCount, int ConditionalVertexCount, int IndexCount); void CreateBox(); bool FileLoad(lcMemFile& File); @@ -110,6 +118,7 @@ public: int mNumVertices; int mNumTexturedVertices; + int mConditionalVertexCount; int mIndexType; }; diff --git a/common/lc_meshloader.cpp b/common/lc_meshloader.cpp index 493f9875..d895daac 100644 --- a/common/lc_meshloader.cpp +++ b/common/lc_meshloader.cpp @@ -6,14 +6,14 @@ #include "lc_application.h" #include "lc_texture.h" -static lcVector2 lcCalculateTexCoord(const lcVector3& Position, const lcLibraryTextureMap* TextureMap) +static lcVector2 lcCalculateTexCoord(const lcVector3& Position, const lcMeshLoaderTextureMap* TextureMap) { switch (TextureMap->Type) { - case lcLibraryTextureMapType::PLANAR: + case lcMeshLoaderTextureMapType::Planar: return lcVector2(lcDot3(Position, TextureMap->Params.Planar.Planes[0]) + TextureMap->Params.Planar.Planes[0].w, lcDot3(Position, TextureMap->Params.Planar.Planes[1]) + TextureMap->Params.Planar.Planes[1].w); - case lcLibraryTextureMapType::CYLINDRICAL: + case lcMeshLoaderTextureMapType::Cylindrical: { const lcVector4& FrontPlane = TextureMap->Params.Cylindrical.FrontPlane; const lcVector4& Plane1 = TextureMap->Params.Cylindrical.Plane1; @@ -33,7 +33,7 @@ static lcVector2 lcCalculateTexCoord(const lcVector3& Position, const lcLibraryT return TexCoord; } - case lcLibraryTextureMapType::SPHERICAL: + case lcMeshLoaderTextureMapType::Spherical: { const lcVector4& FrontPlane = TextureMap->Params.Spherical.FrontPlane; const lcVector3& Center = TextureMap->Params.Spherical.Center; @@ -61,7 +61,7 @@ static lcVector2 lcCalculateTexCoord(const lcVector3& Position, const lcLibraryT return lcVector2(0.0f, 0.0f); } -void lcLibraryMeshData::ResequenceQuad(int* Indices, int a, int b, int c, int d) +static void lcResequenceQuad(int* Indices, int a, int b, int c, int d) { Indices[0] = a; Indices[1] = b; @@ -69,7 +69,7 @@ void lcLibraryMeshData::ResequenceQuad(int* Indices, int a, int b, int c, int d) Indices[3] = d; } -void lcLibraryMeshData::TestQuad(int* QuadIndices, const lcVector3* Vertices) +static void lcTestQuad(int* QuadIndices, const lcVector3* Vertices) { lcVector3 v01 = Vertices[1] - Vertices[0]; lcVector3 v02 = Vertices[2] - Vertices[0]; @@ -87,72 +87,55 @@ void lcLibraryMeshData::TestQuad(int* QuadIndices, const lcVector3* Vertices) if (lcDot(lcCross(v12, v01), lcCross(v01, v13)) > 0.0f) { if (-lcDot(lcCross(v02, v12), lcCross(v12, v23)) > 0.0f) - ResequenceQuad(QuadIndices, 1, 2, 3, 0); + lcResequenceQuad(QuadIndices, 1, 2, 3, 0); else - ResequenceQuad(QuadIndices, 0, 3, 1, 2); + lcResequenceQuad(QuadIndices, 0, 3, 1, 2); } else { if (-lcDot(lcCross(v02, v12), lcCross(v12, v23)) > 0.0f) - ResequenceQuad(QuadIndices, 0, 1, 3, 2); + lcResequenceQuad(QuadIndices, 0, 1, 3, 2); else - ResequenceQuad(QuadIndices, 1, 2, 3, 0); + lcResequenceQuad(QuadIndices, 1, 2, 3, 0); } } -lcLibraryMeshSection* lcLibraryMeshData::AddSection(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, lcTexture* Texture) -{ - lcArray& Sections = mSections[MeshDataType]; - lcLibraryMeshSection* Section; - - for (int SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++) - { - Section = Sections[SectionIdx]; - - if (Section->mColor == ColorCode && Section->mPrimitiveType == PrimitiveType && Section->mTexture == Texture) - return Section; - } - - Section = new lcLibraryMeshSection(PrimitiveType, ColorCode, Texture); - Sections.Add(Section); - - return Section; -} - -void lcLibraryMeshData::AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcLibraryMeshVertex** VertexBuffer) -{ - lcArray& Vertices = mVertices[MeshDataType]; - int CurrentSize = Vertices.GetSize(); - - Vertices.SetSize(CurrentSize + VertexCount); - - *BaseVertex = CurrentSize; - *VertexBuffer = &Vertices[CurrentSize]; -} - const float lcDistanceEpsilon = 0.01f; // Maximum value for 50591.dat const float lcTexCoordEpsilon = 0.01f; -inline bool lcCompareVertices(const lcVector3& Position1, const lcVector3& Position2) +static bool lcCompareVertices(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; } -inline bool lcCompareVertices(const lcVector3& Position1, const lcVector2& TexCoord1, const lcVector3& Position2, const lcVector2& TexCoord2) +static bool lcCompareVertices(const lcVector3& Position1, const lcVector2& TexCoord1, const lcVector3& Position2, const lcVector2& TexCoord2) { - return fabsf(Position1.x - Position2.x) < lcDistanceEpsilon && fabsf(Position1.y - Position2.y) < lcDistanceEpsilon && fabsf(Position1.z - Position2.z) < lcDistanceEpsilon && - fabsf(TexCoord1.x - TexCoord2.x) < lcTexCoordEpsilon && fabsf(TexCoord1.y - TexCoord2.y) < lcTexCoordEpsilon; + return lcCompareVertices(Position1, Position2) && fabsf(TexCoord1.x - TexCoord2.x) < lcTexCoordEpsilon && fabsf(TexCoord1.y - TexCoord2.y) < lcTexCoordEpsilon; } -quint32 lcLibraryMeshData::AddVertex(lcMeshDataType MeshDataType, const lcVector3& Position, bool Optimize) +static bool lcCompareConditionalVertices(const lcVector3* Position1, const lcVector3* Position2) { - lcArray& VertexArray = mVertices[MeshDataType]; + return lcCompareVertices(Position1[0], Position2[0]) && lcCompareVertices(Position1[1], Position2[1]) && lcCompareVertices(Position1[2], Position2[2]) && lcCompareVertices(Position1[3], Position2[3]); +} +lcLibraryMeshSection* lcMeshLoaderTypeData::AddSection(lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, lcTexture* Texture) +{ + for (std::unique_ptr& Section : mSections) + if (Section->mColor == ColorCode && Section->mPrimitiveType == PrimitiveType && Section->mTexture == Texture) + return Section.get(); + + mSections.emplace_back(new lcLibraryMeshSection(PrimitiveType, ColorCode, Texture)); + + return mSections.back().get(); +} + +quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, bool Optimize) +{ if (Optimize) { - for (int VertexIdx = VertexArray.GetSize() - 1; VertexIdx >= 0; VertexIdx--) + for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) { - lcLibraryMeshVertex& Vertex = VertexArray[VertexIdx]; + lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; if (lcCompareVertices(Position, Vertex.Position)) { @@ -162,25 +145,24 @@ quint32 lcLibraryMeshData::AddVertex(lcMeshDataType MeshDataType, const lcVector } } - lcLibraryMeshVertex& Vertex = VertexArray.Add(); + lcMeshLoaderVertex& Vertex = mVertices.Add(); + Vertex.Position = Position; Vertex.Normal = lcVector3(0.0f, 0.0f, 0.0f); Vertex.NormalWeight = 0.0f; Vertex.TexCoord = lcVector2(0.0f, 0.0f); Vertex.Usage = LC_LIBRARY_VERTEX_UNTEXTURED; - return VertexArray.GetSize() - 1; + return mVertices.GetSize() - 1; } -quint32 lcLibraryMeshData::AddVertex(lcMeshDataType MeshDataType, const lcVector3& Position, const lcVector3& Normal, bool Optimize) +quint32 lcMeshLoaderTypeData::AddVertex(const lcVector3& Position, const lcVector3& Normal, bool Optimize) { - lcArray& VertexArray = mVertices[MeshDataType]; - if (Optimize) { - for (int VertexIdx = VertexArray.GetSize() - 1; VertexIdx >= 0; VertexIdx--) + for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) { - lcLibraryMeshVertex& Vertex = VertexArray[VertexIdx]; + lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; if (lcCompareVertices(Position, Vertex.Position)) { @@ -202,27 +184,24 @@ quint32 lcLibraryMeshData::AddVertex(lcMeshDataType MeshDataType, const lcVector } } - lcLibraryMeshVertex& Vertex = VertexArray.Add(); + lcMeshLoaderVertex& Vertex = mVertices.Add(); + Vertex.Position = Position; Vertex.Normal = Normal; Vertex.NormalWeight = 1.0f; Vertex.TexCoord = lcVector2(0.0f, 0.0f); Vertex.Usage = LC_LIBRARY_VERTEX_UNTEXTURED; - return VertexArray.GetSize() - 1; + return mVertices.GetSize() - 1; } -quint32 lcLibraryMeshData::AddTexturedVertex(lcMeshDataType MeshDataType, const lcVector3& Position, const lcVector2& TexCoord, bool Optimize) +quint32 lcMeshLoaderTypeData::AddTexturedVertex(const lcVector3& Position, const lcVector2& TexCoord, bool Optimize) { - mHasTextures = true; - - lcArray& VertexArray = mVertices[MeshDataType]; - if (Optimize) { - for (int VertexIdx = VertexArray.GetSize() - 1; VertexIdx >= 0; VertexIdx--) + for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) { - lcLibraryMeshVertex& Vertex = VertexArray[VertexIdx]; + lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; if (Vertex.Usage & LC_LIBRARY_VERTEX_TEXTURED) { @@ -241,27 +220,24 @@ quint32 lcLibraryMeshData::AddTexturedVertex(lcMeshDataType MeshDataType, const } } - lcLibraryMeshVertex& Vertex = VertexArray.Add(); + lcMeshLoaderVertex& Vertex = mVertices.Add(); + Vertex.Position = Position; Vertex.Normal = lcVector3(0.0f, 0.0f, 0.0f); Vertex.NormalWeight = 0.0f; Vertex.TexCoord = TexCoord; Vertex.Usage = LC_LIBRARY_VERTEX_TEXTURED; - return VertexArray.GetSize() - 1; + return mVertices.GetSize() - 1; } -quint32 lcLibraryMeshData::AddTexturedVertex(lcMeshDataType MeshDataType, const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize) +quint32 lcMeshLoaderTypeData::AddTexturedVertex(const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize) { - mHasTextures = true; - - lcArray& VertexArray = mVertices[MeshDataType]; - if (Optimize) { - for (int VertexIdx = VertexArray.GetSize() - 1; VertexIdx >= 0; VertexIdx--) + for (int VertexIdx = mVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) { - lcLibraryMeshVertex& Vertex = VertexArray[VertexIdx]; + lcMeshLoaderVertex& Vertex = mVertices[VertexIdx]; if (Vertex.Usage & LC_LIBRARY_VERTEX_TEXTURED) { @@ -306,32 +282,45 @@ quint32 lcLibraryMeshData::AddTexturedVertex(lcMeshDataType MeshDataType, const } } - lcLibraryMeshVertex& Vertex = VertexArray.Add(); + lcMeshLoaderVertex& Vertex = mVertices.Add(); + Vertex.Position = Position; Vertex.Normal = Normal; Vertex.NormalWeight = 1.0f; Vertex.TexCoord = TexCoord; Vertex.Usage = LC_LIBRARY_VERTEX_TEXTURED; - return VertexArray.GetSize() - 1; + return mVertices.GetSize() - 1; } -void lcLibraryMeshData::AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer) +quint32 lcMeshLoaderTypeData::AddConditionalVertex(const lcVector3* Position, bool Optimize) { - lcLibraryMeshSection* Section = AddSection(MeshDataType, PrimitiveType, ColorCode, nullptr); - lcArray& Indices = Section->mIndices; - int CurrentSize = Indices.GetSize(); + if (Optimize) + { + for (int VertexIdx = mConditionalVertices.GetSize() - 1; VertexIdx >= 0; VertexIdx--) + { + lcMeshLoaderConditionalVertex& Vertex = mConditionalVertices[VertexIdx]; - Indices.SetSize(CurrentSize + IndexCount); + if (lcCompareConditionalVertices(Position, Vertex.Position)) + return VertexIdx; + } + } - *IndexBuffer = &Indices[CurrentSize]; + lcMeshLoaderConditionalVertex& Vertex = mConditionalVertices.Add(); + + Vertex.Position[0] = Position[0]; + Vertex.Position[1] = Position[1]; + Vertex.Position[2] = Position[2]; + Vertex.Position[3] = Position[3]; + + return mConditionalVertices.GetSize() - 1; } -void lcLibraryMeshData::AddLine(lcMeshDataType MeshDataType, int LineType, quint32 ColorCode, bool WindingCCW, const lcVector3* Vertices, bool Optimize) +void lcMeshLoaderTypeData::ProcessLine(int LineType, quint32 ColorCode, bool WindingCCW, lcVector3* Vertices, bool Optimize) { lcMeshPrimitiveType PrimitiveTypes[4] = { LC_MESH_LINES, LC_MESH_TRIANGLES, LC_MESH_TRIANGLES, LC_MESH_CONDITIONAL_LINES }; lcMeshPrimitiveType PrimitiveType = PrimitiveTypes[LineType - 2]; - lcLibraryMeshSection* Section = AddSection(MeshDataType, PrimitiveType, ColorCode, nullptr); + lcLibraryMeshSection* Section = AddSection(PrimitiveType, ColorCode, nullptr); int QuadIndices[4] = { 0, 1, 2, 3 }; int Indices[4] = { -1, -1, -1, -1 }; @@ -339,7 +328,7 @@ void lcLibraryMeshData::AddLine(lcMeshDataType MeshDataType, int LineType, quint if (LineType == 3 || LineType == 4) { if (LineType == 4) - TestQuad(QuadIndices, Vertices); + lcTestQuad(QuadIndices, Vertices); lcVector3 Normal = lcNormalize(lcCross(Vertices[1] - Vertices[0], Vertices[2] - Vertices[0])); @@ -349,86 +338,90 @@ void lcLibraryMeshData::AddLine(lcMeshDataType MeshDataType, int LineType, quint for (int IndexIdx = 0; IndexIdx < lcMin(LineType, 4); IndexIdx++) { const lcVector3& Position = Vertices[QuadIndices[IndexIdx]]; - Indices[IndexIdx] = AddVertex(MeshDataType, Position, Normal, Optimize); + Indices[IndexIdx] = AddVertex(Position, Normal, Optimize); } } - else + else if (LineType == 2) { - for (int IndexIdx = 0; IndexIdx < lcMin(LineType, 4); IndexIdx++) + for (int IndexIdx = 0; IndexIdx < 2; IndexIdx++) { const lcVector3& Position = Vertices[QuadIndices[IndexIdx]]; - Indices[IndexIdx] = AddVertex(MeshDataType, Position, Optimize); + Indices[IndexIdx] = AddVertex(Position, Optimize); } } + else if (LineType == 5) + { + Indices[0] = AddConditionalVertex(Vertices, Optimize); + std::swap(Vertices[0], Vertices[1]); + Indices[1] = AddConditionalVertex(Vertices, Optimize); + } switch (LineType) { - case 5: - if (Indices[0] != Indices[1] && Indices[0] != Indices[2] && Indices[0] != Indices[3] && Indices[1] != Indices[2] && Indices[1] != Indices[3] && Indices[2] != Indices[3]) - { - Section->mIndices.Add(Indices[0]); - Section->mIndices.Add(Indices[1]); - Section->mIndices.Add(Indices[2]); - Section->mIndices.Add(Indices[3]); - } - break; - - case 4: - if (Indices[0] != Indices[2] && Indices[0] != Indices[3] && Indices[2] != Indices[3]) - { - if (WindingCCW) - { - Section->mIndices.Add(Indices[2]); - Section->mIndices.Add(Indices[3]); - Section->mIndices.Add(Indices[0]); - } - else - { - Section->mIndices.Add(Indices[0]); - Section->mIndices.Add(Indices[3]); - Section->mIndices.Add(Indices[2]); - } - } - Q_FALLTHROUGH(); - - case 3: - if (Indices[0] != Indices[1] && Indices[0] != Indices[2] && Indices[1] != Indices[2]) - { - if (WindingCCW) + case 5: + if (Indices[0] != Indices[1]) { Section->mIndices.Add(Indices[0]); Section->mIndices.Add(Indices[1]); - Section->mIndices.Add(Indices[2]); } - else - { - Section->mIndices.Add(Indices[2]); - Section->mIndices.Add(Indices[1]); - Section->mIndices.Add(Indices[0]); - } - } - break; + break; - case 2: - if (Indices[0] != Indices[1]) - { - Section->mIndices.Add(Indices[0]); - Section->mIndices.Add(Indices[1]); - } - break; + case 4: + if (Indices[0] != Indices[2] && Indices[0] != Indices[3] && Indices[2] != Indices[3]) + { + if (WindingCCW) + { + Section->mIndices.Add(Indices[2]); + Section->mIndices.Add(Indices[3]); + Section->mIndices.Add(Indices[0]); + } + else + { + Section->mIndices.Add(Indices[0]); + Section->mIndices.Add(Indices[3]); + Section->mIndices.Add(Indices[2]); + } + } + Q_FALLTHROUGH(); + + case 3: + if (Indices[0] != Indices[1] && Indices[0] != Indices[2] && Indices[1] != Indices[2]) + { + if (WindingCCW) + { + Section->mIndices.Add(Indices[0]); + Section->mIndices.Add(Indices[1]); + Section->mIndices.Add(Indices[2]); + } + else + { + Section->mIndices.Add(Indices[2]); + Section->mIndices.Add(Indices[1]); + Section->mIndices.Add(Indices[0]); + } + } + break; + + case 2: + if (Indices[0] != Indices[1]) + { + Section->mIndices.Add(Indices[0]); + Section->mIndices.Add(Indices[1]); + } + break; } } -void lcLibraryMeshData::AddTexturedLine(lcMeshDataType MeshDataType, int LineType, quint32 ColorCode, bool WindingCCW, const lcLibraryTextureMap& TextureMap, const lcVector3* Vertices, bool Optimize) +void lcMeshLoaderTypeData::ProcessTexturedLine(int LineType, quint32 ColorCode, bool WindingCCW, const lcMeshLoaderTextureMap& TextureMap, const lcVector3* Vertices, bool Optimize) { lcMeshPrimitiveType PrimitiveType = LC_MESH_TEXTURED_TRIANGLES; - lcLibraryMeshSection* Section = AddSection(MeshDataType, PrimitiveType, ColorCode, TextureMap.Texture); + lcLibraryMeshSection* Section = AddSection(PrimitiveType, ColorCode, TextureMap.Texture); int QuadIndices[4] = { 0, 1, 2, 3 }; int Indices[4] = { -1, -1, -1, -1 }; if (LineType == 4) - TestQuad(QuadIndices, Vertices); + lcTestQuad(QuadIndices, Vertices); lcVector3 Normal = lcNormalize(lcCross(Vertices[1] - Vertices[0], Vertices[2] - Vertices[0])); @@ -443,7 +436,7 @@ void lcLibraryMeshData::AddTexturedLine(lcMeshDataType MeshDataType, int LineTyp TexCoords[QuadIndices[IndexIdx]] = lcCalculateTexCoord(Position, &TextureMap); } - if (TextureMap.Type == lcLibraryTextureMapType::CYLINDRICAL || TextureMap.Type == lcLibraryTextureMapType::SPHERICAL) + if (TextureMap.Type == lcMeshLoaderTextureMapType::Cylindrical || TextureMap.Type == lcMeshLoaderTextureMapType::Spherical) { auto CheckTexCoordsWrap = [&TexCoords, &Vertices, &TextureMap](int Index1, int Index2, int Index3) { @@ -454,7 +447,7 @@ void lcLibraryMeshData::AddTexturedLine(lcMeshDataType MeshDataType, int LineTyp if (u12 < 0.5f && u13 < 0.5f && u23 < 0.5f) return; - const lcVector4& Plane2 = (TextureMap.Type == lcLibraryTextureMapType::CYLINDRICAL) ? TextureMap.Params.Cylindrical.Plane2 : TextureMap.Params.Spherical.Plane2; + const lcVector4& Plane2 = (TextureMap.Type == lcMeshLoaderTextureMapType::Cylindrical) ? TextureMap.Params.Cylindrical.Plane2 : TextureMap.Params.Spherical.Plane2; float Dot1 = fabsf(lcDot(Plane2, lcVector4(Vertices[Index1], 1.0f))); float Dot2 = fabsf(lcDot(Plane2, lcVector4(Vertices[Index2], 1.0f))); float Dot3 = fabsf(lcDot(Plane2, lcVector4(Vertices[Index3], 1.0f))); @@ -505,7 +498,7 @@ void lcLibraryMeshData::AddTexturedLine(lcMeshDataType MeshDataType, int LineTyp CheckTexCoordsWrap(QuadIndices[2], QuadIndices[3], QuadIndices[0]); } - if (TextureMap.Type == lcLibraryTextureMapType::SPHERICAL) + if (TextureMap.Type == lcMeshLoaderTextureMapType::Spherical) { auto CheckTexCoordsPole = [&TexCoords, &Vertices, &TextureMap](int Index1, int Index2, int Index3) { @@ -553,7 +546,7 @@ void lcLibraryMeshData::AddTexturedLine(lcMeshDataType MeshDataType, int LineTyp for (int IndexIdx = 0; IndexIdx < lcMin(LineType, 4); IndexIdx++) { const lcVector3& Position = Vertices[QuadIndices[IndexIdx]]; - Indices[IndexIdx] = AddTexturedVertex(MeshDataType, Position, Normal, TexCoords[QuadIndices[IndexIdx]], Optimize); + Indices[IndexIdx] = AddTexturedVertex(Position, Normal, TexCoords[QuadIndices[IndexIdx]], Optimize); } if (LineType == 4) @@ -592,252 +585,277 @@ void lcLibraryMeshData::AddTexturedLine(lcMeshDataType MeshDataType, int LineTyp } } -void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex) +void lcMeshLoaderTypeData::AddMeshData(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap) { - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) + const lcArray& DataVertices = Data.mVertices; + lcArray IndexRemap(DataVertices.GetSize()); + + if (!TextureMap) { - int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex; - const lcArray& DataVertices = Data.mVertices[MeshDataIdx]; - lcArray& Vertices = mVertices[DestIndex]; + mVertices.AllocGrow(DataVertices.GetSize()); - int VertexCount = DataVertices.GetSize(); - lcArray IndexRemap(VertexCount); - - if (!TextureMap) + for (const lcMeshLoaderVertex& DataVertex : DataVertices) { - Vertices.AllocGrow(VertexCount); + lcVector3 Position = lcMul31(DataVertex.Position, Transform); + int Index; - for (int SrcVertexIdx = 0; SrcVertexIdx < VertexCount; SrcVertexIdx++) + if ((DataVertex.Usage & LC_LIBRARY_VERTEX_TEXTURED) == 0) { - lcVector3 Position = lcMul31(DataVertices[SrcVertexIdx].Position, Transform); - int Index; - - if ((DataVertices[SrcVertexIdx].Usage & LC_LIBRARY_VERTEX_TEXTURED) == 0) - { - if (DataVertices[SrcVertexIdx].NormalWeight == 0.0f) - Index = AddVertex((lcMeshDataType)DestIndex, Position, true); - else - { - lcVector3 Normal = lcNormalize(lcMul30(DataVertices[SrcVertexIdx].Normal, Transform)); - if (InvertNormals) - Normal = -Normal; - Index = AddVertex((lcMeshDataType)DestIndex, Position, Normal, true); - } - } + if (DataVertex.NormalWeight == 0.0f) + Index = AddVertex(Position, true); else { - mHasTextures = true; - - if (DataVertices[SrcVertexIdx].NormalWeight == 0.0f) - Index = AddTexturedVertex((lcMeshDataType)DestIndex, Position, DataVertices[SrcVertexIdx].TexCoord, true); - else - { - lcVector3 Normal = lcNormalize(lcMul30(DataVertices[SrcVertexIdx].Normal, Transform)); - if (InvertNormals) - Normal = -Normal; - Index = AddTexturedVertex((lcMeshDataType)DestIndex, Position, Normal, DataVertices[SrcVertexIdx].TexCoord, true); - } - - Vertices[Index].Usage = DataVertices[SrcVertexIdx].Usage; + lcVector3 Normal = lcNormalize(lcMul30(DataVertex.Normal, Transform)); + if (InvertNormals) + Normal = -Normal; + Index = AddVertex(Position, Normal, true); + } + } + else + { + if (DataVertex.NormalWeight == 0.0f) + Index = AddTexturedVertex(Position, DataVertex.TexCoord, true); + else + { + lcVector3 Normal = lcNormalize(lcMul30(DataVertex.Normal, Transform)); + if (InvertNormals) + Normal = -Normal; + Index = AddTexturedVertex(Position, Normal, DataVertex.TexCoord, true); } - IndexRemap.Add(Index); + mVertices[Index].Usage = DataVertex.Usage; // todo: I think this should be |= } + + IndexRemap.Add(Index); + } + } + else + { + for (const lcMeshLoaderVertex& DataVertex : DataVertices) + { + lcVector3 Position = lcMul31(DataVertex.Position, Transform); + lcVector2 TexCoord = lcCalculateTexCoord(Position, TextureMap); + int Index; + + if (DataVertex.NormalWeight == 0.0f) + Index = AddTexturedVertex(Position, TexCoord, true); + else + { + lcVector3 Normal = lcNormalize(lcMul30(DataVertex.Normal, Transform)); + if (InvertNormals) + Normal = -Normal; + Index = AddTexturedVertex(Position, Normal, TexCoord, true); + } + + IndexRemap.Add(Index); + } + } + + mConditionalVertices.AllocGrow(Data.mConditionalVertices.GetSize()); + lcArray ConditionalRemap(Data.mConditionalVertices.GetSize()); + + for (const lcMeshLoaderConditionalVertex& DataVertex : Data.mConditionalVertices) + { + lcVector3 Position[4]; + + Position[0] = lcMul31(DataVertex.Position[0], Transform); + Position[1] = lcMul31(DataVertex.Position[1], Transform); + Position[2] = lcMul31(DataVertex.Position[2], Transform); + Position[3] = lcMul31(DataVertex.Position[3], Transform); + + int Index = AddConditionalVertex(Position, true); + ConditionalRemap.Add(Index); + } + + for (const std::unique_ptr& SrcSection : Data.mSections) + { + quint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor; + lcTexture* Texture; + lcMeshPrimitiveType PrimitiveType = SrcSection->mPrimitiveType; + + if (SrcSection->mTexture) + Texture = SrcSection->mTexture; + else if (TextureMap && SrcSection->mPrimitiveType == LC_MESH_TRIANGLES) + { + Texture = TextureMap->Texture; + PrimitiveType = LC_MESH_TEXTURED_TRIANGLES; + } + else + Texture = nullptr; + + lcLibraryMeshSection* DstSection = AddSection(PrimitiveType, ColorCode, Texture); + DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); + + if (PrimitiveType == LC_MESH_CONDITIONAL_LINES) + { + for (quint32 Index : SrcSection->mIndices) + DstSection->mIndices.Add(ConditionalRemap[Index]); + } + else if (!InvertWinding || (PrimitiveType == LC_MESH_LINES)) + { + for (quint32 Index : SrcSection->mIndices) + DstSection->mIndices.Add(IndexRemap[Index]); } else { - mHasTextures = true; - - for (int SrcVertexIdx = 0; SrcVertexIdx < VertexCount; SrcVertexIdx++) + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx += 3) { - const lcLibraryMeshVertex& SrcVertex = DataVertices[SrcVertexIdx]; - lcVector3 Position = lcMul31(SrcVertex.Position, Transform); - lcVector2 TexCoord = lcCalculateTexCoord(Position, TextureMap); - int Index; - - if (DataVertices[SrcVertexIdx].NormalWeight == 0.0f) - Index = AddTexturedVertex((lcMeshDataType)DestIndex, Position, TexCoord, true); - else - { - lcVector3 Normal = lcNormalize(lcMul30(DataVertices[SrcVertexIdx].Normal, Transform)); - if (InvertNormals) - Normal = -Normal; - Index = AddTexturedVertex((lcMeshDataType)DestIndex, Position, Normal, TexCoord, true); - } - - IndexRemap.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 = nullptr; - quint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor; - lcTexture* Texture; - lcMeshPrimitiveType PrimitiveType = SrcSection->mPrimitiveType; - - if (SrcSection->mTexture) - Texture = SrcSection->mTexture; - else if (TextureMap && SrcSection->mPrimitiveType == LC_MESH_TRIANGLES) - { - Texture = TextureMap->Texture; - PrimitiveType = LC_MESH_TEXTURED_TRIANGLES; - } - else - Texture = nullptr; - - for (int DstSectionIdx = 0; DstSectionIdx < Sections.GetSize(); DstSectionIdx++) - { - lcLibraryMeshSection* Section = Sections[DstSectionIdx]; - - if (Section->mColor == ColorCode && Section->mPrimitiveType == PrimitiveType && Section->mTexture == Texture) - { - DstSection = Section; - break; - } - } - - if (!DstSection) - { - DstSection = new lcLibraryMeshSection(PrimitiveType, ColorCode, Texture); - - Sections.Add(DstSection); - } - - DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); - - if (!InvertWinding || (PrimitiveType != LC_MESH_TRIANGLES && PrimitiveType != LC_MESH_TEXTURED_TRIANGLES)) - { - 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 += 3) - { - DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx + 2]]); - DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx + 1]]); - DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx + 0]]); - } + DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx + 2]]); + DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx + 1]]); + DstSection->mIndices.Add(IndexRemap[SrcSection->mIndices[IndexIdx + 0]]); } } } } -void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex) +void lcMeshLoaderTypeData::AddMeshDataNoDuplicateCheck(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap) { - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) + const lcArray& DataVertices = Data.mVertices; + quint32 BaseIndex; + + if (!TextureMap) { - int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex; - const lcArray& DataVertices = Data.mVertices[MeshDataIdx]; - lcArray& Vertices = mVertices[DestIndex]; - quint32 BaseIndex; + BaseIndex = mVertices.GetSize(); - if (!TextureMap) + mVertices.SetGrow(lcMin(mVertices.GetSize(), 8 * 1024 * 1024)); + mVertices.AllocGrow(DataVertices.GetSize()); + + for (int SrcVertexIdx = 0; SrcVertexIdx < DataVertices.GetSize(); SrcVertexIdx++) { - BaseIndex = Vertices.GetSize(); + const lcMeshLoaderVertex& SrcVertex = DataVertices[SrcVertexIdx]; + lcMeshLoaderVertex& DstVertex = mVertices.Add(); + DstVertex.Position = lcMul31(SrcVertex.Position, Transform); + DstVertex.Normal = lcNormalize(lcMul30(SrcVertex.Normal, Transform)); + if (InvertNormals) + DstVertex.Normal = -DstVertex.Normal; + DstVertex.NormalWeight = SrcVertex.NormalWeight; + DstVertex.TexCoord = SrcVertex.TexCoord; + DstVertex.Usage = SrcVertex.Usage; + } + } + else + { + BaseIndex = mVertices.GetSize(); - Vertices.SetGrow(lcMin(Vertices.GetSize(), 8 * 1024 * 1024)); - Vertices.AllocGrow(DataVertices.GetSize()); + mVertices.AllocGrow(DataVertices.GetSize()); - for (int SrcVertexIdx = 0; SrcVertexIdx < DataVertices.GetSize(); SrcVertexIdx++) - { - const lcLibraryMeshVertex& SrcVertex = DataVertices[SrcVertexIdx]; - lcLibraryMeshVertex& DstVertex = Vertices.Add(); - DstVertex.Position = lcMul31(SrcVertex.Position, Transform); - DstVertex.Normal = lcNormalize(lcMul30(SrcVertex.Normal, Transform)); - if (InvertNormals) - DstVertex.Normal = -DstVertex.Normal; - DstVertex.NormalWeight = SrcVertex.NormalWeight; - DstVertex.TexCoord = SrcVertex.TexCoord; - DstVertex.Usage = SrcVertex.Usage; - } + for (int SrcVertexIdx = 0; SrcVertexIdx < DataVertices.GetSize(); SrcVertexIdx++) + { + const lcMeshLoaderVertex& SrcVertex = DataVertices[SrcVertexIdx]; + lcMeshLoaderVertex& DstVertex = mVertices.Add(); + + lcVector3 Position = lcMul31(SrcVertex.Position, Transform); + lcVector2 TexCoord = lcCalculateTexCoord(Position, TextureMap); + + DstVertex.Position = Position; + DstVertex.Normal = lcNormalize(lcMul30(SrcVertex.Normal, Transform)); + if (InvertNormals) + DstVertex.Normal = -DstVertex.Normal; + DstVertex.NormalWeight = SrcVertex.NormalWeight; + DstVertex.TexCoord = TexCoord; + DstVertex.Usage = LC_LIBRARY_VERTEX_TEXTURED; + } + } + + mConditionalVertices.AllocGrow(Data.mConditionalVertices.GetSize()); + quint32 BaseConditional = mConditionalVertices.GetSize(); + + for (const lcMeshLoaderConditionalVertex& DataVertex : Data.mConditionalVertices) + { + lcMeshLoaderConditionalVertex& Vertex = mConditionalVertices.Add(); + + Vertex.Position[0] = lcMul31(DataVertex.Position[0], Transform); + Vertex.Position[1] = lcMul31(DataVertex.Position[1], Transform); + Vertex.Position[2] = lcMul31(DataVertex.Position[2], Transform); + Vertex.Position[3] = lcMul31(DataVertex.Position[3], Transform); + } + + for (const std::unique_ptr& SrcSection : Data.mSections) + { + quint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor; + lcTexture* Texture; + lcMeshPrimitiveType PrimitiveType = SrcSection->mPrimitiveType; + + if (SrcSection->mTexture) + Texture = SrcSection->mTexture; + else if (TextureMap && SrcSection->mPrimitiveType == LC_MESH_TRIANGLES) + { + Texture = TextureMap->Texture; + PrimitiveType = LC_MESH_TEXTURED_TRIANGLES; + } + else + Texture = nullptr; + + lcLibraryMeshSection* DstSection = AddSection(SrcSection->mPrimitiveType, ColorCode, Texture); + DstSection->mIndices.SetGrow(lcMin(DstSection->mIndices.GetSize(), 8 * 1024 * 1024)); + DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); + + if (PrimitiveType == LC_MESH_CONDITIONAL_LINES) + { + for (quint32 Index : SrcSection->mIndices) + DstSection->mIndices.Add(BaseConditional + Index); + } + else if (!InvertWinding || (PrimitiveType == LC_MESH_LINES)) + { + for (quint32 Index : SrcSection->mIndices) + DstSection->mIndices.Add(BaseIndex + Index); } else { - mHasTextures = true; - BaseIndex = Vertices.GetSize(); - - Vertices.AllocGrow(DataVertices.GetSize()); - - for (int SrcVertexIdx = 0; SrcVertexIdx < DataVertices.GetSize(); SrcVertexIdx++) + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx += 3) { - const lcLibraryMeshVertex& SrcVertex = DataVertices[SrcVertexIdx]; - lcLibraryMeshVertex& DstVertex = Vertices.Add(); - - lcVector3 Position = lcMul31(SrcVertex.Position, Transform); - lcVector2 TexCoord = lcCalculateTexCoord(Position, TextureMap); - - DstVertex.Position = Position; - DstVertex.Normal = lcNormalize(lcMul30(SrcVertex.Normal, Transform)); - if (InvertNormals) - DstVertex.Normal = -DstVertex.Normal; - DstVertex.NormalWeight = SrcVertex.NormalWeight; - DstVertex.TexCoord = TexCoord; - DstVertex.Usage = LC_LIBRARY_VERTEX_TEXTURED; - } - } - - const lcArray& DataSections = Data.mSections[MeshDataIdx]; - lcArray& Sections = mSections[DestIndex]; - - for (int SrcSectionIdx = 0; SrcSectionIdx < DataSections.GetSize(); SrcSectionIdx++) - { - lcLibraryMeshSection* SrcSection = DataSections[SrcSectionIdx]; - lcLibraryMeshSection* DstSection = nullptr; - quint32 ColorCode = SrcSection->mColor == 16 ? CurrentColorCode : SrcSection->mColor; - lcTexture* Texture; - - if (SrcSection->mTexture) - Texture = SrcSection->mTexture; - else if (TextureMap) - Texture = TextureMap->Texture; - else - Texture = nullptr; - - 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.SetGrow(lcMin(DstSection->mIndices.GetSize(), 8 * 1024 * 1024)); - DstSection->mIndices.AllocGrow(SrcSection->mIndices.GetSize()); - - if (!InvertWinding || (SrcSection->mPrimitiveType != LC_MESH_TRIANGLES && SrcSection->mPrimitiveType != LC_MESH_TEXTURED_TRIANGLES)) - { - 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 += 3) - { - DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx + 2]); - DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx + 1]); - DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx + 0]); - } + DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx + 2]); + DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx + 1]); + DstSection->mIndices.Add(BaseIndex + SrcSection->mIndices[IndexIdx + 0]); } } } } +void lcLibraryMeshData::AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcMeshLoaderVertex** VertexBuffer) +{ + lcArray& Vertices = mData[MeshDataType].mVertices; + int CurrentSize = Vertices.GetSize(); + + Vertices.SetSize(CurrentSize + VertexCount); + + *BaseVertex = CurrentSize; + *VertexBuffer = &Vertices[CurrentSize]; +} + +void lcLibraryMeshData::AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer) +{ + lcLibraryMeshSection* Section = mData[MeshDataType].AddSection(PrimitiveType, ColorCode, nullptr); + lcArray& Indices = Section->mIndices; + int CurrentSize = Indices.GetSize(); + + Indices.SetSize(CurrentSize + IndexCount); + + *IndexBuffer = &Indices[CurrentSize]; +} + +void lcLibraryMeshData::AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex) +{ + for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) + { + const int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex; + mData[DestIndex].AddMeshData(Data.mData[MeshDataIdx], Transform, CurrentColorCode, InvertWinding, InvertNormals, TextureMap); + } + + mHasTextures |= (Data.mHasTextures || TextureMap); +} + +void lcLibraryMeshData::AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex) +{ + for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) + { + const int DestIndex = OverrideDestIndex == LC_MESHDATA_SHARED ? MeshDataIdx : OverrideDestIndex; + mData[DestIndex].AddMeshDataNoDuplicateCheck(Data.mData[MeshDataIdx], Transform, CurrentColorCode, InvertWinding, InvertNormals, TextureMap); + } + + mHasTextures |= (Data.mHasTextures || TextureMap); +} + struct lcMergeSection { lcLibraryMeshSection* Shared; @@ -886,8 +904,10 @@ lcMesh* lcLibraryMeshData::CreateMesh() int BaseVertices[LC_NUM_MESHDATA_TYPES]; int BaseTexturedVertices[LC_NUM_MESHDATA_TYPES]; + int BaseConditionalVertices[LC_NUM_MESHDATA_TYPES]; int NumVertices = 0; int NumTexturedVertices = 0; + int ConditionalVertexCount = 0; std::vector IndexRemap[LC_NUM_MESHDATA_TYPES]; std::vector TexturedIndexRemap[LC_NUM_MESHDATA_TYPES]; @@ -895,40 +915,36 @@ lcMesh* lcLibraryMeshData::CreateMesh() { for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) { - lcArray& Sections = mSections[MeshDataIdx]; + std::vector>& Sections = mData[MeshDataIdx].mSections; - for (int SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++) - { - lcLibraryMeshSection* Section = Sections[SectionIdx]; + for (const std::unique_ptr& Section : Sections) Section->mColor = lcGetColorIndex(Section->mColor); - } BaseVertices[MeshDataIdx] = NumVertices; - NumVertices += mVertices[MeshDataIdx].GetSize(); + NumVertices += mData[MeshDataIdx].mVertices.GetSize(); + BaseConditionalVertices[MeshDataIdx] = ConditionalVertexCount; + ConditionalVertexCount += mData[MeshDataIdx].mConditionalVertices.GetSize(); } } else { for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) { - lcArray& Sections = mSections[MeshDataIdx]; + std::vector>& Sections = mData[MeshDataIdx].mSections; - for (int SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++) - { - lcLibraryMeshSection* Section = Sections[SectionIdx]; + for (const std::unique_ptr& Section : Sections) Section->mColor = lcGetColorIndex(Section->mColor); - } BaseVertices[MeshDataIdx] = NumVertices; BaseTexturedVertices[MeshDataIdx] = NumTexturedVertices; - const lcArray& Vertices = mVertices[MeshDataIdx]; + const lcArray& Vertices = mData[MeshDataIdx].mVertices; IndexRemap[MeshDataIdx].resize(Vertices.GetSize()); TexturedIndexRemap[MeshDataIdx].resize(Vertices.GetSize()); for (int VertexIdx = 0; VertexIdx < Vertices.GetSize(); VertexIdx++) { - const lcLibraryMeshVertex& Vertex = Vertices[VertexIdx]; + const lcMeshLoaderVertex& Vertex = Vertices[VertexIdx]; if (Vertex.Usage & LC_LIBRARY_VERTEX_UNTEXTURED) { @@ -942,6 +958,9 @@ lcMesh* lcLibraryMeshData::CreateMesh() NumTexturedVertices++; } } + + BaseConditionalVertices[MeshDataIdx] = ConditionalVertexCount; + ConditionalVertexCount += mData[MeshDataIdx].mConditionalVertices.GetSize(); } } @@ -952,34 +971,32 @@ lcMesh* lcLibraryMeshData::CreateMesh() for (int LodIdx = 0; LodIdx < LC_NUM_MESH_LODS; LodIdx++) { - const lcArray& SharedSections = mSections[LC_MESHDATA_SHARED]; - const lcArray& Sections = mSections[LodIdx]; + std::vector>& SharedSections = mData[LC_MESHDATA_SHARED].mSections; + std::vector>& Sections = mData[LodIdx].mSections; - for (int SharedSectionIdx = 0; SharedSectionIdx < SharedSections.GetSize(); SharedSectionIdx++) + for (std::unique_ptr& SharedSection : SharedSections) { - lcLibraryMeshSection* SharedSection = SharedSections[SharedSectionIdx]; NumIndices += SharedSection->mIndices.GetSize(); lcMergeSection& MergeSection = MergeSections[LodIdx].Add(); - MergeSection.Shared = SharedSection; + MergeSection.Shared = SharedSection.get(); MergeSection.Lod = nullptr; } - for (int SectionIdx = 0; SectionIdx < Sections.GetSize(); SectionIdx++) + for (std::unique_ptr& Section : Sections) { - lcLibraryMeshSection* Section = Sections[SectionIdx]; bool Found = false; NumIndices += Section->mIndices.GetSize(); - for (int SharedSectionIdx = 0; SharedSectionIdx < SharedSections.GetSize(); SharedSectionIdx++) + for (int SharedSectionIdx = 0; SharedSectionIdx < (int)SharedSections.size(); SharedSectionIdx++) { - lcLibraryMeshSection* SharedSection = SharedSections[SharedSectionIdx]; + lcLibraryMeshSection* SharedSection = SharedSections[SharedSectionIdx].get(); if (SharedSection->mColor == Section->mColor && SharedSection->mPrimitiveType == Section->mPrimitiveType && SharedSection->mTexture == Section->mTexture) { lcMergeSection& MergeSection = MergeSections[LodIdx][SharedSectionIdx]; - MergeSection.Lod = Section; + MergeSection.Lod = Section.get(); Found = true; break; } @@ -989,7 +1006,7 @@ lcMesh* lcLibraryMeshData::CreateMesh() { lcMergeSection& MergeSection = MergeSections[LodIdx].Add(); MergeSection.Shared = nullptr; - MergeSection.Lod = Section; + MergeSection.Lod = Section.get(); } } @@ -997,17 +1014,15 @@ lcMesh* lcLibraryMeshData::CreateMesh() std::sort(MergeSections[LodIdx].begin(), MergeSections[LodIdx].end(), lcLibraryMeshSectionCompare); } - Mesh->Create(NumSections, NumVertices, NumTexturedVertices, NumIndices); + Mesh->Create(NumSections, NumVertices, NumTexturedVertices, ConditionalVertexCount, NumIndices); lcVertex* DstVerts = (lcVertex*)Mesh->mVertexData; if (!mHasTextures) { - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) + for (lcMeshLoaderTypeData& Data : mData) { - const lcArray& Vertices = mVertices[MeshDataIdx]; - - for (const lcLibraryMeshVertex& SrcVertex : Vertices) + for (const lcMeshLoaderVertex& SrcVertex : Data.mVertices) { lcVertex& DstVertex = *DstVerts++; @@ -1015,12 +1030,27 @@ lcMesh* lcLibraryMeshData::CreateMesh() DstVertex.Normal = lcPackNormal(lcVector3LDrawToLeoCAD(SrcVertex.Normal)); } } + + lcVertexConditional* DstConditionalVerts = (lcVertexConditional*)DstVerts; + + for (lcMeshLoaderTypeData& Data : mData) + { + for (const lcMeshLoaderConditionalVertex& SrcVertex : Data.mConditionalVertices) + { + lcVertexConditional& DstVertex = *DstConditionalVerts++; + + DstVertex.Position1 = lcVector3LDrawToLeoCAD(SrcVertex.Position[0]); + DstVertex.Position2 = lcVector3LDrawToLeoCAD(SrcVertex.Position[1]); + DstVertex.Position3 = lcVector3LDrawToLeoCAD(SrcVertex.Position[2]); + DstVertex.Position4 = lcVector3LDrawToLeoCAD(SrcVertex.Position[3]); + } + } } else { - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) + for (lcMeshLoaderTypeData& Data : mData) { - for (const lcLibraryMeshVertex& SrcVertex : mVertices[MeshDataIdx]) + for (const lcMeshLoaderVertex& SrcVertex : Data.mVertices) { if ((SrcVertex.Usage & LC_LIBRARY_VERTEX_UNTEXTURED) == 0) continue; @@ -1034,9 +1064,9 @@ lcMesh* lcLibraryMeshData::CreateMesh() lcVertexTextured* DstTexturedVerts = (lcVertexTextured*)DstVerts; - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) + for (lcMeshLoaderTypeData& Data : mData) { - for (const lcLibraryMeshVertex& SrcVertex : mVertices[MeshDataIdx]) + for (const lcMeshLoaderVertex& SrcVertex : Data.mVertices) { if ((SrcVertex.Usage & LC_LIBRARY_VERTEX_TEXTURED) == 0) continue; @@ -1051,7 +1081,7 @@ lcMesh* lcLibraryMeshData::CreateMesh() for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) { - for (lcLibraryMeshSection* Section : mSections[MeshDataIdx]) + for (const std::unique_ptr& Section : mData[MeshDataIdx].mSections) { if (Section->mPrimitiveType == LC_MESH_TRIANGLES) { @@ -1073,6 +1103,21 @@ lcMesh* lcLibraryMeshData::CreateMesh() } } } + + lcVertexConditional* DstConditionalVerts = (lcVertexConditional*)DstTexturedVerts; + + for (lcMeshLoaderTypeData& Data : mData) + { + for (const lcMeshLoaderConditionalVertex& SrcVertex : Data.mConditionalVertices) + { + lcVertexConditional& DstVertex = *DstConditionalVerts++; + + DstVertex.Position1 = lcVector3LDrawToLeoCAD(SrcVertex.Position[0]); + DstVertex.Position2 = lcVector3LDrawToLeoCAD(SrcVertex.Position[1]); + DstVertex.Position3 = lcVector3LDrawToLeoCAD(SrcVertex.Position[2]); + DstVertex.Position4 = lcVector3LDrawToLeoCAD(SrcVertex.Position[3]); + } + } } NumIndices = 0; @@ -1104,16 +1149,26 @@ lcMesh* lcLibraryMeshData::CreateMesh() { lcLibraryMeshSection* SrcSection = MergeSection.Shared; - if (!mHasTextures) + if (DstSection.PrimitiveType != LC_MESH_CONDITIONAL_LINES) { - quint16 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LC_MESHDATA_SHARED] : BaseVertices[LC_MESHDATA_SHARED]; + if (!mHasTextures) + { + quint16 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LC_MESHDATA_SHARED] : BaseVertices[LC_MESHDATA_SHARED]; + + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; + } + else + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = SrcSection->mIndices[IndexIdx]; + } + else + { + quint16 BaseVertex = BaseConditionalVertices[LC_MESHDATA_SHARED]; for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; } - else - for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) - *Index++ = SrcSection->mIndices[IndexIdx]; DstSection.NumIndices += SrcSection->mIndices.GetSize(); } @@ -1122,16 +1177,26 @@ lcMesh* lcLibraryMeshData::CreateMesh() { lcLibraryMeshSection* SrcSection = MergeSection.Lod; - if (!mHasTextures) + if (DstSection.PrimitiveType != LC_MESH_CONDITIONAL_LINES) { - quint16 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LodIdx] : BaseVertices[LodIdx]; + if (!mHasTextures) + { + quint16 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LodIdx] : BaseVertices[LodIdx]; + + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; + } + else + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = SrcSection->mIndices[IndexIdx]; + } + else + { + quint16 BaseVertex = BaseConditionalVertices[LodIdx]; for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; } - else - for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) - *Index++ = SrcSection->mIndices[IndexIdx]; DstSection.NumIndices += SrcSection->mIndices.GetSize(); } @@ -1144,22 +1209,58 @@ lcMesh* lcLibraryMeshData::CreateMesh() if (MergeSection.Shared) { - quint32 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]; + if (DstSection.PrimitiveType != LC_MESH_CONDITIONAL_LINES) + { + if (!mHasTextures) + { + quint32 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LC_MESHDATA_SHARED] : BaseVertices[LC_MESHDATA_SHARED]; + + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; + } + else + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = SrcSection->mIndices[IndexIdx]; + } + else + { + quint32 BaseVertex = BaseConditionalVertices[LC_MESHDATA_SHARED]; + + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; + } DstSection.NumIndices += SrcSection->mIndices.GetSize(); } if (MergeSection.Lod) { - quint32 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]; + if (DstSection.PrimitiveType != LC_MESH_CONDITIONAL_LINES) + { + if (!mHasTextures) + { + quint32 BaseVertex = DstSection.Texture ? BaseTexturedVertices[LodIdx] : BaseVertices[LodIdx]; + + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; + + DstSection.NumIndices += SrcSection->mIndices.GetSize(); + } + else + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = SrcSection->mIndices[IndexIdx]; + } + else + { + quint16 BaseVertex = BaseConditionalVertices[LodIdx]; + + for (int IndexIdx = 0; IndexIdx < SrcSection->mIndices.GetSize(); IndexIdx++) + *Index++ = BaseVertex + SrcSection->mIndices[IndexIdx]; + } DstSection.NumIndices += SrcSection->mIndices.GetSize(); } @@ -1208,13 +1309,27 @@ lcMesh* lcLibraryMeshData::CreateMesh() if (!Section.Texture) { - const lcVertex* VertexBuffer = static_cast(Mesh->mVertexData); - - for (int Index = 0; Index < Section.NumIndices; Index++) + if (Section.PrimitiveType != LC_MESH_CONDITIONAL_LINES) { - const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position; - SectionMin = lcMin(SectionMin, Position); - SectionMax = lcMax(SectionMax, Position); + const lcVertex* VertexBuffer = static_cast(Mesh->mVertexData); + + for (int Index = 0; Index < Section.NumIndices; Index++) + { + const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position; + SectionMin = lcMin(SectionMin, Position); + SectionMax = lcMax(SectionMax, Position); + } + } + else + { + const lcVertexConditional* VertexBuffer = reinterpret_cast(static_cast(Mesh->mVertexData) + Mesh->mNumVertices * sizeof(lcVertex) + Mesh->mNumTexturedVertices * sizeof(lcVertexTextured)); + + for (int Index = 0; Index < Section.NumIndices; Index++) + { + const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position1; + SectionMin = lcMin(SectionMin, Position); + SectionMax = lcMax(SectionMax, Position); + } } } else @@ -1235,13 +1350,27 @@ lcMesh* lcLibraryMeshData::CreateMesh() if (!Section.Texture) { - const lcVertex* VertexBuffer = static_cast(Mesh->mVertexData); - - for (int Index = 0; Index < Section.NumIndices; Index++) + if (Section.PrimitiveType != LC_MESH_CONDITIONAL_LINES) { - const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position; - SectionMin = lcMin(SectionMin, Position); - SectionMax = lcMax(SectionMax, Position); + const lcVertex* VertexBuffer = static_cast(Mesh->mVertexData); + + for (int Index = 0; Index < Section.NumIndices; Index++) + { + const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position; + SectionMin = lcMin(SectionMin, Position); + SectionMax = lcMax(SectionMax, Position); + } + } + else + { + const lcVertexConditional* VertexBuffer = reinterpret_cast(static_cast(Mesh->mVertexData) + Mesh->mNumVertices * sizeof(lcVertex) + Mesh->mNumTexturedVertices * sizeof(lcVertexTextured)); + + for (int Index = 0; Index < Section.NumIndices; Index++) + { + const lcVector3& Position = VertexBuffer[IndexBuffer[Index]].Position1; + SectionMin = lcMin(SectionMin, Position); + SectionMax = lcMax(SectionMax, Position); + } } } else @@ -1287,12 +1416,12 @@ lcMeshLoader::lcMeshLoader(lcLibraryMeshData& MeshData, bool Optimize, Project* bool lcMeshLoader::LoadMesh(lcFile& File, lcMeshDataType MeshDataType) { - lcArray TextureStack; + lcArray TextureStack; return ReadMeshData(File, lcMatrix44Identity(), 16, false, TextureStack, MeshDataType); } -bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcArray& TextureStack, lcMeshDataType MeshDataType) +bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcArray& TextureStack, lcMeshDataType MeshDataType) { char Buffer[1024]; char* Line; @@ -1403,11 +1532,11 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform CleanTextureName(FileName); - lcLibraryTextureMap& Map = TextureStack.Add(); + lcMeshLoaderTextureMap& Map = TextureStack.Add(); Map.Next = false; Map.Fallback = false; Map.Texture = Library->FindTexture(FileName, mCurrentProject, mSearchProjectFolder); - Map.Type = lcLibraryTextureMapType::PLANAR; + Map.Type = lcMeshLoaderTextureMapType::Planar; for (int EdgeIdx = 0; EdgeIdx < 2; EdgeIdx++) { @@ -1437,12 +1566,12 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform CleanTextureName(FileName); - lcLibraryTextureMap& Map = TextureStack.Add(); + lcMeshLoaderTextureMap& Map = TextureStack.Add(); Map.Next = false; Map.Fallback = false; Map.Texture = Library->FindTexture(FileName, mCurrentProject, mSearchProjectFolder); - Map.Type = lcLibraryTextureMapType::CYLINDRICAL; + Map.Type = lcMeshLoaderTextureMapType::Cylindrical; lcVector3 Up = Points[0] - Points[1]; float UpLength = lcLength(Up); lcVector3 Front = lcNormalize(Points[2] - Points[1]); @@ -1470,11 +1599,11 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform CleanTextureName(FileName); - lcLibraryTextureMap& Map = TextureStack.Add(); + lcMeshLoaderTextureMap& Map = TextureStack.Add(); Map.Next = false; Map.Fallback = false; Map.Texture = Library->FindTexture(FileName, mCurrentProject, mSearchProjectFolder); - Map.Type = lcLibraryTextureMapType::SPHERICAL; + Map.Type = lcMeshLoaderTextureMapType::Spherical; lcVector3 Front = lcNormalize(Points[1] - Points[0]); lcVector3 Plane1Normal = lcNormalize(lcCross(Front, Points[2] - Points[0])); @@ -1554,7 +1683,7 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform if (ColorCode == 16) ColorCode = CurrentColorCode; - lcLibraryTextureMap* TextureMap = nullptr; + lcMeshLoaderTextureMap* TextureMap = nullptr; if (TextureStack.GetSize()) { @@ -1637,7 +1766,7 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform Points[0] = lcMul31(Points[0], CurrentTransform); Points[1] = lcMul31(Points[1], CurrentTransform); - mMeshData.AddLine(MeshDataType, LineType, ColorCode, WindingCCW, Points, mOptimize); + mMeshData.mData[MeshDataType].ProcessLine(LineType, ColorCode, WindingCCW, Points, mOptimize); break; case 3: @@ -1650,13 +1779,14 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform if (TextureMap) { - mMeshData.AddTexturedLine(MeshDataType, LineType, ColorCode, WindingCCW, *TextureMap, Points, mOptimize); + mMeshData.mHasTextures = true; + mMeshData.mData[MeshDataType].ProcessTexturedLine(LineType, ColorCode, WindingCCW, *TextureMap, Points, mOptimize); if (TextureMap->Next) TextureStack.RemoveIndex(TextureStack.GetSize() - 1); } else - mMeshData.AddLine(MeshDataType, LineType, ColorCode, WindingCCW, Points, mOptimize); + mMeshData.mData[MeshDataType].ProcessLine(LineType, ColorCode, WindingCCW, Points, mOptimize); break; case 4: @@ -1670,13 +1800,14 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform if (TextureMap) { - mMeshData.AddTexturedLine(MeshDataType, LineType, ColorCode, WindingCCW, *TextureMap, Points, mOptimize); + mMeshData.mHasTextures = true; + mMeshData.mData[MeshDataType].ProcessTexturedLine(LineType, ColorCode, WindingCCW, *TextureMap, Points, mOptimize); if (TextureMap->Next) TextureStack.RemoveIndex(TextureStack.GetSize() - 1); } else - mMeshData.AddLine(MeshDataType, LineType, ColorCode, WindingCCW, Points, mOptimize); + mMeshData.mData[MeshDataType].ProcessLine(LineType, ColorCode, WindingCCW, Points, mOptimize); break; case 5: @@ -1688,7 +1819,7 @@ bool lcMeshLoader::ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform Points[2] = lcMul31(Points[2], CurrentTransform); Points[3] = lcMul31(Points[3], CurrentTransform); - mMeshData.AddLine(MeshDataType, LineType, ColorCode, WindingCCW, Points, mOptimize); + mMeshData.mData[MeshDataType].ProcessLine(LineType, ColorCode, WindingCCW, Points, mOptimize); break; } diff --git a/common/lc_meshloader.h b/common/lc_meshloader.h index 4a556fda..a64efab6 100644 --- a/common/lc_meshloader.h +++ b/common/lc_meshloader.h @@ -15,7 +15,7 @@ enum lcMeshDataType LC_NUM_MESHDATA_TYPES }; -struct lcLibraryMeshVertex +struct lcMeshLoaderVertex { lcVector3 Position; lcVector3 Normal; @@ -24,6 +24,11 @@ struct lcLibraryMeshVertex quint32 Usage; }; +struct lcMeshLoaderConditionalVertex +{ + lcVector3 Position[4]; +}; + class lcLibraryMeshSection { public: @@ -41,14 +46,14 @@ public: lcArray mIndices; }; -enum class lcLibraryTextureMapType +enum class lcMeshLoaderTextureMapType { - PLANAR, - CYLINDRICAL, - SPHERICAL + Planar, + Cylindrical, + Spherical }; -struct lcLibraryTextureMap +struct lcMeshLoaderTextureMap { lcTexture* Texture; @@ -82,11 +87,54 @@ struct lcLibraryTextureMap float Angle1; float Angle2; - lcLibraryTextureMapType Type; + lcMeshLoaderTextureMapType Type; bool Fallback; bool Next; }; +class lcMeshLoaderTypeData +{ +public: + lcMeshLoaderTypeData() + { + mVertices.SetGrow(1024); + mConditionalVertices.SetGrow(1024); + } + + lcMeshLoaderTypeData(const lcMeshLoaderTypeData&) = delete; + lcMeshLoaderTypeData& operator=(const lcMeshLoaderTypeData&) = delete; + + bool IsEmpty() const + { + return mSections.empty(); + } + + void Clear() + { + mSections.clear(); + mVertices.RemoveAll(); + mConditionalVertices.RemoveAll(); + } + + lcLibraryMeshSection* AddSection(lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, lcTexture* Texture); + + 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 AddConditionalVertex(const lcVector3* Position, bool Optimize); + + void ProcessLine(int LineType, quint32 ColorCode, bool WindingCCW, lcVector3* Vertices, bool Optimize); + void ProcessTexturedLine(int LineType, quint32 ColorCode, bool WindingCCW, const lcMeshLoaderTextureMap& Map, const lcVector3* Vertices, bool Optimize); + + void AddMeshData(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap); + void AddMeshDataNoDuplicateCheck(const lcMeshLoaderTypeData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap); + + std::vector> mSections; + lcArray mVertices; + lcArray mConditionalVertices; +}; + class lcLibraryMeshData { public: @@ -94,59 +142,36 @@ public: { mHasTextures = false; mHasStyleStud = false; - - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) - mVertices[MeshDataIdx].SetGrow(1024); - } - - ~lcLibraryMeshData() - { - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) - mSections[MeshDataIdx].DeleteAll(); } lcLibraryMeshData(const lcLibraryMeshData&) = delete; - lcLibraryMeshData(lcLibraryMeshData&&) = delete; lcLibraryMeshData& operator=(const lcLibraryMeshData&) = delete; - lcLibraryMeshData& operator=(lcLibraryMeshData&&) = delete; bool IsEmpty() const { - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) - if (!mSections[MeshDataIdx].IsEmpty()) + for (const lcMeshLoaderTypeData& Data : mData) + if (!Data.IsEmpty()) return false; return true; } - void RemoveAll() + void Clear() { - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) - mVertices[MeshDataIdx].RemoveAll(); - - for (int MeshDataIdx = 0; MeshDataIdx < LC_NUM_MESHDATA_TYPES; MeshDataIdx++) - mSections[MeshDataIdx].RemoveAll(); + for (lcMeshLoaderTypeData& Data : mData) + Data.Clear(); mHasTextures = false; + mHasStyleStud = false; } lcMesh* CreateMesh(); - lcLibraryMeshSection* AddSection(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, lcTexture* Texture); - quint32 AddVertex(lcMeshDataType MeshDataType, const lcVector3& Position, bool Optimize); - quint32 AddVertex(lcMeshDataType MeshDataType, const lcVector3& Position, const lcVector3& Normal, bool Optimize); - quint32 AddTexturedVertex(lcMeshDataType MeshDataType, const lcVector3& Position, const lcVector2& TexCoord, bool Optimize); - quint32 AddTexturedVertex(lcMeshDataType MeshDataType, const lcVector3& Position, const lcVector3& Normal, const lcVector2& TexCoord, bool Optimize); - void AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcLibraryMeshVertex** VertexBuffer); + void AddVertices(lcMeshDataType MeshDataType, int VertexCount, int* BaseVertex, lcMeshLoaderVertex** VertexBuffer); void AddIndices(lcMeshDataType MeshDataType, lcMeshPrimitiveType PrimitiveType, quint32 ColorCode, int IndexCount, quint32** IndexBuffer); - void AddLine(lcMeshDataType MeshDataType, int LineType, quint32 ColorCode, bool WindingCCW, const lcVector3* Vertices, bool Optimize); - void AddTexturedLine(lcMeshDataType MeshDataType, int LineType, quint32 ColorCode, bool WindingCCW, const lcLibraryTextureMap& Map, const lcVector3* Vertices, bool Optimize); - void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex); - void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcLibraryTextureMap* TextureMap, lcMeshDataType OverrideDestIndex); - void TestQuad(int* QuadIndices, const lcVector3* Vertices); - void ResequenceQuad(int* QuadIndices, int a, int b, int c, int d); + void AddMeshData(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex); + void AddMeshDataNoDuplicateCheck(const lcLibraryMeshData& Data, const lcMatrix44& Transform, quint32 CurrentColorCode, bool InvertWinding, bool InvertNormals, lcMeshLoaderTextureMap* TextureMap, lcMeshDataType OverrideDestIndex); - lcArray mSections[LC_NUM_MESHDATA_TYPES]; - lcArray mVertices[LC_NUM_MESHDATA_TYPES]; + std::array mData; bool mHasTextures; bool mHasStyleStud; }; @@ -159,7 +184,7 @@ public: bool LoadMesh(lcFile& File, lcMeshDataType MeshDataType); protected: - bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcArray& TextureStack, lcMeshDataType MeshDataType); + bool ReadMeshData(lcFile& File, const lcMatrix44& CurrentTransform, quint32 CurrentColorCode, bool InvertWinding, lcArray& TextureStack, lcMeshDataType MeshDataType); lcLibraryMeshData& mMeshData; bool mOptimize; diff --git a/common/lc_scene.cpp b/common/lc_scene.cpp index 4017dddc..49341c1b 100644 --- a/common/lc_scene.cpp +++ b/common/lc_scene.cpp @@ -242,53 +242,16 @@ void lcScene::DrawOpaqueMeshes(lcContext* Context, bool DrawLit, int PrimitiveTy } else if (Section->PrimitiveType == LC_MESH_CONDITIONAL_LINES) { - const lcMatrix44 WorldViewProjectionMatrix = lcMul(RenderMesh.WorldMatrix, lcMul(mViewMatrix, Context->GetProjectionMatrix())); - const lcVertex* const VertexBuffer = (lcVertex*)Mesh->mVertexData; + int VertexBufferOffset = Mesh->mVertexCacheOffset != -1 ? Mesh->mVertexCacheOffset : 0; + VertexBufferOffset += Mesh->mNumVertices * sizeof(lcVertex) + Mesh->mNumTexturedVertices * sizeof(lcVertexTextured); const int IndexBufferOffset = Mesh->mIndexCacheOffset != -1 ? Mesh->mIndexCacheOffset : 0; - const int VertexBufferOffset = Mesh->mVertexCacheOffset != -1 ? Mesh->mVertexCacheOffset : 0; - Context->SetVertexFormat(VertexBufferOffset, 3, 1, 0, 0, DrawLit); + Context->SetEdgeColorIndex(ColorIndex); + Context->SetMaterial(lcMaterialType::UnlitColorConditional); + Context->SetVertexFormatConditional(VertexBufferOffset); - if (Mesh->mIndexType == GL_UNSIGNED_SHORT) - { - const quint16* const Indices = (quint16*)((char*)Mesh->mIndexData + Section->IndexOffset); - - for (int i = 0; i < Section->NumIndices; i += 4) - { - lcVector4 p1 = lcMul4(lcVector4(VertexBuffer[Indices[i + 0]].Position, 1.0f), WorldViewProjectionMatrix); - lcVector4 p2 = lcMul4(lcVector4(VertexBuffer[Indices[i + 1]].Position, 1.0f), WorldViewProjectionMatrix); - lcVector4 p3 = lcMul4(lcVector4(VertexBuffer[Indices[i + 2]].Position, 1.0f), WorldViewProjectionMatrix); - lcVector4 p4 = lcMul4(lcVector4(VertexBuffer[Indices[i + 3]].Position, 1.0f), WorldViewProjectionMatrix); - - p1 /= p1.w; - p2 /= p2.w; - p3 /= p3.w; - p4 /= p4.w; - - if (((p1.y - p2.y) * (p3.x - p1.x) + (p2.x - p1.x) * (p3.y - p1.y)) * ((p1.y - p2.y) * (p4.x - p1.x) + (p2.x - p1.x) * (p4.y - p1.y)) >= 0) - Context->DrawIndexedPrimitives(GL_LINES, 2, Mesh->mIndexType, IndexBufferOffset + Section->IndexOffset + i * sizeof(quint16)); - } - } - else - { - const quint32* const Indices = (quint32*)((char*)Mesh->mIndexData + Section->IndexOffset); - - for (int i = 0; i < Section->NumIndices; i += 4) - { - lcVector4 p1 = lcMul4(lcVector4(VertexBuffer[Indices[i + 0]].Position, 1.0f), WorldViewProjectionMatrix); - lcVector4 p2 = lcMul4(lcVector4(VertexBuffer[Indices[i + 1]].Position, 1.0f), WorldViewProjectionMatrix); - lcVector4 p3 = lcMul4(lcVector4(VertexBuffer[Indices[i + 2]].Position, 1.0f), WorldViewProjectionMatrix); - lcVector4 p4 = lcMul4(lcVector4(VertexBuffer[Indices[i + 3]].Position, 1.0f), WorldViewProjectionMatrix); - - p1 /= p1.w; - p2 /= p2.w; - p3 /= p3.w; - p4 /= p4.w; - - if (((p1.y - p2.y) * (p3.x - p1.x) + (p2.x - p1.x) * (p3.y - p1.y)) * ((p1.y - p2.y) * (p4.x - p1.x) + (p2.x - p1.x) * (p4.y - p1.y)) >= 0) - Context->DrawIndexedPrimitives(GL_LINES, 2, Mesh->mIndexType, IndexBufferOffset + Section->IndexOffset + i * sizeof(quint32)); - } - } + const GLenum DrawPrimitiveType = Section->PrimitiveType & (LC_MESH_TRIANGLES | LC_MESH_TEXTURED_TRIANGLES) ? GL_TRIANGLES : GL_LINES; + Context->DrawIndexedPrimitives(DrawPrimitiveType, Section->NumIndices, Mesh->mIndexType, IndexBufferOffset + Section->IndexOffset); continue; } @@ -440,8 +403,9 @@ void lcScene::Draw(lcContext* Context) const Context->SetViewMatrix(mViewMatrix); - constexpr bool DrawConditional = false; const lcPreferences& Preferences = lcGetPreferences(); + const bool DrawLines = Preferences.mDrawEdgeLines && Preferences.mLineWidth != 0.0f; + const bool DrawConditional = false; // lcShadingMode ShadingMode = Preferences.mShadingMode; // if (ShadingMode == lcShadingMode::Wireframe && !mAllowWireframe) @@ -461,8 +425,6 @@ void lcScene::Draw(lcContext* Context) const } else if (mShadingMode == lcShadingMode::Flat) { - const bool DrawLines = Preferences.mDrawEdgeLines && Preferences.mLineWidth != 0.0f; - int LinePrimitiveTypes = 0; if (DrawLines) @@ -501,8 +463,6 @@ void lcScene::Draw(lcContext* Context) const } else { - const bool DrawLines = Preferences.mDrawEdgeLines && Preferences.mLineWidth != 0.0f; - int LinePrimitiveTypes = LC_MESH_LINES; if (DrawConditional) diff --git a/common/lc_synth.cpp b/common/lc_synth.cpp index 8ba4c4d0..5dd87f7e 100644 --- a/common/lc_synth.cpp +++ b/common/lc_synth.cpp @@ -935,7 +935,7 @@ void lcSynthInfoFlexSystemHose::AddParts(lcMemFile& File, lcLibraryMeshData& Mes File.WriteBuffer(Line, strlen(Line)); } - const lcLibraryMeshVertex OutsideSectionVertices[16] = + const lcMeshLoaderVertex OutsideSectionVertices[16] = { { lcVector3( 4.00000f, 0.0f, 0.00000f), lcVector3( 1.000000f, 0.0f, 0.000000f), 4.0f, lcVector2(0.0f, 0.0f), 0 }, { lcVector3( 3.69552f, 0.0f, 1.53073f), lcVector3( 0.923880f, 0.0f, 0.382683f), 4.0f, lcVector2(0.0f, 0.0f), 0 }, @@ -955,7 +955,7 @@ void lcSynthInfoFlexSystemHose::AddParts(lcMemFile& File, lcLibraryMeshData& Mes { lcVector3( 3.69552f, 0.0f, -1.53073f), lcVector3( 0.923880f, 0.0f, -0.382683f), 4.0f, lcVector2(0.0f, 0.0f), 0 }, }; - const lcLibraryMeshVertex InsideSectionVertices[16] = + const lcMeshLoaderVertex InsideSectionVertices[16] = { { lcVector3( 2.00000f, 0.0f, 0.00000f), lcVector3(-1.00000f, 0.0f, 0.00000f), 4.0f, lcVector2(0.0f, 0.0f), 0 }, { lcVector3( 1.84776f, 0.0f, 0.76536f), lcVector3(-0.92388f, 0.0f, -0.38268f), 4.0f, lcVector2(0.0f, 0.0f), 0 }, @@ -975,10 +975,10 @@ void lcSynthInfoFlexSystemHose::AddParts(lcMemFile& File, lcLibraryMeshData& Mes { lcVector3( 1.84776f, 0.0f, -0.76536f), lcVector3(-0.92388f, 0.0f, 0.38268f), 4.0f, lcVector2(0.0f, 0.0f), 0 }, }; - auto AddSectionVertices = [&MeshData, &Sections](const lcLibraryMeshVertex* SectionVertices, int NumSectionVertices) + auto AddSectionVertices = [&MeshData, &Sections](const lcMeshLoaderVertex* SectionVertices, int NumSectionVertices) { int BaseVertex; - lcLibraryMeshVertex* VertexBuffer; + lcMeshLoaderVertex* VertexBuffer; quint32* IndexBuffer; MeshData.AddVertices(LC_MESHDATA_SHARED, NumSectionVertices * (Sections.GetSize() - 1), &BaseVertex, &VertexBuffer); @@ -1098,7 +1098,7 @@ void lcSynthInfoFlexibleAxle::AddParts(lcMemFile& File, lcLibraryMeshData& MeshD File.WriteBuffer(Line, strlen(Line)); } - const lcLibraryMeshVertex SectionVertices[28] = + const lcMeshLoaderVertex SectionVertices[28] = { { lcVector3(-6.000f, 0.0f, 0.000f), lcVector3(-1.000f, 0.0f, 0.000f), 2.0f, lcVector2(0.0f, 0.0f), 0 }, { lcVector3(-5.602f, 0.0f, 2.000f), lcVector3(-0.942f, 0.0f, 0.336f), 4.0f, lcVector2(0.0f, 0.0f), 0 }, @@ -1133,7 +1133,7 @@ void lcSynthInfoFlexibleAxle::AddParts(lcMemFile& File, lcLibraryMeshData& MeshD const int NumSectionVertices = LC_ARRAY_COUNT(SectionVertices); int BaseVertex; - lcLibraryMeshVertex* VertexBuffer; + lcMeshLoaderVertex* VertexBuffer; quint32* IndexBuffer; MeshData.AddVertices(LC_MESHDATA_SHARED, NumSectionVertices * (Sections.GetSize() - 1), &BaseVertex, &VertexBuffer); MeshData.AddIndices(LC_MESHDATA_SHARED, LC_MESH_LINES, 24, 2 * 12 * (Sections.GetSize() - 2), &IndexBuffer); @@ -1217,7 +1217,7 @@ void lcSynthInfoBraidedString::AddParts(lcMemFile& File, lcLibraryMeshData& Mesh }; int BaseVertex; - lcLibraryMeshVertex* VertexBuffer; + lcMeshLoaderVertex* VertexBuffer; quint32* IndexBuffer; MeshData.AddVertices(LC_MESHDATA_SHARED, NumBraids * ((Sections.GetSize() - 2) * NumSegments + 1), &BaseVertex, &VertexBuffer); MeshData.AddIndices(LC_MESHDATA_SHARED, LC_MESH_LINES, 24, NumBraids * (Sections.GetSize() - 2) * NumSegments * 2, &IndexBuffer); @@ -1402,7 +1402,7 @@ lcMesh* lcSynthInfo::CreateMesh(const lcArray& ControlPoint File.WriteU8(0); - lcArray TextureStack; + lcArray TextureStack; File.Seek(0, SEEK_SET); lcMeshLoader MeshLoader(MeshData, false, nullptr, false); diff --git a/common/pieceinf.cpp b/common/pieceinf.cpp index f08c6f54..5b78f5d4 100644 --- a/common/pieceinf.cpp +++ b/common/pieceinf.cpp @@ -82,7 +82,7 @@ void PieceInfo::SetModel(lcModel* Model, bool UpdateMesh, Project* CurrentProjec } lcLibraryMeshData MeshData; - lcArray TextureStack; + lcArray TextureStack; PieceFile.Seek(0, SEEK_SET); lcMeshLoader MeshLoader(MeshData, true, CurrentProject, SearchProjectFolder); diff --git a/leocad.qrc b/leocad.qrc index 9f52c6d6..3487e2d6 100644 --- a/leocad.qrc +++ b/leocad.qrc @@ -122,6 +122,8 @@ resources/shaders/fakelit_color_vs.glsl resources/shaders/fakelit_texture_decal_ps.glsl resources/shaders/fakelit_texture_decal_vs.glsl + resources/shaders/unlit_color_conditional_ps.glsl + resources/shaders/unlit_color_conditional_vs.glsl resources/shaders/unlit_color_ps.glsl resources/shaders/unlit_color_vs.glsl resources/shaders/unlit_texture_decal_ps.glsl diff --git a/resources/shaders/unlit_color_conditional_ps.glsl b/resources/shaders/unlit_color_conditional_ps.glsl new file mode 100644 index 00000000..40335ca6 --- /dev/null +++ b/resources/shaders/unlit_color_conditional_ps.glsl @@ -0,0 +1,8 @@ +LC_PIXEL_OUTPUT + +uniform mediump vec4 MaterialColor; + +void main() +{ + gl_FragColor = MaterialColor; +} diff --git a/resources/shaders/unlit_color_conditional_vs.glsl b/resources/shaders/unlit_color_conditional_vs.glsl new file mode 100644 index 00000000..58df02f0 --- /dev/null +++ b/resources/shaders/unlit_color_conditional_vs.glsl @@ -0,0 +1,30 @@ +LC_VERTEX_INPUT vec3 VertexPosition1; +LC_VERTEX_INPUT vec3 VertexPosition2; +LC_VERTEX_INPUT vec3 VertexPosition3; +LC_VERTEX_INPUT vec3 VertexPosition4; + +uniform mat4 WorldViewProjectionMatrix; + +void main() +{ + vec4 p1 = WorldViewProjectionMatrix * vec4(VertexPosition1, 1.0); + vec4 p2 = WorldViewProjectionMatrix * vec4(VertexPosition2, 1.0); + vec4 p3 = WorldViewProjectionMatrix * vec4(VertexPosition3, 1.0); + vec4 p4 = WorldViewProjectionMatrix * vec4(VertexPosition4, 1.0); + vec4 Position = p1; + + p1 /= p1.w; + p2 /= p2.w; + p3 /= p3.w; + p4 /= p4.w; + + if (((p1.y - p2.y) * (p3.x - p1.x) + (p2.x - p1.x) * (p3.y - p1.y)) * ((p1.y - p2.y) * (p4.x - p1.x) + (p2.x - p1.x) * (p4.y - p1.y)) >= 0.0) + { + if (((p2.y - p1.y) * (p3.x - p2.x) + (p1.x - p2.x) * (p3.y - p2.y)) * ((p2.y - p1.y) * (p4.x - p2.x) + (p1.x - p2.x) * (p4.y - p2.y)) >= 0.0) + gl_Position = Position; + else + gl_Position = vec4(0.0, 0.0, 0.0, 0.0); + } + else + gl_Position = vec4(0.0, 0.0, 0.0, 0.0); +}