Add mesh bounds metadata
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <XCEngine/Core/Asset/IResource.h>
|
#include <XCEngine/Core/Asset/IResource.h>
|
||||||
#include <XCEngine/Core/Containers/Array.h>
|
#include <XCEngine/Core/Containers/Array.h>
|
||||||
|
#include <XCEngine/Core/Math/Bounds.h>
|
||||||
#include <XCEngine/Core/Math/Vector2.h>
|
#include <XCEngine/Core/Math/Vector2.h>
|
||||||
#include <XCEngine/Core/Math/Vector3.h>
|
#include <XCEngine/Core/Math/Vector3.h>
|
||||||
#include <XCEngine/Core/Types.h>
|
#include <XCEngine/Core/Types.h>
|
||||||
@@ -42,6 +43,7 @@ struct MeshSection {
|
|||||||
Core::uint32 startIndex;
|
Core::uint32 startIndex;
|
||||||
Core::uint32 indexCount;
|
Core::uint32 indexCount;
|
||||||
Core::uint32 materialID;
|
Core::uint32 materialID;
|
||||||
|
Math::Bounds bounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mesh : public IResource {
|
class Mesh : public IResource {
|
||||||
@@ -71,6 +73,9 @@ public:
|
|||||||
Core::uint32 GetIndexCount() const { return m_indexCount; }
|
Core::uint32 GetIndexCount() const { return m_indexCount; }
|
||||||
bool IsUse32BitIndex() const { return m_use32BitIndex; }
|
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);
|
void AddSection(const MeshSection& section);
|
||||||
const Containers::Array<MeshSection>& GetSections() const { return m_sections; }
|
const Containers::Array<MeshSection>& GetSections() const { return m_sections; }
|
||||||
|
|
||||||
@@ -87,6 +92,7 @@ private:
|
|||||||
Containers::Array<Core::uint8> m_vertexData;
|
Containers::Array<Core::uint8> m_vertexData;
|
||||||
Containers::Array<Core::uint8> m_indexData;
|
Containers::Array<Core::uint8> m_indexData;
|
||||||
Containers::Array<MeshSection> m_sections;
|
Containers::Array<MeshSection> m_sections;
|
||||||
|
Math::Bounds m_bounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Resources
|
} // namespace Resources
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ void Mesh::Release() {
|
|||||||
m_attributes = VertexAttribute::Position;
|
m_attributes = VertexAttribute::Position;
|
||||||
m_indexCount = 0;
|
m_indexCount = 0;
|
||||||
m_use32BitIndex = false;
|
m_use32BitIndex = false;
|
||||||
|
m_bounds = Math::Bounds();
|
||||||
UpdateMemorySize();
|
UpdateMemorySize();
|
||||||
SetInvalid();
|
SetInvalid();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,8 +20,31 @@ struct ImportedMeshData {
|
|||||||
std::vector<StaticMeshVertex> vertices;
|
std::vector<StaticMeshVertex> vertices;
|
||||||
std::vector<Core::uint32> indices;
|
std::vector<Core::uint32> indices;
|
||||||
VertexAttribute attributes = VertexAttribute::Position;
|
VertexAttribute attributes = VertexAttribute::Position;
|
||||||
|
Math::Bounds bounds;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Math::Bounds ComputeBounds(const std::vector<StaticMeshVertex>& 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 ConvertAssimpMatrix(const aiMatrix4x4& matrix) {
|
||||||
Math::Matrix4 result;
|
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;
|
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.attributes = attributes;
|
||||||
|
result.bounds = ComputeBounds(result.vertices);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,6 +193,7 @@ void ProcessNode(const aiNode& node,
|
|||||||
section.startIndex = startIndex;
|
section.startIndex = startIndex;
|
||||||
section.indexCount = static_cast<Core::uint32>(meshData.indices.size());
|
section.indexCount = static_cast<Core::uint32>(meshData.indices.size());
|
||||||
section.materialID = mesh->mMaterialIndex;
|
section.materialID = mesh->mMaterialIndex;
|
||||||
|
section.bounds = meshData.bounds;
|
||||||
sections.PushBack(section);
|
sections.PushBack(section);
|
||||||
|
|
||||||
attributes = attributes | meshData.attributes;
|
attributes = attributes | meshData.attributes;
|
||||||
@@ -287,6 +312,7 @@ LoadResult MeshLoader::Load(const Containers::String& path, const ImportSettings
|
|||||||
for (const MeshSection& section : sections) {
|
for (const MeshSection& section : sections) {
|
||||||
mesh->AddSection(section);
|
mesh->AddSection(section);
|
||||||
}
|
}
|
||||||
|
mesh->SetBounds(ComputeBounds(vertices));
|
||||||
|
|
||||||
return LoadResult(mesh);
|
return LoadResult(mesh);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,4 +71,15 @@ TEST(Mesh, AddSection) {
|
|||||||
EXPECT_EQ(mesh.GetSections()[0].materialID, 2u);
|
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
|
} // namespace
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ TEST(MeshLoader, LoadValidObjMesh) {
|
|||||||
EXPECT_TRUE(HasVertexAttribute(mesh->GetVertexAttributes(), VertexAttribute::Position));
|
EXPECT_TRUE(HasVertexAttribute(mesh->GetVertexAttributes(), VertexAttribute::Position));
|
||||||
EXPECT_TRUE(HasVertexAttribute(mesh->GetVertexAttributes(), VertexAttribute::Normal));
|
EXPECT_TRUE(HasVertexAttribute(mesh->GetVertexAttributes(), VertexAttribute::Normal));
|
||||||
EXPECT_TRUE(HasVertexAttribute(mesh->GetVertexAttributes(), VertexAttribute::UV0));
|
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<const StaticMeshVertex*>(mesh->GetVertexData());
|
const auto* vertices = static_cast<const StaticMeshVertex*>(mesh->GetVertexData());
|
||||||
ASSERT_NE(vertices, nullptr);
|
ASSERT_NE(vertices, nullptr);
|
||||||
|
|||||||
Reference in New Issue
Block a user