clang-format off ---------------------------------------------------------------------------- (a) FarApart - gap of 7.5 mm, much larger than the 1 mm limit. Cross-section at z = 1.5 (y-axis vertical, x-axis horizontal): y ^ +---+ 2| +-------+ | b | b: 1x1x1 cube | | |
| 72 | // parallel coplanar cube faces unless a vertex match is present. |
| 73 | // clang-format on |
| 74 | TEST( MRMesh, MeshMeshDistance_FarApart ) |
| 75 | { |
| 76 | const auto a = makeRefCube(); // [-2, 2]^3 |
| 77 | const auto b = makeUnitCube(); // [-0.5, 0.5]^3 |
| 78 | const AffineXf3f xf = AffineXf3f::translation( Vector3f( 10.0f, 1.5f, 1.5f ) ); |
| 79 | const float trueDist = 7.5f; |
| 80 | const float trueDistSq = trueDist * trueDist; |
| 81 | |
| 82 | // no limit: function returns the true gap |
| 83 | { |
| 84 | const auto d = findDistance( a, b, &xf, kNoLimitSq ); |
| 85 | EXPECT_NEAR( d.distSq, trueDistSq, 1e-2f ); |
| 86 | |
| 87 | const auto sd = findSignedDistance( a, b, &xf, kNoLimitSq ); |
| 88 | EXPECT_NEAR( sd.signedDist, trueDist, 1e-2f ); |
| 89 | EXPECT_EQ( sd.status, MeshMeshCollisionStatus::BothOutside ); |
| 90 | } |
| 91 | |
| 92 | // 1 mm limit: real distance exceeds the limit -> findDistance early-exits |
| 93 | // returning distSq = upDistLimitSq with invalid res.a/b. findSignedDistance |
| 94 | // cannot determine inside/outside without valid projection points, so it |
| 95 | // reports NotColliding with signedDist = +sqrt(upDistLimitSq) = 1.0. |
| 96 | { |
| 97 | const auto d = findDistance( a, b, &xf, kOneMmLimitSq ); |
| 98 | EXPECT_FLOAT_EQ( d.distSq, kOneMmLimitSq ); |
| 99 | |
| 100 | const auto sd = findSignedDistance( a, b, &xf, kOneMmLimitSq ); |
| 101 | EXPECT_FLOAT_EQ( sd.signedDist, 1.0f ); |
| 102 | EXPECT_EQ( sd.status, MeshMeshCollisionStatus::NotColliding ); |
| 103 | } |
| 104 | |
| 105 | // strict 0 limit: findDistance never descends into the BVH, returns |
| 106 | // distSq = 0 with invalid res.a/b. findCollidingTriangles is empty for |
| 107 | // far-apart meshes, but inside/outside cannot be derived from the invalid |
| 108 | // points, so the function reports NotColliding with signedDist = 0. |
| 109 | { |
| 110 | const auto d = findDistance( a, b, &xf, kZeroLimitSq ); |
| 111 | EXPECT_FLOAT_EQ( d.distSq, kZeroLimitSq ); |
| 112 | |
| 113 | const auto sd = findSignedDistance( a, b, &xf, kZeroLimitSq ); |
| 114 | EXPECT_FLOAT_EQ( sd.signedDist, 0.0f ); |
| 115 | EXPECT_EQ( sd.status, MeshMeshCollisionStatus::NotColliding ); |
| 116 | } |
| 117 | } |
| 118 | |
| 119 | // clang-format off |
| 120 | // ---------------------------------------------------------------------------- |
nothing calls this directly
no test coverage detected