public void TestLineSegIntersect() { foreach (Aabb box in Take(100, Aabbs)) { checkBox(box); Aabb a, b, c, d; box.QuadBreak(out a, out b, out c, out d); checkBox(a); checkBox(b); checkBox(c); checkBox(d); Aabb[] subs = new Aabb[] { a, b, c, d }; foreach (Aabb t in subs) { Assert.IsTrue(box.Contains(t)); Assert.IsTrue(box.Intersects(t)); Assert.IsTrue(t.Intersects(box)); Assert.IsFalse(t.Contains(box)); Assert.IsTrue(Math.Abs((box.H * 0.5) - t.H) < 0.00001, "Not half height?"); Assert.IsTrue(Math.Abs((box.W * 0.5) - t.W) < 0.00001, "Not half width?"); foreach (Aabb tt in subs) { if (tt == t) { continue; } Assert.IsFalse(t.Contains(tt)); Assert.IsFalse(tt.Contains(t)); if (t.Intersects(tt)) { Aabb x = Aabb.Intersect(t, tt); Assert.IsTrue(x.W >= 0.0, "Neg width?"); Assert.IsTrue(x.H >= 0.0, "Neg height?"); Assert.IsTrue((x.W * x.H) < 0.000001, "non-tiny intersection?"); } } } foreach (Aabb o in new Aabb[] { b, c, d }) { Assert.IsFalse(a.Contains(o)); } } }
public void TestAabb() { float3 v0 = float3(100, 200, 300); float3 v1 = float3(200, 300, 400); float3 v2 = float3(50, 100, 350); Aabb a0; a0.Min = float3.zero; a0.Max = v0; Aabb a1; a1.Min = float3.zero; a1.Max = v1; Aabb a2; a2.Min = v2; a2.Max = v1; Aabb a3; a3.Min = v2; a3.Max = v0; Assert.IsTrue(a0.IsValid); Assert.IsTrue(a1.IsValid); Assert.IsTrue(a2.IsValid); Assert.IsFalse(a3.IsValid); Assert.IsTrue(a1.Contains(a0)); Assert.IsFalse(a0.Contains(a1)); Assert.IsTrue(a1.Contains(a2)); Assert.IsFalse(a2.Contains(a1)); Assert.IsFalse(a0.Contains(a2)); Assert.IsFalse(a2.Contains(a0)); // Test Union / Intersect { Aabb unionAabb = a0; unionAabb.Include(a1); Assert.IsTrue(unionAabb.Min.x == 0); Assert.IsTrue(unionAabb.Min.y == 0); Assert.IsTrue(unionAabb.Min.z == 0); Assert.IsTrue(unionAabb.Max.x == a1.Max.x); Assert.IsTrue(unionAabb.Max.y == a1.Max.y); Assert.IsTrue(unionAabb.Max.z == a1.Max.z); Aabb intersectAabb = a2; intersectAabb.Intersect(a3); Assert.IsTrue(intersectAabb.Min.x == 50); Assert.IsTrue(intersectAabb.Min.y == 100); Assert.IsTrue(intersectAabb.Min.z == 350); Assert.IsTrue(intersectAabb.Max.x == a3.Max.x); Assert.IsTrue(intersectAabb.Max.y == a3.Max.y); Assert.IsTrue(intersectAabb.Max.z == a3.Max.z); } // Test Expand / Contains { Aabb a5; a5.Min = v2; a5.Max = v1; float3 testPoint = float3(v2.x - 1.0f, v1.y + 1.0f, .5f * (v2.z + v1.z)); Assert.IsFalse(a5.Contains(testPoint)); a5.Expand(1.5f); Assert.IsTrue(a5.Contains(testPoint)); } // Test transform { Aabb ut; ut.Min = v0; ut.Max = v1; // Identity transform should not modify aabb Aabb outAabb = Unity.Physics.Math.TransformAabb(RigidTransform.identity, ut); TestUtils.AreEqual(ut.Min, outAabb.Min, 1e-3f); // Test translation outAabb = Unity.Physics.Math.TransformAabb(new RigidTransform(quaternion.identity, float3(100.0f, 0.0f, 0.0f)), ut); Assert.AreEqual(outAabb.Min.x, 200); Assert.AreEqual(outAabb.Min.y, 200); Assert.AreEqual(outAabb.Max.x, 300); Assert.AreEqual(outAabb.Max.z, 400); // Test rotation quaternion rot = quaternion.EulerXYZ(0.0f, 0.0f, k_pi2); outAabb = Unity.Physics.Math.TransformAabb(new RigidTransform(rot, float3.zero), ut); TestUtils.AreEqual(outAabb.Min, float3(-300.0f, 100.0f, 300.0f), 1e-3f); TestUtils.AreEqual(outAabb.Max, float3(-200.0f, 200.0f, 400.0f), 1e-3f); TestUtils.AreEqual(outAabb.SurfaceArea, ut.SurfaceArea, 1e-2f); } }