src/scene.cc
branchpyrit
changeset 36 b490093b0ac3
parent 34 28f6e8b9d5d1
child 38 5d043eeb09d9
--- 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();