bool Octree::boxTriangleIntersection(BoundingBox Box, Triangle triangle) { //This algorithm is a composition of 13 tests to determine intersection //if all pass, there is overlap float min,max,d,p0,p1,p2,rad,fex,fey,fez; //center the box at (0,0,0) with respect to the triangle //translate triangle vertices Vector v0,v1,v2; //edges of new triangle Vector e0,e1,e2; //Vector that goes half the diagonal of the bounding box Vector boxHalfSize = (Box.boxMaxExtent - Box.boxMinExtent) / 2.0; point boxCenter( (Box.boxMinExtent.px + Box.boxMaxExtent.px)/2.0, (Box.boxMinExtent.py + Box.boxMaxExtent.py)/2.0, (Box.boxMinExtent.pz + Box.boxMaxExtent.pz)/2.0 ); /*v0.set(triangle.Vertex[0].px-boxCenter.px,triangle.Vertex[0].py-boxCenter.py,triangle.Vertex[0].pz-boxCenter.pz); v1.set(triangle.Vertex[1].px-boxCenter.px,triangle.Vertex[1].py-boxCenter.py,triangle.Vertex[1].pz-boxCenter.pz); v2.set(triangle.Vertex[2].px-boxCenter.px,triangle.Vertex[2].py-boxCenter.py,triangle.Vertex[2].pz-boxCenter.pz);*/ v0 = triangle.Vertex[0] - boxCenter; v1 = triangle.Vertex[1] - boxCenter; v2 = triangle.Vertex[2] - boxCenter; e0 = v1 - v0; e1 = v2 - v1; e2 = v0 - v2; //the first 9 tests fex = fabs(e0.px); fey = fabs(e0.py); fez = fabs(e0.pz); AXISTEST_X01(e0.pz, e0.py, fez, fey); AXISTEST_Y02(e0.pz, e0.px, fez, fex); AXISTEST_Z12(e0.py, e0.px, fey, fex); fex = fabs(e1.px); fey = fabs(e1.py); fez = fabs(e1.pz); AXISTEST_X01(e1.pz, e1.py, fez, fey); AXISTEST_Y02(e1.pz, e1.px, fez, fex); AXISTEST_Z0(e1.py, e1.px, fey, fex); fex = fabs(e2.px); fey = fabs(e2.py); fez = fabs(e2.pz); AXISTEST_X2(e2.pz, e2.py, fez, fey); AXISTEST_Y1(e2.pz, e2.px, fez, fex); AXISTEST_Z12(e2.py, e2.px, fey, fex); //now the 3 tests //X test FINDMINMAX(v0.px,v1.px,v2.px,min,max); if(min>boxHalfSize.px || max<-boxHalfSize.px) return false; //Y test FINDMINMAX(v0.py,v1.py,v2.py,min,max); if(min>boxHalfSize.py || max<-boxHalfSize.py) return false; //Z test FINDMINMAX(v0.pz,v1.pz,v2.pz,min,max); if(min>boxHalfSize.pz || max<-boxHalfSize.pz) return false; Vector normal = e0.crossProduct(e1); d = -(normal.dotProduct(v0)); if(!planeBoxOverlap(normal,d,boxHalfSize)) return false; return true; }
int triBoxOverlap(float boxcenter[3],float boxhalfsize[3],float triverts[3][3]) { /* use separating axis theorem to test overlap between triangle and box */ /* need to test for overlap in these directions: */ /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ /* we do not even need to test these) */ /* 2) normal of the triangle */ /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ /* this gives 3x3=9 more tests */ float v0[3],v1[3],v2[3]; // float axis[3]; float min,max,p0,p1,p2,rad,fex,fey,fez; // -NJMP- "d" local variable removed float normal[3],e0[3],e1[3],e2[3]; /* This is the fastest branch on Sun */ /* move everything so that the boxcenter is in (0,0,0) */ SUB(v0,triverts[0],boxcenter); SUB(v1,triverts[1],boxcenter); SUB(v2,triverts[2],boxcenter); /* compute triangle edges */ SUB(e0,v1,v0); /* tri edge 0 */ SUB(e1,v2,v1); /* tri edge 1 */ SUB(e2,v0,v2); /* tri edge 2 */ /* Bullet 3: */ /* test the 9 tests first (this was faster) */ fex = fabsf(e0[X]); fey = fabsf(e0[Y]); fez = fabsf(e0[Z]); AXISTEST_X01(e0[Z], e0[Y], fez, fey); AXISTEST_Y02(e0[Z], e0[X], fez, fex); AXISTEST_Z12(e0[Y], e0[X], fey, fex); fex = fabsf(e1[X]); fey = fabsf(e1[Y]); fez = fabsf(e1[Z]); AXISTEST_X01(e1[Z], e1[Y], fez, fey); AXISTEST_Y02(e1[Z], e1[X], fez, fex); AXISTEST_Z0(e1[Y], e1[X], fey, fex); fex = fabsf(e2[X]); fey = fabsf(e2[Y]); fez = fabsf(e2[Z]); AXISTEST_X2(e2[Z], e2[Y], fez, fey); AXISTEST_Y1(e2[Z], e2[X], fez, fex); AXISTEST_Z12(e2[Y], e2[X], fey, fex); /* Bullet 1: */ /* first test overlap in the {x,y,z}-directions */ /* find min, max of the triangle each direction, and test for overlap in */ /* that direction -- this is equivalent to testing a minimal AABB around */ /* the triangle against the AABB */ /* test in X-direction */ FINDMINMAX(v0[X],v1[X],v2[X],min,max); if(min>boxhalfsize[X] || max<-boxhalfsize[X]) return 0; /* test in Y-direction */ FINDMINMAX(v0[Y],v1[Y],v2[Y],min,max); if(min>boxhalfsize[Y] || max<-boxhalfsize[Y]) return 0; /* test in Z-direction */ FINDMINMAX(v0[Z],v1[Z],v2[Z],min,max); if(min>boxhalfsize[Z] || max<-boxhalfsize[Z]) return 0; /* Bullet 2: */ /* test if the box intersects the plane of the triangle */ /* compute plane equation of triangle: normal*x+d=0 */ CROSS(normal,e0,e1); // -NJMP- (line removed here) if(!planeBoxOverlap(normal,v0,boxhalfsize)) return 0; // -NJMP- return 1; /* box and triangle overlaps */ }
bool8 AtiTriBoxMoller( const TBM_FLOAT boxcenter[3], const TBM_FLOAT boxhalfsize[3], const TBM_FLOAT triVert0[3], const TBM_FLOAT triVert1[3], const TBM_FLOAT triVert2[3]) { // use separating axis theorem to test overlap between triangle and box // need to test for overlap in these directions: // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle // we do not even need to test these) // 2) normal of the triangle // 3) crossproduct(edge from tri, {x,y,z}-directin) // this gives 3x3=9 more tests TBM_FLOAT v0[3], v1[3], v2[3]; TBM_FLOAT min, max, d, p0, p1, p2, rad, fex, fey, fez; TBM_FLOAT normal[3], e0[3], e1[3], e2[3]; // This is the fastest branch on Sun // move everything so that the boxcenter is in (0,0,0) SUB (v0, triVert0, boxcenter); SUB (v1, triVert1, boxcenter); SUB (v2, triVert2, boxcenter); // compute triangle edges SUB (e0, v1, v0); // tri edge 0 SUB (e1, v2, v1); // tri edge 1 SUB (e2, v0, v2); // tri edge 2 // Bullet 3: // test the 9 tests first (this was faster) fex = (TBM_FLOAT)fabs (e0[X]); fey = (TBM_FLOAT)fabs (e0[Y]); fez = (TBM_FLOAT)fabs (e0[Z]); AXISTEST_X01 (e0[Z], e0[Y], fez, fey); AXISTEST_Y02 (e0[Z], e0[X], fez, fex); AXISTEST_Z12 (e0[Y], e0[X], fey, fex); fex = (TBM_FLOAT)fabs (e1[X]); fey = (TBM_FLOAT)fabs (e1[Y]); fez = (TBM_FLOAT)fabs (e1[Z]); AXISTEST_X01 (e1[Z], e1[Y], fez, fey); AXISTEST_Y02 (e1[Z], e1[X], fez, fex); AXISTEST_Z0 (e1[Y], e1[X], fey, fex); fex = (TBM_FLOAT)fabs (e2[X]); fey = (TBM_FLOAT)fabs (e2[Y]); fez = (TBM_FLOAT)fabs (e2[Z]); AXISTEST_X2 (e2[Z], e2[Y], fez, fey); AXISTEST_Y1 (e2[Z], e2[X], fez, fex); AXISTEST_Z12 (e2[Y], e2[X], fey, fex); // Bullet 1: // first test overlap in the {x,y,z}-directions // find min, max of the triangle each direction, and test for overlap in // that direction -- this is equivalent to testing a minimal AABB around // the triangle against the AABB // test in X-direction FINDMINMAX (v0[X], v1[X], v2[X], min, max); if (min > boxhalfsize[X] || max < -boxhalfsize[X]) { return FALSE; } // test in Y-direction FINDMINMAX (v0[Y], v1[Y], v2[Y], min, max); if (min > boxhalfsize[Y] || max < -boxhalfsize[Y]) { return FALSE; } // test in Z-direction FINDMINMAX (v0[Z], v1[Z], v2[Z], min, max); if (min > boxhalfsize[Z] || max < -boxhalfsize[Z]) { return FALSE; } // Bullet 2: // test if the box intersects the plane of the triangle // compute plane equation of triangle: normal*x+d=0 CROSS (normal, e0, e1); d = -DOT (normal, v0); // plane eq: normal.x+d=0 return AtiPlaneBoxOverlap (normal, d, boxhalfsize); }
static bool fast_tri_box_overlap(const Vector3& boxcenter,const Vector3 boxhalfsize,const Vector3 *triverts) { /* use separating axis theorem to test overlap between triangle and box */ /* need to test for overlap in these directions: */ /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ /* we do not even need to test these) */ /* 2) normal of the triangle */ /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ /* this gives 3x3=9 more tests */ Vector3 v0,v1,v2; float min,max,d,p0,p1,p2,rad,fex,fey,fez; Vector3 normal,e0,e1,e2; /* This is the fastest branch on Sun */ /* move everything so that the boxcenter is in (0,0,0) */ v0=triverts[0]-boxcenter; v1=triverts[1]-boxcenter; v2=triverts[2]-boxcenter; /* compute triangle edges */ e0=v1-v0; /* tri edge 0 */ e1=v2-v1; /* tri edge 1 */ e2=v0-v2; /* tri edge 2 */ /* Bullet 3: */ /* test the 9 tests first (this was faster) */ fex = Math::abs(e0.x); fey = Math::abs(e0.y); fez = Math::abs(e0.z); AXISTEST_X01(e0.z, e0.y, fez, fey); AXISTEST_Y02(e0.z, e0.x, fez, fex); AXISTEST_Z12(e0.y, e0.x, fey, fex); fex = Math::abs(e1.x); fey = Math::abs(e1.y); fez = Math::abs(e1.z); AXISTEST_X01(e1.z, e1.y, fez, fey); AXISTEST_Y02(e1.z, e1.x, fez, fex); AXISTEST_Z0(e1.y, e1.x, fey, fex); fex = Math::abs(e2.x); fey = Math::abs(e2.y); fez = Math::abs(e2.z); AXISTEST_X2(e2.z, e2.y, fez, fey); AXISTEST_Y1(e2.z, e2.x, fez, fex); AXISTEST_Z12(e2.y, e2.x, fey, fex); /* Bullet 1: */ /* first test overlap in the {x,y,z}-directions */ /* find min, max of the triangle each direction, and test for overlap in */ /* that direction -- this is equivalent to testing a minimal AABB around */ /* the triangle against the AABB */ /* test in X-direction */ FINDMINMAX(v0.x,v1.x,v2.x,min,max); if(min>boxhalfsize.x || max<-boxhalfsize.x) return false; /* test in Y-direction */ FINDMINMAX(v0.y,v1.y,v2.y,min,max); if(min>boxhalfsize.y || max<-boxhalfsize.y) return false; /* test in Z-direction */ FINDMINMAX(v0.z,v1.z,v2.z,min,max); if(min>boxhalfsize.z || max<-boxhalfsize.z) return false; /* Bullet 2: */ /* test if the box intersects the plane of the triangle */ /* compute plane equation of triangle: normal*x+d=0 */ normal=e0.cross(e1); d=-normal.dot(v0); /* plane eq: normal.x+d=0 */ if(!planeBoxOverlap(normal,d,boxhalfsize)) return false; return true; /* box and triangle overlaps */ }
inline bool tri_box_overlap(const Aabb& aabb, const glm::vec3& triv0, const glm::vec3& triv1, const glm::vec3& triv2) { /* use separating axis theorem to test overlap between triangle and box */ /* need to test for overlap in these directions: */ /* 1) the {x, y, z}-directions (actually, since we use the AABB of the triangle */ /* we do not even need to test these) */ /* 2) normal of the triangle */ /* 3) crossproduct(edge from tri, {x, y, z}-directin) */ /* this gives 3x3=9 more tests */ /* move everything so that the boxcenter is in (0,0,0) */ glm::vec3 v0, v1, v2; v0 = triv0 - aabb.center; v1 = triv1 - aabb.center; v2 = triv2 - aabb.center; /* compute triangle edges */ glm::vec3 e0, e1, e2; e0 = v1 - v0; e1 = v2 - v1; e2 = v0 - v2; float min, max, p0, p1, p2, rad; /* Bullet 3: */ /* test the 9 tests first (this was faster) */ { float fex = glm::abs<float>(e0.x); float fey = glm::abs<float>(e0.y); float fez = glm::abs<float>(e0.z); AXISTEST_X01(e0.z, e0.y, fez, fey); AXISTEST_Y02(e0.z, e0.x, fez, fex); AXISTEST_Z12(e0.y, e0.x, fey, fex); } { float fex = glm::abs<float>(e1.x); float fey = glm::abs<float>(e1.y); float fez = glm::abs<float>(e1.z); AXISTEST_X01(e1.z, e1.y, fez, fey); AXISTEST_Y02(e1.z, e1.x, fez, fex); AXISTEST_Z0(e1.y, e1.x, fey, fex); } { float fex = glm::abs<float>(e2.x); float fey = glm::abs<float>(e2.y); float fez = glm::abs<float>(e2.z); AXISTEST_X2(e2.z, e2.y, fez, fey); AXISTEST_Y1(e2.z, e2.x, fez, fex); AXISTEST_Z12(e2.y, e2.x, fey, fex); } /* Bullet 1: */ /* first test overlap in the {x, y, z}-directions */ /* find min, max of the triangle each direction, and test for overlap in */ /* that direction -- this is equivalent to testing a minimal AABB around */ /* the triangle against the AABB */ /* test in X-direction */ detail::find_min_max(v0.x, v1.x, v2.x, min, max); if (min>aabb.half.x || max<-aabb.half.x) return false; /* test in Y-direction */ detail::find_min_max(v0.y, v1.y, v2.y, min, max); if (min>aabb.half.y || max<-aabb.half.y) return false; /* test in Z-direction */ detail::find_min_max(v0.z, v1.z, v2.z, min, max); if (min>aabb.half.z || max<-aabb.half.z) return false; /* Bullet 2: */ /* test if the box intersects the plane of the triangle */ /* compute plane equation of triangle: normal*x+d=0 */ glm::vec3 normal = glm::cross(e0, e1); return detail::plane_box_overlap(normal, v0, aabb.half); }
/* by Tomas Akenine-Möller */ bool BoundingBox::containsTriangle( const Vec& tv0, const Vec& tv1, const Vec& tv2 ) const { Vec boxcenter(center); Vec boxhalfsize(xExtent, yExtent, zExtent); int X = 0, Y = 1, Z = 2; /* use separating axis theorem to test overlap between triangle and box */ /* need to test for overlap in these directions: */ /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ /* we do not even need to test these) */ /* 2) normal of the triangle */ /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ /* this gives 3x3=9 more tests */ Vec v0,v1,v2; double min,max,p0,p1,p2,rad,fex,fey,fez; Vec normal,e0,e1,e2; /* This is the fastest branch on Sun */ /* move everything so that the box center is in (0,0,0) */ v0=tv0-boxcenter; v1=tv1-boxcenter; v2=tv2-boxcenter; /* compute triangle edges */ e0=v1-v0; /* tri edge 0 */ e1=v2-v1; /* tri edge 1 */ e2=v0-v2; /* tri edge 2 */ /* Bullet 3: */ /* test the 9 tests first (this was faster) */ fex = fabsf(e0[X]); fey = fabsf(e0[Y]); fez = fabsf(e0[Z]); AXISTEST_X01(e0[Z], e0[Y], fez, fey); AXISTEST_Y02(e0[Z], e0[X], fez, fex); AXISTEST_Z12(e0[Y], e0[X], fey, fex); fex = fabsf(e1[X]); fey = fabsf(e1[Y]); fez = fabsf(e1[Z]); AXISTEST_X01(e1[Z], e1[Y], fez, fey); AXISTEST_Y02(e1[Z], e1[X], fez, fex); AXISTEST_Z0(e1[Y], e1[X], fey, fex); fex = fabsf(e2[X]); fey = fabsf(e2[Y]); fez = fabsf(e2[Z]); AXISTEST_X2(e2[Z], e2[Y], fez, fey); AXISTEST_Y1(e2[Z], e2[X], fez, fex); AXISTEST_Z12(e2[Y], e2[X], fey, fex); /* Bullet 1: */ /* first test overlap in the {x,y,z}-directions */ /* find min, max of the triangle each direction, and test for overlap in */ /* that direction -- this is equivalent to testing a minimal AABB around */ /* the triangle against the AABB */ /* test in X-direction */ FINDMINMAX(v0[X],v1[X],v2[X],min,max); if(min>boxhalfsize[X] || max<-boxhalfsize[X]) return 0; /* test in Y-direction */ FINDMINMAX(v0[Y],v1[Y],v2[Y],min,max); if(min>boxhalfsize[Y] || max<-boxhalfsize[Y]) return 0; /* test in Z-direction */ FINDMINMAX(v0[Z],v1[Z],v2[Z],min,max); if(min>boxhalfsize[Z] || max<-boxhalfsize[Z]) return 0; /* Bullet 2: */ /* test if the box intersects the plane of the triangle */ /* compute plane equation of triangle: normal*x+d=0 */ normal = e0 ^ e1; if(!planeBoxOverlap(normal,v0,boxhalfsize)) return 0; return 1; /* box and triangle overlaps */ }
int IsTriangleIntersectBox(float boxcenter[3], float boxhalf[3], float triverts[3][3]) { /* use separating axis theorem to test overlap between triangle and box */ /* need to test for overlap in these directions: */ /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ /* we do not even need to test these) */ /* 2) normal of the triangle */ /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ /* this gives 3x3=9 more tests */ float v0[3],v1[3],v2[3]; float min,max,d,p0,p1,p2,rad,fex,fey,fez; float normal[3],e0[3],e1[3],e2[3]; /* 1) first test overlap in the {x,y,z}-directions */ /* find min, max of the triangle each direction, and test for overlap in */ /* that direction -- this is equivalent to testing a minimal AABB around */ /* the triangle against the AABB */ /* test in X */ v0[X]=triverts[0][X]-boxcenter[X]; v1[X]=triverts[1][X]-boxcenter[X]; v2[X]=triverts[2][X]-boxcenter[X]; FINDMINMAX(v0[X],v1[X],v2[X],min,max); if(min>boxhalf[X] || max<-boxhalf[X]) return 0; /* test in Y */ v0[Y]=triverts[0][Y]-boxcenter[Y]; v1[Y]=triverts[1][Y]-boxcenter[Y]; v2[Y]=triverts[2][Y]-boxcenter[Y]; FINDMINMAX(v0[Y],v1[Y],v2[Y],min,max); if(min>boxhalf[Y] || max<-boxhalf[Y]) return 0; /* test in Z */ v0[Z]=triverts[0][Z]-boxcenter[Z]; v1[Z]=triverts[1][Z]-boxcenter[Z]; v2[Z]=triverts[2][Z]-boxcenter[Z]; FINDMINMAX(v0[Z],v1[Z],v2[Z],min,max); if(min>boxhalf[Z] || max<-boxhalf[Z]) return 0; /* 2) */ /* test if the box intersects the plane of the triangle */ /* compute plane equation of triangle: normal*x+d=0 */ SUB(e0,v1,v0); /* tri edge 0 */ SUB(e1,v2,v1); /* tri edge 1 */ CROSS(normal,e0,e1); d=-DOT(normal,v0); /* plane eq: normal.x+d=0 */ if(!planeBoxOverlap(normal,d,boxhalf)) return 0; /* compute the last triangle edge */ SUB(e2,v0,v2); /* 3) */ fex = fabsf(e0[X]); fey = fabsf(e0[Y]); fez = fabsf(e0[Z]); AXISTEST_X01(e0[Z], e0[Y], fez, fey); AXISTEST_Y02(e0[Z], e0[X], fez, fex); AXISTEST_Z12(e0[Y], e0[X], fey, fex); fex = fabsf(e1[X]); fey = fabsf(e1[Y]); fez = fabsf(e1[Z]); AXISTEST_X01(e1[Z], e1[Y], fez, fey); AXISTEST_Y02(e1[Z], e1[X], fez, fex); AXISTEST_Z0(e1[Y], e1[X], fey, fex); fex = fabsf(e2[X]); fey = fabsf(e2[Y]); fez = fabsf(e2[Z]); AXISTEST_X2(e2[Z], e2[Y], fez, fey); AXISTEST_Y1(e2[Z], e2[X], fez, fex); AXISTEST_Z12(e2[Y], e2[X], fey, fex); return 1; }
int IntersectionTests::triBoxOverlap(float boxhalfsize[3],float v0[3], float v1[3],float v2[3]) { /* use separating axis theorem to test overlap between triangle and box */ /* need to test for overlap in these directions: */ /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ /* we do not even need to test these) */ /* 2) normal of the triangle */ /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ /* this gives 3x3=9 more tests */ //double v0[3],v1[3],v2[3]; // double axis[3]; float min,max,d,p0,p1,p2,rad,fex,fey,fez; float normal[3],e0[3],e1[3],e2[3]; /* This is the fastest branch on Sun */ /* move everything so that the boxcenter is in (0,0,0) */ // SUB(v0,trivertsA,boxcenter); // SUB(v1,trivertsB,boxcenter); // SUB(v2,trivertsC,boxcenter); /* compute triangle edges */ //e0[0] = v1[0] - v0[0]; e0[1] = v1[1] - v0[1]; e0[2] = v1[2] - v0[2]; //e1[0] = v2[0] - v1[0]; e1[1] = v2[1] - v1[1]; e1[2] = v2[2] - v1[2]; //e2[0] = v0[0] - v2[0]; e2[1] = v0[1] - v2[1]; e2[2] = v0[2] - v2[2]; SUB(e0,v1,v0); /* tri edge 0 */ SUB(e1,v2,v1); /* tri edge 1 */ SUB(e2,v0,v2); /* tri edge 2 */ /* Bullet 3: */ /* test the 9 tests first (this was faster) */ fex = e0[X];//fabs(e0[X]); fey = e0[Y];//fabs(e0[Y]); fez = e0[Z];//fabs(e0[Z]); if(e0[X] < 0) fex = -e0[X]; if(e0[Y] < 0) fey = -e0[Y]; if(e0[Z] < 0) fez = -e0[Z]; AXISTEST_X01(e0[Z], e0[Y], fez, fey); AXISTEST_Y02(e0[Z], e0[X], fez, fex); AXISTEST_Z12(e0[Y], e0[X], fey, fex); fex = e1[X];//fabs(e1[X]); fey = e1[Y];//fabs(e1[Y]); fez = e1[Z];//fabs(e1[Z]); if(e1[X] < 0) fex = -e1[X]; if(e1[Y] < 0) fey = -e1[Y]; if(e1[Z] < 0) fez = -e1[Z]; AXISTEST_X01(e1[Z], e1[Y], fez, fey); AXISTEST_Y02(e1[Z], e1[X], fez, fex); AXISTEST_Z0(e1[Y], e1[X], fey, fex); fex = e2[X];//fabs(e2[X]); fey = e2[Y];//fabs(e2[Y]); fez = e2[Z];//fabs(e2[Z]); if(e2[X] < 0) fex = -e2[X]; if(e2[Y] < 0) fey = -e2[Y]; if(e2[Z] < 0) fez = -e2[Z]; AXISTEST_X2(e2[Z], e2[Y], fez, fey); AXISTEST_Y1(e2[Z], e2[X], fez, fex); AXISTEST_Z12(e2[Y], e2[X], fey, fex); /* Bullet 1: */ /* first test overlap in the {x,y,z}-directions */ /* find min, max of the triangle each direction, and test for overlap in */ /* that direction -- this is equivalent to testing a minimal AABB around */ /* the triangle against the AABB */ /* test in X-direction */ FINDMINMAX(v0[X],v1[X],v2[X],min,max); if(min>boxhalfsize[X] || max<-boxhalfsize[X]) return 0; /* test in Y-direction */ FINDMINMAX(v0[Y],v1[Y],v2[Y],min,max); if(min>boxhalfsize[Y] || max<-boxhalfsize[Y]) return 0; /* test in Z-direction */ FINDMINMAX(v0[Z],v1[Z],v2[Z],min,max); if(min>boxhalfsize[Z] || max<-boxhalfsize[Z]) return 0; /* Bullet 2: */ /* test if the box intersects the plane of the triangle */ /* compute plane equation of triangle: normal*x+d=0 */ CROSS(normal,e0,e1); d=-DOT(normal,v0); /* plane eq: normal.x+d=0 */ if(!planeBoxOverlap(normal,d,boxhalfsize)) return 0; return 1; /* box and triangle overlaps */ }
// Use separating axis theorem to test overlap between triangle and box // need to test for overlap in these directions: // 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle // we do not even need to test these) // 2) normal of the triangle // 3) crossproduct(edge from tri, {x,y,z}-directin) // this gives 3x3=9 more tests bool overlapTriangleBox(Vec3r& boxcenter, Vec3r& boxhalfsize, Vec3r triverts[3]) { Vec3r v0, v1, v2, normal, e0, e1, e2; real min, max, d, p0, p1, p2, rad, fex, fey, fez; // This is the fastest branch on Sun // move everything so that the boxcenter is in (0, 0, 0) v0 = triverts[0] - boxcenter; v1 = triverts[1] - boxcenter; v2 = triverts[2] - boxcenter; // compute triangle edges e0 = v1 - v0; e1 = v2 - v1; e2 = v0 - v2; // Bullet 3: // Do the 9 tests first (this was faster) fex = fabs(e0[X]); fey = fabs(e0[Y]); fez = fabs(e0[Z]); AXISTEST_X01(e0[Z], e0[Y], fez, fey); AXISTEST_Y02(e0[Z], e0[X], fez, fex); AXISTEST_Z12(e0[Y], e0[X], fey, fex); fex = fabs(e1[X]); fey = fabs(e1[Y]); fez = fabs(e1[Z]); AXISTEST_X01(e1[Z], e1[Y], fez, fey); AXISTEST_Y02(e1[Z], e1[X], fez, fex); AXISTEST_Z0(e1[Y], e1[X], fey, fex); fex = fabs(e2[X]); fey = fabs(e2[Y]); fez = fabs(e2[Z]); AXISTEST_X2(e2[Z], e2[Y], fez, fey); AXISTEST_Y1(e2[Z], e2[X], fez, fex); AXISTEST_Z12(e2[Y], e2[X], fey, fex); // Bullet 1: // first test overlap in the {x,y,z}-directions // find min, max of the triangle each direction, and test for overlap in // that direction -- this is equivalent to testing a minimal AABB around // the triangle against the AABB // test in X-direction FINDMINMAX(v0[X], v1[X], v2[X], min, max); if (min > boxhalfsize[X] || max < -boxhalfsize[X]) return false; // test in Y-direction FINDMINMAX(v0[Y], v1[Y], v2[Y], min, max); if (min > boxhalfsize[Y] || max < -boxhalfsize[Y]) return false; // test in Z-direction FINDMINMAX(v0[Z], v1[Z], v2[Z], min, max); if(min > boxhalfsize[Z] || max < -boxhalfsize[Z]) return false; // Bullet 2: // test if the box intersects the plane of the triangle // compute plane equation of triangle: normal * x + d = 0 normal = e0 ^ e1; d = -(normal * v0); // plane eq: normal.x + d = 0 if (!overlapPlaneBox(normal, d, boxhalfsize)) return false; return true; // box and triangle overlaps }