|
@@ -120,6 +120,8 @@ TEST_SUITE("ShapeTests")
|
|
|
// Test IsValidScale function
|
|
|
TEST_CASE("TestIsValidScale")
|
|
|
{
|
|
|
+ constexpr float cMinScaleToleranceSq = Square(1.0e-6f * ScaleHelpers::cMinScale);
|
|
|
+
|
|
|
// Test simple shapes
|
|
|
Ref<Shape> sphere = new SphereShape(2.0f);
|
|
|
CHECK(!sphere->IsValidScale(Vec3::sZero()));
|
|
@@ -128,14 +130,20 @@ TEST_SUITE("ShapeTests")
|
|
|
CHECK(!sphere->IsValidScale(Vec3(2, 1, 1)));
|
|
|
CHECK(!sphere->IsValidScale(Vec3(1, 2, 1)));
|
|
|
CHECK(!sphere->IsValidScale(Vec3(1, 1, 2)));
|
|
|
+ CHECK(sphere->MakeScaleValid(Vec3::sZero()).IsClose(Vec3::sReplicate(ScaleHelpers::cMinScale), cMinScaleToleranceSq)); // Averaging can cause a slight error
|
|
|
+ CHECK(sphere->MakeScaleValid(Vec3(-2, 3, 4)) == Vec3(-3, 3, 3));
|
|
|
|
|
|
Ref<Shape> capsule = new CapsuleShape(2.0f, 0.5f);
|
|
|
CHECK(!capsule->IsValidScale(Vec3::sZero()));
|
|
|
+ CHECK(!capsule->IsValidScale(Vec3(0, 1, 0)));
|
|
|
+ CHECK(!capsule->IsValidScale(Vec3(1, 0, 1)));
|
|
|
CHECK(capsule->IsValidScale(Vec3(2, 2, 2)));
|
|
|
CHECK(capsule->IsValidScale(Vec3(-1, 1, -1)));
|
|
|
CHECK(!capsule->IsValidScale(Vec3(2, 1, 1)));
|
|
|
CHECK(!capsule->IsValidScale(Vec3(1, 2, 1)));
|
|
|
CHECK(!capsule->IsValidScale(Vec3(1, 1, 2)));
|
|
|
+ CHECK(capsule->MakeScaleValid(Vec3::sZero()).IsClose(Vec3::sReplicate(ScaleHelpers::cMinScale), cMinScaleToleranceSq));
|
|
|
+ CHECK(capsule->MakeScaleValid(Vec3(-2, 3, 4)) == Vec3(-3, 3, 3));
|
|
|
|
|
|
Ref<Shape> tapered_capsule = TaperedCapsuleShapeSettings(2.0f, 0.5f, 0.7f).Create().Get();
|
|
|
CHECK(!tapered_capsule->IsValidScale(Vec3::sZero()));
|
|
@@ -144,30 +152,47 @@ TEST_SUITE("ShapeTests")
|
|
|
CHECK(!tapered_capsule->IsValidScale(Vec3(2, 1, 1)));
|
|
|
CHECK(!tapered_capsule->IsValidScale(Vec3(1, 2, 1)));
|
|
|
CHECK(!tapered_capsule->IsValidScale(Vec3(1, 1, 2)));
|
|
|
+ CHECK(tapered_capsule->MakeScaleValid(Vec3::sZero()).IsClose(Vec3::sReplicate(ScaleHelpers::cMinScale), cMinScaleToleranceSq));
|
|
|
+ CHECK(tapered_capsule->MakeScaleValid(Vec3(2, -3, 4)) == Vec3(3, -3, 3));
|
|
|
|
|
|
Ref<Shape> cylinder = new CylinderShape(0.5f, 2.0f);
|
|
|
CHECK(!cylinder->IsValidScale(Vec3::sZero()));
|
|
|
+ CHECK(!cylinder->IsValidScale(Vec3(0, 1, 0)));
|
|
|
+ CHECK(!cylinder->IsValidScale(Vec3(1, 0, 1)));
|
|
|
CHECK(cylinder->IsValidScale(Vec3(2, 2, 2)));
|
|
|
CHECK(cylinder->IsValidScale(Vec3(-1, 1, -1)));
|
|
|
CHECK(!cylinder->IsValidScale(Vec3(2, 1, 1)));
|
|
|
CHECK(cylinder->IsValidScale(Vec3(1, 2, 1)));
|
|
|
CHECK(!cylinder->IsValidScale(Vec3(1, 1, 2)));
|
|
|
+ CHECK(cylinder->MakeScaleValid(Vec3::sZero()).IsClose(Vec3::sReplicate(ScaleHelpers::cMinScale), cMinScaleToleranceSq));
|
|
|
+ CHECK(cylinder->MakeScaleValid(Vec3(-1.0e-10f, 1, 1.0e-10f)) == Vec3(-ScaleHelpers::cMinScale, 1, ScaleHelpers::cMinScale));
|
|
|
+ CHECK(cylinder->MakeScaleValid(Vec3(2, 5, -4)) == Vec3(3, 5, -3));
|
|
|
|
|
|
Ref<Shape> triangle = new TriangleShape(Vec3(1, 2, 3), Vec3(4, 5, 6), Vec3(7, 8, 9));
|
|
|
CHECK(!triangle->IsValidScale(Vec3::sZero()));
|
|
|
+ CHECK(!triangle->IsValidScale(Vec3::sAxisX()));
|
|
|
+ CHECK(!triangle->IsValidScale(Vec3::sAxisY()));
|
|
|
+ CHECK(!triangle->IsValidScale(Vec3::sAxisZ()));
|
|
|
CHECK(triangle->IsValidScale(Vec3(2, 2, 2)));
|
|
|
CHECK(triangle->IsValidScale(Vec3(-1, 1, -1)));
|
|
|
CHECK(triangle->IsValidScale(Vec3(2, 1, 1)));
|
|
|
CHECK(triangle->IsValidScale(Vec3(1, 2, 1)));
|
|
|
CHECK(triangle->IsValidScale(Vec3(1, 1, 2)));
|
|
|
+ CHECK(triangle->MakeScaleValid(Vec3::sZero()).IsClose(Vec3::sReplicate(ScaleHelpers::cMinScale), cMinScaleToleranceSq));
|
|
|
+ CHECK(triangle->MakeScaleValid(Vec3(2, 5, -4)) == Vec3(2, 5, -4));
|
|
|
|
|
|
Ref<Shape> triangle2 = new TriangleShape(Vec3(1, 2, 3), Vec3(4, 5, 6), Vec3(7, 8, 9), 0.01f); // With convex radius
|
|
|
CHECK(!triangle2->IsValidScale(Vec3::sZero()));
|
|
|
+ CHECK(!triangle2->IsValidScale(Vec3::sAxisX()));
|
|
|
+ CHECK(!triangle2->IsValidScale(Vec3::sAxisY()));
|
|
|
+ CHECK(!triangle2->IsValidScale(Vec3::sAxisZ()));
|
|
|
CHECK(triangle2->IsValidScale(Vec3(2, 2, 2)));
|
|
|
CHECK(triangle2->IsValidScale(Vec3(-1, 1, -1)));
|
|
|
CHECK(!triangle2->IsValidScale(Vec3(2, 1, 1)));
|
|
|
CHECK(!triangle2->IsValidScale(Vec3(1, 2, 1)));
|
|
|
CHECK(!triangle2->IsValidScale(Vec3(1, 1, 2)));
|
|
|
+ CHECK(triangle2->MakeScaleValid(Vec3::sZero()).IsClose(Vec3::sReplicate(ScaleHelpers::cMinScale), cMinScaleToleranceSq));
|
|
|
+ CHECK(triangle2->MakeScaleValid(Vec3(2, 6, -4)) == Vec3(4, 4, -4));
|
|
|
|
|
|
Ref<Shape> scaled = new ScaledShape(sphere, Vec3(1, 2, 1));
|
|
|
CHECK(!scaled->IsValidScale(Vec3::sZero()));
|
|
@@ -282,6 +307,22 @@ TEST_SUITE("ShapeTests")
|
|
|
CHECK(!mutable_compound4->IsValidScale(Vec3(1, 2, 1)));
|
|
|
CHECK(mutable_compound4->IsValidScale(Vec3(1, 1, 2))); // We're rotation around Z, so non-uniform in the Z direction is ok
|
|
|
|
|
|
+ // Test a cylinder rotated by 90 degrees around Z rotating Y to X, meaning that Y and Z should be scaled uniformly
|
|
|
+ MutableCompoundShapeSettings mutable_compound_settings5;
|
|
|
+ mutable_compound_settings5.AddShape(Vec3(1, 2, 3), Quat::sRotation(Vec3::sAxisZ(), -0.5f * JPH_PI), new CylinderShape(1.0f, 0.5f));
|
|
|
+ Ref<Shape> mutable_compound5 = mutable_compound_settings5.Create().Get();
|
|
|
+ CHECK(mutable_compound5->IsValidScale(Vec3::sReplicate(2)));
|
|
|
+ CHECK(mutable_compound5->IsValidScale(Vec3(1, 2, 2)));
|
|
|
+ CHECK(mutable_compound5->IsValidScale(Vec3(1, 2, -2)));
|
|
|
+ CHECK(!mutable_compound5->IsValidScale(Vec3(2, 1, 2)));
|
|
|
+ CHECK(!mutable_compound5->IsValidScale(Vec3(2, 2, 1)));
|
|
|
+ CHECK(mutable_compound5->MakeScaleValid(Vec3::sReplicate(2)).IsClose(Vec3::sReplicate(2)));
|
|
|
+ CHECK(mutable_compound5->MakeScaleValid(Vec3::sReplicate(-2)).IsClose(Vec3::sReplicate(-2)));
|
|
|
+ CHECK(mutable_compound5->MakeScaleValid(Vec3(1, 2, 2)).IsClose(Vec3(1, 2, 2)));
|
|
|
+ CHECK(mutable_compound5->MakeScaleValid(Vec3(1, 2, -2)).IsClose(Vec3(1, 2, -2)));
|
|
|
+ CHECK(mutable_compound5->MakeScaleValid(Vec3(2, 1, 2)).IsClose(Vec3::sReplicate(5.0f / 3.0f))); // Not the best solution, but we don't have logic to average over YZ only
|
|
|
+ CHECK(mutable_compound5->MakeScaleValid(Vec3(2, 2, 1)).IsClose(Vec3::sReplicate(5.0f / 3.0f))); // Not the best solution, but we don't have logic to average over YZ only
|
|
|
+
|
|
|
// Test a rotated translated shape that can only be scaled uniformly
|
|
|
RotatedTranslatedShapeSettings rt_settings(Vec3(1, 2, 3), Quat::sRotation(Vec3::sAxisX(), 0.1f * JPH_PI), sphere);
|
|
|
Ref<Shape> rt_shape = rt_settings.Create().Get();
|
|
@@ -321,6 +362,21 @@ TEST_SUITE("ShapeTests")
|
|
|
CHECK(!rt_shape4->IsValidScale(Vec3(2, 1, 1)));
|
|
|
CHECK(!rt_shape4->IsValidScale(Vec3(1, 2, 1)));
|
|
|
CHECK(rt_shape4->IsValidScale(Vec3(1, 1, 2))); // We're rotation around Z, so non-uniform in the Z direction is ok
|
|
|
+
|
|
|
+ // Test a cylinder rotated by 90 degrees around Z rotating Y to X, meaning that Y and Z should be scaled uniformly
|
|
|
+ RotatedTranslatedShapeSettings rt_settings5(Vec3(1, 2, 3), Quat::sRotation(Vec3::sAxisZ(), -0.5f * JPH_PI), new CylinderShape(1.0f, 0.5f));
|
|
|
+ Ref<Shape> rt_shape5 = rt_settings5.Create().Get();
|
|
|
+ CHECK(rt_shape5->IsValidScale(Vec3::sReplicate(2)));
|
|
|
+ CHECK(rt_shape5->IsValidScale(Vec3(1, 2, 2)));
|
|
|
+ CHECK(rt_shape5->IsValidScale(Vec3(1, 2, -2)));
|
|
|
+ CHECK(!rt_shape5->IsValidScale(Vec3(2, 1, 2)));
|
|
|
+ CHECK(!rt_shape5->IsValidScale(Vec3(2, 2, 1)));
|
|
|
+ CHECK(rt_shape5->MakeScaleValid(Vec3::sReplicate(2)).IsClose(Vec3::sReplicate(2)));
|
|
|
+ CHECK(rt_shape5->MakeScaleValid(Vec3::sReplicate(-2)).IsClose(Vec3::sReplicate(-2)));
|
|
|
+ CHECK(rt_shape5->MakeScaleValid(Vec3(1, 2, 2)).IsClose(Vec3(1, 2, 2)));
|
|
|
+ CHECK(rt_shape5->MakeScaleValid(Vec3(1, 2, -2)).IsClose(Vec3(1, 2, -2)));
|
|
|
+ CHECK(rt_shape5->MakeScaleValid(Vec3(2, 1, 2)).IsClose(Vec3(2, 1.5f, 1.5f))); // YZ will be averaged here
|
|
|
+ CHECK(rt_shape5->MakeScaleValid(Vec3(2, 2, 1)).IsClose(Vec3(2, 1.5f, 1.5f))); // YZ will be averaged here
|
|
|
}
|
|
|
|
|
|
// Test embedded shape
|