| |
| package com.badlogic.gdx.math; |
| |
| import static org.junit.Assert.assertFalse; |
| import static org.junit.Assert.assertTrue; |
| |
| import org.junit.Test; |
| |
| import com.badlogic.gdx.math.Intersector.SplitTriangle; |
| |
| public class IntersectorTest { |
| |
| /** Compares two triangles for equality. Triangles must have the same winding, but may begin with different vertex. Values are |
| * epsilon compared, with default tolerance. Triangles are assumed to be valid triangles - no duplicate vertices. */ |
| private static boolean triangleEquals (float[] base, int baseOffset, int stride, float[] comp) { |
| assertTrue(stride >= 3); |
| assertTrue(base.length - baseOffset >= 9); |
| assertTrue(comp.length == 9); |
| |
| int offset = -1; |
| // Find first comp vertex in base triangle |
| for (int i = 0; i < 3; i++) { |
| int b = baseOffset + i * stride; |
| if (MathUtils.isEqual(base[b], comp[0]) && MathUtils.isEqual(base[b + 1], comp[1]) |
| && MathUtils.isEqual(base[b + 2], comp[2])) { |
| offset = i; |
| break; |
| } |
| } |
| assertTrue("Triangles do not have common first vertex.", offset != -1); |
| // Compare vertices |
| for (int i = 0; i < 3; i++) { |
| int b = baseOffset + ((offset + i) * stride) % (3 * stride); |
| int c = i * stride; |
| if (!MathUtils.isEqual(base[b], comp[c]) || !MathUtils.isEqual(base[b + 1], comp[c + 1]) |
| || !MathUtils.isEqual(base[b + 2], comp[c + 2])) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| @Test |
| public void testSplitTriangle () { |
| Plane plane = new Plane(new Vector3(1, 0, 0), 0); |
| SplitTriangle split = new SplitTriangle(3); |
| |
| {// All back |
| float[] fTriangle = {-10, 0, 10, -1, 0, 0, -12, 0, 10}; // Whole triangle on the back side |
| Intersector.splitTriangle(fTriangle, plane, split); |
| assertTrue(split.numBack == 1); |
| assertTrue(split.numFront == 0); |
| assertTrue(split.total == 1); |
| assertTrue(triangleEquals(split.back, 0, 3, fTriangle)); |
| |
| fTriangle[4] = 5f; |
| assertFalse("Test is broken", triangleEquals(split.back, 0, 3, fTriangle)); |
| } |
| |
| {// All front |
| float[] fTriangle = {10, 0, 10, 1, 0, 0, 12, 0, 10}; // Whole triangle on the front side |
| Intersector.splitTriangle(fTriangle, plane, split); |
| assertTrue(split.numBack == 0); |
| assertTrue(split.numFront == 1); |
| assertTrue(split.total == 1); |
| assertTrue(triangleEquals(split.front, 0, 3, fTriangle)); |
| } |
| |
| {// Two back, one front |
| float[] triangle = {-10, 0, 10, 10, 0, 0, -10, 0, -10}; // ABC One vertex in front, two in back |
| Intersector.splitTriangle(triangle, plane, split); // Split points are D (0,0,5) and E (0,0,-5) |
| assertTrue(split.numBack == 2); |
| assertTrue(split.numFront == 1); |
| assertTrue(split.total == 3); |
| // There is only one way to triangulate front |
| assertTrue(triangleEquals(split.front, 0, 3, new float[] {0, 0, 5, 10, 0, 0, 0, 0, -5})); |
| |
| // There are two ways to triangulate back |
| float[][] firstWay = { {-10, 0, 10, 0, 0, 5, 0, 0, -5}, {-10, 0, 10, 0, 0, -5, -10, 0, -10}};// ADE AEC |
| float[][] secondWay = { {-10, 0, 10, 0, 0, 5, -10, 0, -10}, {0, 0, 5, 0, 0, -5, -10, 0, -10}};// ADC DEC |
| float[] base = split.back; |
| boolean first = (triangleEquals(base, 0, 3, firstWay[0]) && triangleEquals(base, 9, 3, firstWay[1])) |
| || (triangleEquals(base, 0, 3, firstWay[1]) && triangleEquals(base, 9, 3, firstWay[0])); |
| boolean second = (triangleEquals(base, 0, 3, secondWay[0]) && triangleEquals(base, 9, 3, secondWay[1])) |
| || (triangleEquals(base, 0, 3, secondWay[1]) && triangleEquals(base, 9, 3, secondWay[0])); |
| assertTrue("Either first or second way must be right (first: " + first + ", second: " + second + ")", first ^ second); |
| } |
| |
| {// Two front, one back |
| float[] triangle = {10, 0, 10, -10, 0, 0, 10, 0, -10}; // ABC One vertex in back, two in front |
| Intersector.splitTriangle(triangle, plane, split); // Split points are D (0,0,5) and E (0,0,-5) |
| assertTrue(split.numBack == 1); |
| assertTrue(split.numFront == 2); |
| assertTrue(split.total == 3); |
| // There is only one way to triangulate back |
| assertTrue(triangleEquals(split.back, 0, 3, new float[] {0, 0, 5, -10, 0, 0, 0, 0, -5})); |
| |
| // There are two ways to triangulate front |
| float[][] firstWay = { {10, 0, 10, 0, 0, 5, 0, 0, -5}, {10, 0, 10, 0, 0, -5, 10, 0, -10}};// ADE AEC |
| float[][] secondWay = { {10, 0, 10, 0, 0, 5, 10, 0, -10}, {0, 0, 5, 0, 0, -5, 10, 0, -10}};// ADC DEC |
| float[] base = split.front; |
| boolean first = (triangleEquals(base, 0, 3, firstWay[0]) && triangleEquals(base, 9, 3, firstWay[1])) |
| || (triangleEquals(base, 0, 3, firstWay[1]) && triangleEquals(base, 9, 3, firstWay[0])); |
| boolean second = (triangleEquals(base, 0, 3, secondWay[0]) && triangleEquals(base, 9, 3, secondWay[1])) |
| || (triangleEquals(base, 0, 3, secondWay[1]) && triangleEquals(base, 9, 3, secondWay[0])); |
| assertTrue("Either first or second way must be right (first: " + first + ", second: " + second + ")", first ^ second); |
| } |
| } |
| } |