diff --git a/Engine/Source/Runtime/ECWorld/StaticMeshComponent.cpp b/Engine/Source/Runtime/ECWorld/StaticMeshComponent.cpp index a21a2bbd..26de2cd3 100644 --- a/Engine/Source/Runtime/ECWorld/StaticMeshComponent.cpp +++ b/Engine/Source/Runtime/ECWorld/StaticMeshComponent.cpp @@ -52,11 +52,7 @@ uint32_t StaticMeshComponent::GetStartVertex() const uint32_t StaticMeshComponent::GetVertexCount() const { -#ifdef EDITOR_MODE - return IsProgressiveMeshValid() ? m_currentVertexCount : UINT32_MAX; -#else - return UINT32_MAX; -#endif + return m_currentVertexCount; } uint16_t StaticMeshComponent::GetVertexBuffer() const @@ -73,10 +69,15 @@ uint32_t StaticMeshComponent::GetStartIndex() const return 0U; } +uint32_t StaticMeshComponent::GetPolygonCount() const +{ + return m_currentPolygonCount; +} + uint32_t StaticMeshComponent::GetIndexCount() const { #ifdef EDITOR_MODE - return IsProgressiveMeshValid() ? m_currentPolygonCount * 3U : UINT32_MAX; + return IsProgressiveMeshValid() ? GetPolygonCount() * 3U : UINT32_MAX; #else return UINT32_MAX; #endif @@ -96,6 +97,9 @@ void StaticMeshComponent::Reset() m_pMeshData = nullptr; m_pRequiredVertexFormat = nullptr; + m_currentVertexCount = UINT32_MAX; + m_currentPolygonCount = UINT32_MAX; + m_vertexBuffer.clear(); m_vertexBufferHandle = UINT16_MAX; @@ -106,10 +110,8 @@ void StaticMeshComponent::Reset() m_wireframeIndexBuffer.clear(); m_wireframeIndexBufferHandle = UINT16_MAX; - m_totalVertexCount = UINT32_MAX; - m_currentVertexCount = UINT32_MAX; - m_totalPolygonCount = UINT32_MAX; - m_currentPolygonCount = UINT32_MAX; + m_originVertexCount = UINT32_MAX; + m_originPolygonCount = UINT32_MAX; m_progressiveMeshReductionPercent = 1.0f; m_progressiveMeshVertexBuffer.clear(); @@ -130,6 +132,9 @@ void StaticMeshComponent::Build() return; } + m_currentVertexCount = m_pMeshData->GetVertexCount(); + m_currentPolygonCount = m_pMeshData->GetPolygonCount(); + const bool containsPosition = m_pRequiredVertexFormat->Contains(cd::VertexAttributeType::Position); const bool containsNormal = m_pRequiredVertexFormat->Contains(cd::VertexAttributeType::Normal); const bool containsTangent = m_pRequiredVertexFormat->Contains(cd::VertexAttributeType::Tangent); @@ -141,10 +146,8 @@ void StaticMeshComponent::Build() const bool containsBoneIndex = m_pRequiredVertexFormat->Contains(cd::VertexAttributeType::BoneIndex); const bool containsBoneWeight = m_pRequiredVertexFormat->Contains(cd::VertexAttributeType::BoneWeight); - const uint32_t vertexCount = m_pMeshData->GetVertexCount(); const uint32_t vertexFormatStride = m_pRequiredVertexFormat->GetStride(); - - m_vertexBuffer.resize(vertexCount * vertexFormatStride); + m_vertexBuffer.resize(m_currentVertexCount * vertexFormatStride); uint32_t vbDataSize = 0U; auto vbDataPtr = m_vertexBuffer.data(); @@ -154,7 +157,7 @@ void StaticMeshComponent::Build() vbDataSize += dataSize; }; - for (uint32_t vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex) + for (uint32_t vertexIndex = 0; vertexIndex < m_currentVertexCount; ++vertexIndex) { if (containsPosition) { @@ -224,9 +227,9 @@ void StaticMeshComponent::Build() } // Fill index buffer data. - const bool useU16Index = vertexCount <= static_cast(std::numeric_limits::max()) + 1U; + const bool useU16Index = m_currentVertexCount <= static_cast(std::numeric_limits::max()) + 1U; const uint32_t indexTypeSize = useU16Index ? sizeof(uint16_t) : sizeof(uint32_t); - const uint32_t indicesCount = m_pMeshData->GetPolygonCount() * 3U; + const uint32_t indicesCount = m_currentPolygonCount * 3U; m_indexBuffer.resize(indicesCount* indexTypeSize); uint32_t ibDataSize = 0U; @@ -270,7 +273,7 @@ void StaticMeshComponent::Submit() m_vertexBufferHandle = vertexBufferHandle.idx; // Create index buffer. - const bool useU16Index = m_pMeshData->GetVertexCount() <= static_cast(std::numeric_limits::max()) + 1U; + const bool useU16Index = m_currentVertexCount <= static_cast(std::numeric_limits::max()) + 1U; m_indexBufferHandle = SubmitIndexBuffer(m_indexBuffer, useU16Index); #ifdef EDITOR_MODE @@ -282,10 +285,8 @@ void StaticMeshComponent::Submit() void StaticMeshComponent::BuildWireframeData() { - assert(m_pMeshData); - - const uint32_t indicesCount = m_pMeshData->GetPolygonCount() * 3U; - const bool useU16Index = m_pMeshData->GetVertexCount() <= static_cast(std::numeric_limits::max()) + 1U; + const uint32_t indicesCount = m_currentPolygonCount * 3U; + const bool useU16Index = m_currentVertexCount <= static_cast(std::numeric_limits::max()) + 1U; const uint32_t indexTypeSize = useU16Index ? sizeof(uint16_t) : sizeof(uint32_t); uint32_t wireframeIndicesCount = bgfx::topologyConvert(bgfx::TopologyConvert::TriListToLineList, nullptr, 0U, @@ -308,10 +309,8 @@ void StaticMeshComponent::BuildProgressiveMeshData() m_permutation = cd::MoveTemp(permutationMapPair.first); m_map = cd::MoveTemp(permutationMapPair.second); - m_totalVertexCount = m_pMeshData->GetVertexCount(); - m_currentVertexCount = m_totalVertexCount; - m_totalPolygonCount = m_pMeshData->GetPolygonCount(); - m_currentPolygonCount = m_totalPolygonCount; + m_originVertexCount = m_currentVertexCount; + m_originPolygonCount = m_currentPolygonCount; m_progressiveMeshIndexBuffer.resize(m_currentPolygonCount * 3U); // Copy and modify buffer. @@ -326,7 +325,7 @@ void StaticMeshComponent::BuildProgressiveMeshData() } // After sorting vertex buffer, modify index buffer accordingly. - const bool useU16Index = m_totalVertexCount <= static_cast(std::numeric_limits::max()) + 1U; + const bool useU16Index = m_originVertexCount <= static_cast(std::numeric_limits::max()) + 1U; const uint32_t indexTypeSize = useU16Index ? sizeof(uint16_t) : sizeof(uint32_t); m_progressiveMeshIndexBuffer.resize(m_indexBuffer.size()); @@ -363,7 +362,7 @@ void StaticMeshComponent::BuildProgressiveMeshData() void StaticMeshComponent::UpdateProgressiveMeshData() { assert(m_progressiveMeshReductionPercent >= 0.0f && m_progressiveMeshReductionPercent <= 1.0f); - uint32_t lodVertexCount = static_cast(m_progressiveMeshReductionPercent * m_totalVertexCount); + uint32_t lodVertexCount = static_cast(m_progressiveMeshReductionPercent * m_originVertexCount); if (lodVertexCount == m_currentVertexCount) { return; @@ -374,19 +373,20 @@ void StaticMeshComponent::UpdateProgressiveMeshData() // update index buffer uint32_t polygonCount = 0; - const bool useU16Index = m_totalVertexCount <= static_cast(std::numeric_limits::max()) + 1U; + const bool useU16Index = m_originVertexCount <= static_cast(std::numeric_limits::max()) + 1U; const uint32_t indexTypeSize = useU16Index ? sizeof(uint16_t) : sizeof(uint32_t); if (useU16Index) { - uint16_t* pIndexBuffer = reinterpret_cast(m_progressiveMeshIndexBuffer.data()); - for (uint32_t polygonIndex = 0U; polygonIndex < m_totalPolygonCount; ++polygonIndex) + using IndexType = uint16_t; + auto* pIndexBuffer = reinterpret_cast(m_progressiveMeshIndexBuffer.data()); + for (uint32_t polygonIndex = 0U; polygonIndex < m_originPolygonCount; ++polygonIndex) { uint16_t polygon[3]; uint32_t startIndex = polygonIndex * 3; for (uint32_t ii = 0U; ii < 3U; ++ii) { - uint16_t index = pIndexBuffer[startIndex + ii]; + IndexType index = pIndexBuffer[startIndex + ii]; while (index > lodVertexCount) { index = m_map[index]; @@ -406,7 +406,33 @@ void StaticMeshComponent::UpdateProgressiveMeshData() } else { - assert("support u32 in generic way."); + // TODO : Remove duplicated codes. + using IndexType = uint32_t; + auto* pIndexBuffer = reinterpret_cast(m_progressiveMeshIndexBuffer.data()); + for (uint32_t polygonIndex = 0U; polygonIndex < m_originPolygonCount; ++polygonIndex) + { + uint16_t polygon[3]; + + uint32_t startIndex = polygonIndex * 3; + for (uint32_t ii = 0U; ii < 3U; ++ii) + { + IndexType index = pIndexBuffer[startIndex + ii]; + while (index > lodVertexCount) + { + index = m_map[index]; + } + + polygon[ii] = index; + } + + if (polygon[0] != polygon[1] && + polygon[0] != polygon[2] && + polygon[1] != polygon[2]) + { + std::memcpy(pIndexBuffer + startIndex, polygon, 3 * indexTypeSize); + ++polygonCount; + } + } } m_currentPolygonCount = polygonCount; diff --git a/Engine/Source/Runtime/ECWorld/StaticMeshComponent.h b/Engine/Source/Runtime/ECWorld/StaticMeshComponent.h index a5ed86d7..c77ded23 100644 --- a/Engine/Source/Runtime/ECWorld/StaticMeshComponent.h +++ b/Engine/Source/Runtime/ECWorld/StaticMeshComponent.h @@ -45,6 +45,7 @@ class StaticMeshComponent final uint32_t GetVertexCount() const; uint16_t GetVertexBuffer() const; uint32_t GetStartIndex() const; + uint32_t GetPolygonCount() const; uint32_t GetIndexCount() const; uint16_t GetIndexBuffer() const; @@ -58,6 +59,8 @@ class StaticMeshComponent final const cd::VertexFormat* m_pRequiredVertexFormat = nullptr; // Output + uint32_t m_currentVertexCount = UINT32_MAX; + uint32_t m_currentPolygonCount = UINT32_MAX; std::vector m_vertexBuffer; std::vector m_indexBuffer; uint16_t m_vertexBufferHandle = UINT16_MAX; @@ -87,10 +90,9 @@ class StaticMeshComponent final std::vector m_progressiveMeshIndexBuffer; uint16_t m_progressiveMeshIndexBufferHandle = UINT16_MAX; - uint32_t m_totalVertexCount = UINT32_MAX; - uint32_t m_currentVertexCount = UINT32_MAX; - uint32_t m_totalPolygonCount = UINT32_MAX; - uint32_t m_currentPolygonCount = UINT32_MAX; + uint32_t m_originVertexCount = UINT32_MAX; + uint32_t m_originPolygonCount = UINT32_MAX; + float m_progressiveMeshReductionPercent = 1.0f; std::vector m_permutation; std::vector m_map;