feat: add selection to meshrendercomponent
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
@@ -263,6 +264,74 @@ namespace {
|
||||
"invalid primitive keys must not build a mesh");
|
||||
}
|
||||
|
||||
void testPrimitiveShapes()
|
||||
{
|
||||
using PrimitiveMeshes::Shape;
|
||||
const std::array<PrimitiveMeshes::Desc, 6> descs{{
|
||||
{.shape = Shape::Box, .size = {2.0f, 0.5f, 3.0f}},
|
||||
{.shape = Shape::Plane, .size = {4.0f, 1.0f, 6.0f}},
|
||||
{.shape = Shape::Sphere, .radius = 0.75f},
|
||||
{.shape = Shape::Cylinder, .radius = 0.5f, .height = 3.0f},
|
||||
{.shape = Shape::Capsule, .radius = 0.4f, .height = 2.0f},
|
||||
{.shape = Shape::Capsule, .radius = 1.0f, .height = 1.0f},
|
||||
}};
|
||||
|
||||
for (const auto& desc : descs) {
|
||||
const std::string key = PrimitiveMeshes::MakeKey(desc);
|
||||
const auto parsed = PrimitiveMeshes::ParseKey(key + "#2");
|
||||
check(parsed.has_value() && *parsed == desc, "every primitive must rebuild exactly from its key");
|
||||
|
||||
const CPUMesh mesh = PrimitiveMeshes::Make(desc);
|
||||
check(mesh.name == key, "primitives must be named by their key");
|
||||
check(!mesh.indices.empty() && mesh.indices.size() % 3 == 0, "primitives must be made of triangles");
|
||||
|
||||
bool valid = true;
|
||||
for (const std::uint32_t index : mesh.indices) {
|
||||
valid = valid && index < mesh.vertices.size();
|
||||
}
|
||||
check(valid, "primitive indices must point at their own vertices");
|
||||
|
||||
bool outward = true;
|
||||
bool tangents = true;
|
||||
for (const auto& vertex : mesh.vertices) {
|
||||
outward = outward && close(glm::length(vertex.normal), 1.0f) && glm::dot(vertex.position, vertex.normal) > -0.001f;
|
||||
tangents = tangents && close(glm::dot(glm::vec3{vertex.tangent}, vertex.normal), 0.0f) &&
|
||||
close(std::abs(vertex.tangent.w), 1.0f);
|
||||
}
|
||||
check(outward, "primitive normals must be unit length and point away from the center");
|
||||
check(tangents, "primitive tangents must lie in the surface with a handedness of +-1");
|
||||
|
||||
bool counterClockwise = true;
|
||||
for (std::size_t i = 0; i < mesh.indices.size(); i += 3) {
|
||||
const auto& a = mesh.vertices[mesh.indices[i]];
|
||||
const auto& b = mesh.vertices[mesh.indices[i + 1]];
|
||||
const auto& c = mesh.vertices[mesh.indices[i + 2]];
|
||||
const glm::vec3 faceNormal = glm::cross(b.position - a.position, c.position - a.position);
|
||||
counterClockwise = counterClockwise && glm::dot(faceNormal, a.normal + b.normal + c.normal) >= 0.0f;
|
||||
}
|
||||
check(counterClockwise, "primitive triangles must be counter clockwise seen from outside");
|
||||
}
|
||||
|
||||
const CPUMesh sphere = PrimitiveMeshes::Make(descs[2]);
|
||||
check(close(sphere.maxPos.x, 0.75f) && close(sphere.minPos.y, -0.75f), "a sphere must reach its radius");
|
||||
const CPUMesh plane = PrimitiveMeshes::Make(descs[1]);
|
||||
check(close(plane.maxPos.x, 2.0f) && close(plane.maxPos.z, 3.0f) && close(plane.maxPos.y, 0.0f),
|
||||
"a plane must be flat on y = 0 with its size on x and z");
|
||||
const CPUMesh capsule = PrimitiveMeshes::Make(descs[4]);
|
||||
check(close(capsule.maxPos.y, 1.0f) && close(capsule.maxPos.x, 0.4f),
|
||||
"a capsule height must be its full length, like the collider");
|
||||
const CPUMesh cylinder = PrimitiveMeshes::Make(descs[3]);
|
||||
check(close(cylinder.maxPos.y, 1.5f) && close(cylinder.minPos.y, -1.5f), "a cylinder must be centered on its height");
|
||||
|
||||
check(!PrimitiveMeshes::ParseKey("prim://sphere?radius=1&radius=2").has_value() &&
|
||||
!PrimitiveMeshes::ParseKey("prim://cylinder?radius=1").has_value() &&
|
||||
!PrimitiveMeshes::ParseKey("prim://plane?size=1,2,3").has_value() &&
|
||||
!PrimitiveMeshes::ParseKey("prim://cone?radius=1").has_value() &&
|
||||
!PrimitiveMeshes::ParseKey("prim://sphere?radius=-1").has_value() &&
|
||||
!PrimitiveMeshes::ParseKey("prim://sphere").has_value(),
|
||||
"malformed primitive keys must be rejected");
|
||||
}
|
||||
|
||||
void testIndirectDrawListBatchesByMesh()
|
||||
{
|
||||
std::vector<GPUMesh> meshes(2);
|
||||
@@ -357,6 +426,7 @@ void RunGraphicsTests()
|
||||
testPrimitiveBoxMesh();
|
||||
testSimpleColorMaterial();
|
||||
testPrimitiveMeshKeys();
|
||||
testPrimitiveShapes();
|
||||
testDeletionQueueWaitsForFrame();
|
||||
testIndirectDrawListBatchesByMesh();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user