--- a/src/scene.cc Wed Dec 12 19:59:19 2007 +0100
+++ b/src/scene.cc Thu Dec 13 00:08:11 2007 +0100
@@ -329,6 +329,136 @@
#endif
}
+bool Triangle::intersect_bbox(const BBox &bbox) const
+{
+ const Vector3 boxcenter = (bbox.L+bbox.H)*0.5;
+ const Vector3 boxhalfsize = (bbox.H-bbox.L)*0.5;
+ const Vector3 v0 = A->P - boxcenter;
+ const Vector3 v1 = B->P - boxcenter;
+ const Vector3 v2 = C->P - boxcenter;
+ const Vector3 e0 = v1-v0;
+ const Vector3 e1 = v2-v1;
+ const Vector3 e2 = v0-v2;
+
+ Float fex = fabsf(e0.x);
+ Float fey = fabsf(e0.y);
+ Float fez = fabsf(e0.z);
+
+ Float p0,p1,p2,min,max,rad;
+
+ p0 = e0.z*v0.y - e0.y*v0.z;
+ p2 = e0.z*v2.y - e0.y*v2.z;
+ if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;}
+ rad = fez * boxhalfsize.y + fey * boxhalfsize.z;
+ if(min>rad || max<-rad) return false;
+
+ p0 = -e0.z*v0.x + e0.x*v0.z;
+ p2 = -e0.z*v2.x + e0.x*v2.z;
+ if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;}
+ rad = fez * boxhalfsize.x + fex * boxhalfsize.z;
+ if(min>rad || max<-rad) return false;
+
+ p1 = e0.y*v1.x - e0.x*v1.y;
+ p2 = e0.y*v2.x - e0.x*v2.y;
+ if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;}
+ rad = fey * boxhalfsize.x + fex * boxhalfsize.y;
+ if(min>rad || max<-rad) return false;
+
+ fex = fabsf(e1.x);
+ fey = fabsf(e1.y);
+ fez = fabsf(e1.z);
+
+ p0 = e1.z*v0.y - e1.y*v0.z;
+ p2 = e1.z*v2.y - e1.y*v2.z;
+ if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;}
+ rad = fez * boxhalfsize.y + fey * boxhalfsize.z;
+ if(min>rad || max<-rad) return false;
+
+ p0 = -e1.z*v0.x + e1.x*v0.z;
+ p2 = -e1.z*v2.x + e1.x*v2.z;
+ if(p0<p2) {min=p0; max=p2;} else {min=p2; max=p0;}
+ rad = fez * boxhalfsize.x + fex * boxhalfsize.z;
+ if(min>rad || max<-rad) return false;
+
+ p0 = e1.y*v0.x - e1.x*v0.y;
+ p1 = e1.y*v1.x - e1.x*v1.y;
+ if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;}
+ rad = fey * boxhalfsize.x + fex * boxhalfsize.y;
+ if(min>rad || max<-rad) return false;
+
+ fex = fabsf(e2.x);
+ fey = fabsf(e2.y);
+ fez = fabsf(e2.z);
+
+ p0 = e2.z*v0.y - e2.y*v0.z;
+ p1 = e2.z*v1.y - e2.y*v1.z;
+ if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;}
+ rad = fez * boxhalfsize.y + fey * boxhalfsize.z;
+ if(min>rad || max<-rad) return false;
+
+ p0 = -e2.z*v0.x + e2.x*v0.z;
+ p1 = -e2.z*v1.x + e2.x*v1.z;
+ if(p0<p1) {min=p0; max=p1;} else {min=p1; max=p0;}
+ rad = fez * boxhalfsize.x + fex * boxhalfsize.z;
+ if(min>rad || max<-rad) return false;
+
+ p1 = e2.y*v1.x - e2.x*v1.y;
+ p2 = e2.y*v2.x - e2.x*v2.y;
+ if(p2<p1) {min=p2; max=p1;} else {min=p1; max=p2;}
+ rad = fey * boxhalfsize.x + fex * boxhalfsize.y;
+ if(min>rad || max<-rad) return false;
+
+ /* test overlap in the {x,y,z}-directions */
+ /* test in X-direction */
+ min = v0.x;
+ if (v1.x < min) min = v1.x;
+ if (v2.x < min) min = v2.x;
+ max = v0.x;
+ if (v1.x > max) max = v1.x;
+ if (v2.x > max) max = v2.x;
+ if(min>boxhalfsize.x || max<-boxhalfsize.x) return false;
+
+ /* test in Y-direction */
+ min = v0.y;
+ if (v1.y < min) min = v1.y;
+ if (v2.y < min) min = v2.y;
+ max = v0.y;
+ if (v1.y > max) max = v1.y;
+ if (v2.y > max) max = v2.y;
+ if(min>boxhalfsize.y || max<-boxhalfsize.y) return false;
+
+ /* test in Z-direction */
+ min = v0.z;
+ if (v1.z < min) min = v1.z;
+ if (v2.z < min) min = v2.z;
+ max = v0.z;
+ if (v1.z > max) max = v1.z;
+ if (v2.z > max) max = v2.z;
+ if(min>boxhalfsize.z || max<-boxhalfsize.z) return false;
+
+ /* test if the box intersects the plane of the triangle */
+ Vector3 vmin,vmax;
+ Float v;
+ for(int q=0;q<3;q++)
+ {
+ v=v0[q];
+ if(N[q]>0.0f)
+ {
+ vmin.cell[q]=-boxhalfsize[q] - v;
+ vmax.cell[q]= boxhalfsize[q] - v;
+ }
+ else
+ {
+ vmin.cell[q]= boxhalfsize[q] - v;
+ vmax.cell[q]=-boxhalfsize[q] - v;
+ }
+ }
+ if(dot(N,vmin)>0.0f) return false;
+ if(dot(N,vmax)>=0.0f) return true;
+
+ return false;
+}
+
BBox Triangle::get_bbox() const
{
BBox bbox = BBox();