예제 #1
0
파일: objects.cpp 프로젝트: spillow/Samples
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;
}
예제 #2
0
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);
}
예제 #4
0
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 */
}
예제 #5
0
  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);
  }
예제 #6
0
/* 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 */
}
예제 #7
0
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 */
}
예제 #9
0
  // 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
  }