diff --git a/src/graphics/model/model_gltf.cpp b/src/graphics/model/model_gltf.cpp index 452b2302..ad21d1da 100644 --- a/src/graphics/model/model_gltf.cpp +++ b/src/graphics/model/model_gltf.cpp @@ -461,7 +461,7 @@ void GLTFLoader::ReadTextures() void GLTFLoader::ReadMeshes() { - m_model = {}; + m_model = std::make_unique(); for (const auto& node : m_root["meshes"]) { @@ -475,97 +475,72 @@ void GLTFLoader::ReadMeshes() auto part = mesh->AddPart(material); - std::vector positions; - std::vector normals; - std::vector uvs; - std::vector uvs2; - std::vector colors; - - std::vector indices; - if (primitive.contains("attributes")) { const auto& attributes = primitive["attributes"]; - positions = ReadPositions(attributes["POSITION"].get()); + auto positions = ReadPositions(attributes["POSITION"].get()); if (positions.empty()) continue; + part->SetVertices(positions.size()); + + for (size_t i = 0; i < positions.size(); i++) + part->GetVertex(i).SetPosition(positions[i]); + if (attributes.contains("NORMAL")) { - normals = ReadNormals(attributes["NORMAL"].get()); - } - else - { - normals.resize(positions.size()); - std::fill(normals.begin(), normals.end(), glm::vec3(0.0, 1.0, 0.0)); + part->Add(VertexAttribute::NORMAL); + + auto normals = ReadNormals(attributes["NORMAL"].get()); + + for (size_t i = 0; i < normals.size(); i++) + part->GetVertex(i).SetNormal(normals[i]); } if (attributes.contains("TEXCOORD_0")) { - uvs = ReadUVs(attributes["TEXCOORD_0"].get()); - } - else - { - uvs.resize(positions.size()); - std::fill(uvs.begin(), uvs.end(), glm::vec2(0.0, 0.0)); + part->Add(VertexAttribute::UV1); + + auto uvs = ReadUVs(attributes["TEXCOORD_0"].get()); + + for (size_t i = 0; i < uvs.size(); i++) + part->GetVertex(i).SetUV1(uvs[i]); } if (attributes.contains("TEXCOORD_1")) { - uvs2 = ReadUVs(attributes["TEXCOORD_1"].get()); - } - else - { - uvs2.resize(positions.size()); - std::fill(uvs2.begin(), uvs2.end(), glm::vec2(0.0, 0.0)); + part->Add(VertexAttribute::UV2); + + auto uvs = ReadUVs(attributes["TEXCOORD_1"].get()); + + for (size_t i = 0; i < uvs.size(); i++) + part->GetVertex(i).SetUV2(uvs[i]); } if (attributes.contains("COLOR_0")) { - colors = ReadColors(attributes["COLOR_0"].get()); + part->Add(VertexAttribute::COLOR); + + auto colors = ReadColors(attributes["COLOR_0"].get()); + + for (size_t i = 0; i < colors.size(); i++) + part->GetVertex(i).SetColor(colors[i]); } - else + } + + if (primitive.contains("indices")) + { + auto indices = ReadIndices(primitive["indices"].get()); + + part->SetIndices(indices.size()); + + for (size_t i = 0; i < indices.size(); i += 3) { - colors.resize(positions.size()); - std::fill(colors.begin(), colors.end(), glm::u8vec4(255, 255, 255, 255)); + part->SetIndex(i + 0, indices[i + 0]); + part->SetIndex(i + 1, indices[i + 1]); + part->SetIndex(i + 2, indices[i + 2]); } - - if (primitive.contains("indices")) - { - indices = ReadIndices(primitive["indices"].get()); - } - - // Combine vertex attributes into vertices - std::vector vertices(positions.size()); - - for (size_t i = 0; i < positions.size(); i++) - { - vertices[i].position = positions[i] * glm::vec3(1.0, 1.0, -1.0); - vertices[i].normal = normals[i] * glm::vec3(1.0, 1.0, -1.0); - vertices[i].uv = uvs[i]; - vertices[i].uv2 = uvs2[i]; - vertices[i].color = colors[i]; - } - - // No indices, reverse triangle vertices - if (indices.empty()) - { - for (size_t i = 0; i < vertices.size() - 2; i += 3) - std::swap(vertices[i], vertices[i + 1]); - } - // Indices present, reverse triangle indices order - else - { - for (size_t i = 0; i < indices.size() - 2; i += 3) - std::swap(indices[i], indices[i + 1]); - } - - for (const auto& vertex : vertices) - part->AddVertex(vertex); - - for (const auto& index : indices) - part->AddIndex(index); } } diff --git a/src/graphics/model/model_mesh.cpp b/src/graphics/model/model_mesh.cpp index 34662fa4..275ebd7e 100644 --- a/src/graphics/model/model_mesh.cpp +++ b/src/graphics/model/model_mesh.cpp @@ -137,6 +137,7 @@ void CModelPart::SetVertices(size_t count) void CModelPart::SetIndices(size_t count) { + m_indices.enabled = count > 0; m_indices.array.resize(count); } @@ -196,7 +197,7 @@ void CModelPart::Add(VertexAttribute attribute) case VertexAttribute::BONE_WEIGHTS: m_boneWeights.enabled = true; m_boneWeights.array.resize(m_positions.array.size()); - break; + return; } } @@ -283,6 +284,11 @@ void CModelPart::AddIndex(unsigned int index) if (m_indices.enabled) m_indices.array.push_back(index); } +void CModelPart::SetIndex(size_t index, unsigned int value) +{ + m_indices.array[index] = value; +} + void CModelPart::GetTriangles(std::vector& triangles) { size_t n = IsIndexed() @@ -301,10 +307,18 @@ void CModelPart::GetTriangles(std::vector& triangles) auto vertex = GetVertex(index); verts[j].position = vertex.GetPosition(); - verts[j].color = vertex.GetColor(); - verts[j].uv = vertex.GetUV1(); - verts[j].uv2 = vertex.GetUV2(); - verts[j].normal = vertex.GetNormal(); + + if (Has(VertexAttribute::COLOR)) verts[j].color = vertex.GetColor(); + else verts[j].color = { 255, 255, 255, 255 }; + + if (Has(VertexAttribute::UV1)) verts[j].uv = vertex.GetUV1(); + else verts[j].uv = { 0, 0 }; + + if (Has(VertexAttribute::UV2)) verts[j].uv2 = vertex.GetUV2(); + else verts[j].uv2 = { 0, 0 }; + + if (Has(VertexAttribute::NORMAL)) verts[j].normal = vertex.GetNormal(); + else verts[j].normal = { 0, 0, 1 }; } triangles.push_back({ verts[0], verts[1], verts[2], GetMaterial() }); diff --git a/src/graphics/model/model_mesh.h b/src/graphics/model/model_mesh.h index 5b865206..238e5b85 100644 --- a/src/graphics/model/model_mesh.h +++ b/src/graphics/model/model_mesh.h @@ -150,6 +150,9 @@ public: //! Adds an index void AddIndex(unsigned int index); + //! Set index + void SetIndex(size_t index, unsigned int value); + //! Fills the array with converted model triangles void GetTriangles(std::vector& triangles);