Revision 39b13612ebd645a65eda854771b517371f2f858a authored by ennetws on 13 March 2015, 18:17:18 UTC, committed by ennetws on 13 March 2015, 18:17:18 UTC
1 parent c702819
BoundingBox.cpp
#include "BoundingBox.h"

BoundingBox::BoundingBox()
{
this->center = Vector3d(0,0,0);

this->xExtent = 0;
this->yExtent = 0;
this->zExtent = 0;
}

BoundingBox::BoundingBox( const Vector3d& c, double x, double y, double z )
{
this->center = c;

this->xExtent = x;
this->yExtent = y;
this->zExtent = z;

Vector3d corner(x/2, y/2, z/2);

vmin = center - corner;
vmax = center + corner;
}

BoundingBox& BoundingBox::operator=( const BoundingBox& other )
{
this->center = other.center;

this->xExtent = other.xExtent;
this->yExtent = other.yExtent;
this->zExtent = other.zExtent;

this->vmax = other.vmax;
this->vmin = other.vmin;

return *this;
}

/*void BoundingBox::computeFromTris( const StdVector<BaseTriangle*>& tris )
{
vmin = Vector3d(DBL_MAX, DBL_MAX, DBL_MAX);
vmax = Vector3d(-DBL_MAX, -DBL_MAX, -DBL_MAX);

double minx = 0, miny = 0, minz = 0;
double maxx = 0, maxy = 0, maxz = 0;

minx = maxx = tris[0]->vec(0).x();
miny = maxy = tris[0]->vec(0).y();
minz = maxz = tris[0]->vec(0).z();

for (int i = 0; i < (int)tris.size(); i++)
{
for(int v = 0; v < 3; v++)
{
Vector3d vec = tris[i]->vec(v);

if (vec.x() < minx) minx = vec.x();
if (vec.x() > maxx) maxx = vec.x();
if (vec.y() < miny) miny = vec.y();
if (vec.y() > maxy) maxy = vec.y();
if (vec.z() < minz) minz = vec.z();
if (vec.z() > maxz) maxz = vec.z();
}
}

vmax = Vector3d(maxx, maxy, maxz);
vmin = Vector3d(minx, miny, minz);

this->center = (vmin + vmax) / 2.0;

this->xExtent = abs(vmax.x() - center.x());
this->yExtent = abs(vmax.y() - center.y());
this->zExtent = abs(vmax.z() - center.z());
}*/

/*bool BoundingBox::intersects( const Ray& ray ) const
{
double rhs;
double fWdU[3];
double fAWdU[3];
double fDdU[3];
double fAWxDdU[3];

Vector3d UNIT_X(1.0, 0.0, 0.0);
Vector3d UNIT_Y(0.0, 1.0, 0.0);
Vector3d UNIT_Z(0.0, 0.0, 1.0);

Vector3d diff = ray.origin - center;
Vector3d wCrossD = cross(ray.direction , diff);

fWdU[0] = dot(ray.direction , UNIT_X);
fAWdU[0] = abs(fWdU[0]);
fDdU[0] = dot(diff , UNIT_X);
if (fADdU[0] > xExtent && fDdU[0] * fWdU[0] >= 0.0)		return false;

fWdU[1] = dot(ray.direction , UNIT_Y);
fAWdU[1] = abs(fWdU[1]);
fDdU[1] = dot(diff , UNIT_Y);
if (fADdU[1] > yExtent && fDdU[1] * fWdU[1] >= 0.0)		return false;

fWdU[2] = dot(ray.direction , UNIT_Z);
fAWdU[2] = abs(fWdU[2]);
fDdU[2] = dot(diff , UNIT_Z);
if (fADdU[2] > zExtent && fDdU[2] * fWdU[2] >= 0.0)		return false;

fAWxDdU[0] = abs(dot(wCrossD , UNIT_X));
rhs = yExtent , fAWdU[2] + zExtent * fAWdU[1];
if (fAWxDdU[0] > rhs)		return false;

fAWxDdU[1] = abs(dot(wCrossD , UNIT_Y));
rhs = xExtent * fAWdU[2] + zExtent * fAWdU[0];
if (fAWxDdU[1] > rhs)		return false;

fAWxDdU[2] = abs(dot(wCrossD , UNIT_Z));
rhs = xExtent * fAWdU[1] + yExtent * fAWdU[0];
if (fAWxDdU[2] > rhs)		return false;

return true;
}*/

BoundingBox::BoundingBox( const Vector3d& fromMin, const Vector3d& toMax )
{
vmin = fromMin;
vmax = toMax;

this->center = (vmin + vmax) / 2.0;

this->xExtent = abs(vmax.x() - center.x());
this->yExtent = abs(vmax.y() - center.y());
this->zExtent = abs(vmax.z() - center.z());
}

std::vector<Vector3d> BoundingBox::getCorners()
{
std::vector<Vector3d> corners;

Vector3d x = (Vector3d(1,0,0) * xExtent);
Vector3d y = (Vector3d(0,1,0) * yExtent);
Vector3d z = (Vector3d(0,0,1) * zExtent);

Vector3d c = center + x + y + z;

corners.push_back(c);
corners.push_back(c - (x*2));
corners.push_back(c - (y*2));
corners.push_back(c - (x*2) - (y*2));

corners.push_back(corners[0] - (z*2));
corners.push_back(corners[1] - (z*2));
corners.push_back(corners[2] - (z*2));
corners.push_back(corners[3] - (z*2));

return corners;
}

/* AABB-triangle overlap test code                      */
/* by Tomas Akenine-MÃ¶ller                              */
bool BoundingBox::containsTriangle( const Vector3d& tv0, const Vector3d& tv1, const Vector3d& tv2 ) const
{
Vector3d boxcenter(center);
Vector3d 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 */
Vector3d v0,v1,v2;
Vector3d 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 = cross(e0, e1);

if(!planeBoxOverlap(normal,v0,boxhalfsize)) return 0;
return 1;   /* box and triangle overlaps */
}

bool BoundingBox::intersectsBoundingBox( const BoundingBox& bb ) const
{
if (center.x() + xExtent < bb.center.x() - bb.xExtent || center.x() - xExtent > bb.center.x() + bb.xExtent)
return false;
else if (center.y() + yExtent < bb.center.y() - bb.yExtent || center.y() - yExtent > bb.center.y() + bb.yExtent)
return false;
else if (center.z() + zExtent < bb.center.z() - bb.zExtent || center.z() - zExtent > bb.center.z() + bb.zExtent)
return false;
else
return true;
}

bool BoundingBox::intersectsSphere( const Vector3d& sphere_center, double radius )
{
if (abs(center.x() - sphere_center.x()) < radius + xExtent
&& abs(center.y() - sphere_center.y()) < radius + yExtent
&& abs(center.z() - sphere_center.z()) < radius + zExtent)
return true;

return false;
}

bool BoundingBox::contains( const Vector3d& point ) const
{
return abs(center.x() - point.x()) < xExtent
&& abs(center.y() - point.y()) < yExtent
&& abs(center.z() - point.z()) < zExtent;
}

Vector3d BoundingBox::Center()
{
return center;
}

void BoundingBox::Offset( double s )
{
Offset( Vector3d(s,s,s));
}

void BoundingBox::Offset( Vector3d delta )
{
*this = BoundingBox(vmin - delta, vmax + delta);
}

double BoundingBox::Diag()
{
return (vmin - vmax).norm();
}

Computing file changes ...