From 6f1cbbf3050507542eb5cdd6549ffebd5fd67945 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Thu, 26 Mar 2026 03:26:44 +0800 Subject: [PATCH] Add mesh bounds metadata --- engine/include/XCEngine/Resources/Mesh/Mesh.h | 6 +++++ engine/src/Resources/Mesh/Mesh.cpp | 1 + engine/src/Resources/Mesh/MeshLoader.cpp | 26 +++++++++++++++++++ tests/Resources/Mesh/test_mesh.cpp | 11 ++++++++ tests/Resources/Mesh/test_mesh_loader.cpp | 4 +++ 5 files changed, 48 insertions(+) diff --git a/engine/include/XCEngine/Resources/Mesh/Mesh.h b/engine/include/XCEngine/Resources/Mesh/Mesh.h index 71126bde..854a5012 100644 --- a/engine/include/XCEngine/Resources/Mesh/Mesh.h +++ b/engine/include/XCEngine/Resources/Mesh/Mesh.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -42,6 +43,7 @@ struct MeshSection { Core::uint32 startIndex; Core::uint32 indexCount; Core::uint32 materialID; + Math::Bounds bounds; }; class Mesh : public IResource { @@ -70,6 +72,9 @@ public: size_t GetIndexDataSize() const { return m_indexData.Size(); } Core::uint32 GetIndexCount() const { return m_indexCount; } bool IsUse32BitIndex() const { return m_use32BitIndex; } + + void SetBounds(const Math::Bounds& bounds) { m_bounds = bounds; } + const Math::Bounds& GetBounds() const { return m_bounds; } void AddSection(const MeshSection& section); const Containers::Array& GetSections() const { return m_sections; } @@ -87,6 +92,7 @@ private: Containers::Array m_vertexData; Containers::Array m_indexData; Containers::Array m_sections; + Math::Bounds m_bounds; }; } // namespace Resources diff --git a/engine/src/Resources/Mesh/Mesh.cpp b/engine/src/Resources/Mesh/Mesh.cpp index 74fd34ee..d27acbe4 100644 --- a/engine/src/Resources/Mesh/Mesh.cpp +++ b/engine/src/Resources/Mesh/Mesh.cpp @@ -16,6 +16,7 @@ void Mesh::Release() { m_attributes = VertexAttribute::Position; m_indexCount = 0; m_use32BitIndex = false; + m_bounds = Math::Bounds(); UpdateMemorySize(); SetInvalid(); } diff --git a/engine/src/Resources/Mesh/MeshLoader.cpp b/engine/src/Resources/Mesh/MeshLoader.cpp index 609f0091..5a090537 100644 --- a/engine/src/Resources/Mesh/MeshLoader.cpp +++ b/engine/src/Resources/Mesh/MeshLoader.cpp @@ -20,8 +20,31 @@ struct ImportedMeshData { std::vector vertices; std::vector indices; VertexAttribute attributes = VertexAttribute::Position; + Math::Bounds bounds; }; +Math::Bounds ComputeBounds(const std::vector& vertices) { + if (vertices.empty()) { + return Math::Bounds(); + } + + Math::Vector3 min = vertices.front().position; + Math::Vector3 max = vertices.front().position; + + for (const StaticMeshVertex& vertex : vertices) { + min.x = std::min(min.x, vertex.position.x); + min.y = std::min(min.y, vertex.position.y); + min.z = std::min(min.z, vertex.position.z); + max.x = std::max(max.x, vertex.position.x); + max.y = std::max(max.y, vertex.position.y); + max.z = std::max(max.z, vertex.position.z); + } + + Math::Bounds bounds; + bounds.SetMinMax(min, max); + return bounds; +} + Math::Matrix4 ConvertAssimpMatrix(const aiMatrix4x4& matrix) { Math::Matrix4 result; result.m[0][0] = matrix.a1; result.m[0][1] = matrix.a2; result.m[0][2] = matrix.a3; result.m[0][3] = matrix.a4; @@ -129,6 +152,7 @@ ImportedMeshData ImportSingleMesh(const aiMesh& mesh, } result.attributes = attributes; + result.bounds = ComputeBounds(result.vertices); return result; } @@ -169,6 +193,7 @@ void ProcessNode(const aiNode& node, section.startIndex = startIndex; section.indexCount = static_cast(meshData.indices.size()); section.materialID = mesh->mMaterialIndex; + section.bounds = meshData.bounds; sections.PushBack(section); attributes = attributes | meshData.attributes; @@ -287,6 +312,7 @@ LoadResult MeshLoader::Load(const Containers::String& path, const ImportSettings for (const MeshSection& section : sections) { mesh->AddSection(section); } + mesh->SetBounds(ComputeBounds(vertices)); return LoadResult(mesh); } diff --git a/tests/Resources/Mesh/test_mesh.cpp b/tests/Resources/Mesh/test_mesh.cpp index 0f1006d8..a033b223 100644 --- a/tests/Resources/Mesh/test_mesh.cpp +++ b/tests/Resources/Mesh/test_mesh.cpp @@ -71,4 +71,15 @@ TEST(Mesh, AddSection) { EXPECT_EQ(mesh.GetSections()[0].materialID, 2u); } +TEST(Mesh, SetBounds) { + Mesh mesh; + + Bounds bounds; + bounds.SetMinMax(Vector3(-1.0f, -2.0f, -3.0f), Vector3(1.0f, 2.0f, 3.0f)); + mesh.SetBounds(bounds); + + EXPECT_EQ(mesh.GetBounds().GetMin(), Vector3(-1.0f, -2.0f, -3.0f)); + EXPECT_EQ(mesh.GetBounds().GetMax(), Vector3(1.0f, 2.0f, 3.0f)); +} + } // namespace diff --git a/tests/Resources/Mesh/test_mesh_loader.cpp b/tests/Resources/Mesh/test_mesh_loader.cpp index ccc34b77..77ebb949 100644 --- a/tests/Resources/Mesh/test_mesh_loader.cpp +++ b/tests/Resources/Mesh/test_mesh_loader.cpp @@ -60,6 +60,10 @@ TEST(MeshLoader, LoadValidObjMesh) { EXPECT_TRUE(HasVertexAttribute(mesh->GetVertexAttributes(), VertexAttribute::Position)); EXPECT_TRUE(HasVertexAttribute(mesh->GetVertexAttributes(), VertexAttribute::Normal)); EXPECT_TRUE(HasVertexAttribute(mesh->GetVertexAttributes(), VertexAttribute::UV0)); + EXPECT_EQ(mesh->GetBounds().GetMin(), XCEngine::Math::Vector3(0.0f, 0.0f, -1.0f)); + EXPECT_EQ(mesh->GetBounds().GetMax(), XCEngine::Math::Vector3(1.0f, 1.0f, -1.0f)); + EXPECT_EQ(mesh->GetSections()[0].bounds.GetMin(), XCEngine::Math::Vector3(0.0f, 0.0f, -1.0f)); + EXPECT_EQ(mesh->GetSections()[0].bounds.GetMax(), XCEngine::Math::Vector3(1.0f, 1.0f, -1.0f)); const auto* vertices = static_cast(mesh->GetVertexData()); ASSERT_NE(vertices, nullptr);