blob: 7480e7293b7ca1ec1f34d75ed16735dac1aa3183 [file] [log] [blame]
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);
}
}
}