From cffc45188439481a8269fedd8747faedf1444c8c Mon Sep 17 00:00:00 2001 From: Jorrit Rouwe Date: Tue, 12 Dec 2023 18:38:00 +0100 Subject: [PATCH] Added unit test for saving mesh shapes (#792) --- UnitTests/Physics/ShapeTests.cpp | 57 ++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/UnitTests/Physics/ShapeTests.cpp b/UnitTests/Physics/ShapeTests.cpp index d20cd5b5f..8ff981f3b 100644 --- a/UnitTests/Physics/ShapeTests.cpp +++ b/UnitTests/Physics/ShapeTests.cpp @@ -16,8 +16,11 @@ #include #include #include +#include #include #include +#include +#include #include TEST_SUITE("ShapeTests") @@ -620,4 +623,58 @@ TEST_SUITE("ShapeTests") AABox bounds3 = mutable_compound->GetWorldSpaceBounds(DMat44::sRotationTranslation(rotation, DVec3(100, 200, 300)), Vec3(1, 2, 3)); CHECK(!bounds3.IsValid()); } + + TEST_CASE("TestSaveMeshShape") + { + // Create an n x n grid of triangles + const int n = 10; + const float s = 0.1f; + TriangleList triangles; + for (int z = 0; z < n; ++z) + for (int x = 0; x < n; ++x) + { + float fx = s * x - s * n / 2, fz = s * z - s * n / 2; + triangles.push_back(Triangle(Vec3(fx, 0, fz), Vec3(fx, 0, fz + s), Vec3(fx + s, 0, fz + s))); + triangles.push_back(Triangle(Vec3(fx, 0, fz), Vec3(fx + s, 0, fz + s), Vec3(fx + s, 0, fz))); + } + MeshShapeSettings mesh_settings(triangles); + mesh_settings.SetEmbedded(); + RefConst shape = mesh_settings.Create().Get(); + + // Calculate expected bounds + AABox expected_bounds; + for (const Triangle &t : triangles) + for (const Float3 &v : t.mV) + expected_bounds.Encapsulate(Vec3(v)); + + stringstream stream; + + { + // Write mesh to stream + StreamOutWrapper wrapper(stream); + shape->SaveBinaryState(wrapper); + } + + { + // Read back mesh + StreamInWrapper iwrapper(stream); + Shape::ShapeResult result = Shape::sRestoreFromBinaryState(iwrapper); + CHECK(result.IsValid()); + RefConst mesh_shape = static_cast(result.Get().GetPtr()); + + // Test if it contains the same amount of triangles + Shape::Stats stats = mesh_shape->GetStats(); + CHECK(stats.mNumTriangles == triangles.size()); + + // Check bounding box + CHECK(mesh_shape->GetLocalBounds() == expected_bounds); + + // Check if we can hit it with a ray + RayCastResult hit; + RayCast ray(Vec3(0.5f * s, 1, 0.25f * s), Vec3(0, -2, 0)); // Hit in the center of a triangle + CHECK(mesh_shape->CastRay(ray, SubShapeIDCreator(), hit)); + CHECK(hit.mFraction == 0.5f); + CHECK(mesh_shape->GetSurfaceNormal(hit.mSubShapeID2, ray.GetPointOnRay(hit.mFraction)) == Vec3::sAxisY()); + } + } }