public boolean SPETestTriangleAABB(PVector v0, PVector v1, PVector v2, PVector bmin, PVector bmax) { float p0, p1, p2, r; PVector c = PVector.add(bmin , bmax); c.mult( 0.5 ); float e0 = (bmax.x -bmin.x) * 0.5 ; float e1 = (bmax.y -bmin.y) * 0.5 ; float e2 = (bmax.z -bmin.z) * 0.5 ; v0 = PVector.sub(v0 , c); v1 = PVector.sub(v1 , c); v2 = PVector.sub(v2 , c); PVector f0 = PVector.sub(v1 , v0); PVector f1 = PVector.sub(v2 , v1); PVector f2 = PVector.sub(v0 , v2); //a00 p0 = -v0.y * (v1.z - v0.z) + v0.z * (v1.y - v0.y); p1 = -v1.y * (v1.z - v0.z) + v1.z * (v1.y - v0.y); p2 = -v2.y * (v1.z - v0.z) + v2.z * (v1.y - v0.y); r = e1 * abs(f0.z) + e2 * abs(f0.y); if(max(-max(max(p0, p1), p2), min(min(p0, p1), p2)) > r) { return false; } //a01 p0 = -v0.y * (v2.z - v1.z) + v0.z * (v2.y - v1.y); p1 = -v1.y * (v2.z - v1.z) + v1.z * (v2.y - v1.y); p2 = -v2.y * (v2.z - v1.z) + v2.z * (v2.y - v1.y); r = e1 * abs(f1.z) + e2 * abs(f1.y); if(max(-max(max(p0, p1), p2), min(min(p0, p1), p2)) > r) { return false; } //a02 p0 = -v0.y * (v0.z - v2.z) + v0.z * (v0.y - v2.y); p1 = -v1.y * (v0.z - v2.z) + v1.z * (v0.y - v2.y); p2 = -v2.y * (v0.z - v2.z) + v2.z * (v0.y - v2.y); r = e1 * abs(f2.z) + e2 * abs(f2.y); if(max(-max(max(p0, p1), p2), min(min(p0, p1), p2)) > r) { return false; } //a10 p0 = v0.x * (v1.z - v0.z) + -v0.z * (v1.x - v0.x); p1 = v1.x * (v1.z - v0.z) + -v1.z * (v1.x - v0.x); p2 = v2.x * (v1.z - v0.z) + -v2.z * (v1.x - v0.x); r = e0 * abs(f0.z) + e2 * abs(f0.x); if(max(-max(max(p0, p1), p2), min(min(p0, p1), p2)) > r) { return false; } //a11 p0 = v0.x * (v2.z - v1.z) + -v0.z * (v2.x - v1.x); p1 = v1.x * (v2.z - v1.z) + -v1.z * (v2.x - v1.x); p2 = v2.x * (v2.z - v1.z) + -v2.z * (v2.x - v1.x); r = e0 * abs(f1.z) + e2 * abs(f1.x); if(max(-max(max(p0, p1), p2), min(min(p0, p1), p2)) > r) { return false; } //a12 p0 = v0.x * (v0.z - v2.z) + -v0.z * (v0.x - v2.x); p1 = v1.x * (v0.z - v2.z) + -v1.z * (v0.x - v2.x); p2 = v2.x * (v0.z - v2.z) + -v2.z * (v0.x - v2.x); r = e0 * abs(f2.z) + e2 * abs(f2.x); if(max(-max(max(p0, p1), p2), min(min(p0, p1), p2)) > r) { return false; } //a20 p0 = -v0.x * (v1.y - v0.y) + v0.y * (v1.x - v0.x); p1 = -v1.x * (v1.y - v0.y) + v1.y * (v1.x - v0.x); p2 = -v2.x * (v1.y - v0.y) + v2.y * (v1.x - v0.x); r = e0 * abs(f0.y) + e1 * abs(f0.x); if(max(-max(max(p0, p1), p2), min(min(p0, p1), p2)) > r) { return false; } //a21 p0 = -v0.x * (v2.y - v1.y) + v0.y * (v2.x - v1.x); p1 = -v1.x * (v2.y - v1.y) + v1.y * (v2.x - v1.x); p2 = -v2.x * (v2.y - v1.y) + v2.y * (v2.x - v1.x); r = e0 * abs(f1.y) + e1 * abs(f1.x); if(max(-max(max(p0, p1), p2), min(min(p0, p1), p2)) > r) { return false; } //a22 p0 = -v0.x * (v0.y - v2.y) + v0.y * (v0.x - v2.x); p1 = -v1.x * (v0.y - v2.y) + v1.y * (v0.x - v2.x); p2 = -v2.x * (v0.y - v2.y) + v2.y * (v0.x - v2.x); r = e0 * abs(f2.y) + e1 * abs(f2.x); if(max(-max(max(p0, p1), p2), min(min(p0, p1), p2)) > r) { return false; } if(max(max(v0.x, v1.x), v2.x) < -e0 || min(min(v0.x, v1.x), v2.x) > e0) { return false; } if(max(max(v0.y, v1.y), v2.y) < -e1 || min(min(v0.y, v1.y), v2.y) > e1) { return false; } if(max(max(v0.z, v1.z), v2.z) < -e2 || min(min(v0.z, v1.z), v2.z) > e2) { return false; } PVector pn = f0.cross(f1); float pd = pn.dot(v0); PVector b2min, b2max; b2min = PVector.sub(bmin , c); b2max = PVector.sub(bmax , c); return SPETestAABBPlane(b2min, b2max, pn, pd); } public boolean SPETestAABBPlane(PVector b2min, PVector b2max, PVector pn, float pd) { // These two lines not necessary with a (center, extents) AABB representation PVector c = PVector.add(b2max , b2min); c.mult ( 0.5 ) ; // Compute AABB center PVector e = PVector.sub(b2max , c); // Compute positive extents // Compute the projection interval radius of b onto L(t) = b.c + t * p.n float r = e.x*abs(pn.x) + e.y*abs(pn.y) + e.z*abs(pn.z); // Compute distance of box center from plane float s = pn.dot(c) - pd; // Intersection occurs when distance s falls within [-r,+r] interval if (abs(s) <= r) { return(true); } else { return(false); } }