src/scene.cc
branchpyrit
changeset 40 929aad02c5f2
parent 38 5d043eeb09d9
child 42 fbdeb3e04543
--- a/src/scene.cc	Fri Dec 14 16:51:22 2007 +0100
+++ b/src/scene.cc	Mon Dec 17 22:03:50 2007 +0100
@@ -59,21 +59,21 @@
 /* http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm */
 bool BBox::intersect(const Ray &ray, Float &a, Float &b)
 {
-	Float tnear = -FLT_MAX;
-	Float tfar = FLT_MAX;
-	Float t1, t2;
+	register Float tnear = -Inf;
+	register Float tfar = Inf;
+	register Float t1, t2;
 
 	for (int i = 0; i < 3; i++)
 	{
-		if (ray.dir.cell[i] == 0) {
+		if (ray.dir[i] == 0) {
 			/* ray is parallel to these planes */
-			if (ray.o.cell[i] < L.cell[i] || ray.o.cell[i] > H.cell[i])
+			if (ray.o[i] < L[i] || ray.o[i] > H[i])
 				return false;
 		} else
 		{
 			/* compute the intersection distance of the planes */
-			t1 = (L.cell[i] - ray.o.cell[i]) / ray.dir.cell[i];
-			t2 = (H.cell[i] - ray.o.cell[i]) / ray.dir.cell[i];
+			t1 = (L[i] - ray.o[i]) / ray.dir[i];
+			t2 = (H[i] - ray.o[i]) / ray.dir[i];
 
 			if (t1 > t2)
 				swap(t1, t2);
@@ -82,10 +82,8 @@
 				tnear = t1; /* want largest Tnear */
 			if (t2 < tfar)
 				tfar = t2; /* want smallest Tfar */
-			if (tnear > tfar)
-				return false; /* box missed */
-			if (tfar < 0)
-				return false; /* box is behind ray */
+			if (tnear > tfar || tfar < 0)
+				return false; /* box missed; box is behind ray */
 		}
 	}
 
@@ -110,6 +108,7 @@
 	return false;
 }
 
+/* if there should be CSG sometimes, this may be needed... */
 bool Sphere::intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const
 {
 	//allts = new vector<Float>();
@@ -167,14 +166,41 @@
 
 bool Box::intersect(const Ray &ray, Float &dist) const
 {
-	Float a,b;
-	if (get_bbox().intersect(ray, a, b) && a < dist)
+	register Float tnear = -Inf;
+	register Float tfar = Inf;
+	register Float t1, t2;
+
+	for (int i = 0; i < 3; i++)
 	{
-		dist = a;
+		if (ray.dir[i] == 0) {
+			/* ray is parallel to these planes */
+			if (ray.o[i] < L[i] || ray.o[i] > H[i])
+				return false;
+		}
+		else
+		{
+			/* compute the intersection distance of the planes */
+			t1 = (L[i] - ray.o[i]) / ray.dir[i];
+			t2 = (H[i] - ray.o[i]) / ray.dir[i];
+
+			if (t1 > t2)
+				swap(t1, t2);
+
+			if (t1 > tnear)
+				tnear = t1; /* want largest Tnear */
+			if (t2 < tfar)
+				tfar = t2; /* want smallest Tfar */
+			if (tnear > tfar || tfar < 0)
+				return false; /* box missed; box is behind ray */
+		}
+	}
+
+	if (tnear < dist)
+	{
+		dist = tnear;
 		return true;
 	}
-	else
-		return false;
+	return false;
 }
 
 bool Box::intersect_bbox(const BBox &bbox) const
@@ -187,23 +213,50 @@
 
 const Vector3 Box::normal(const Vector3 &P) const
 {
-	Vector3 N;
-	for (int i = 0; i < 3; i++)
+	register Vector3 l = P - L;
+	register Vector3 h = H - P;
+
+	if (l.x < h.x)
+		h.x = -1;
+	else
+	{
+		l.x = h.x;
+		h.x = +1;
+	}
+
+	if (l.y < h.y)
+		h.y = -1;
+	else
 	{
-		if (P.cell[i] >= L.cell[i]-Eps && P.cell[i] <= L.cell[i]+Eps)
-		//if (P.cell[i] == L.cell[i])
-		{
-			N.cell[i] = -1.0;
-			break;
-		}
-		if (P.cell[i] >= H.cell[i]-Eps && P.cell[i] <= H.cell[i]+Eps)
-		//if (P.cell[i] == H.cell[i])
-		{
-			N.cell[i] = +1.0;
-			break;
-		}
+		l.y = h.y;
+		h.y = +1;
+	}
+
+	if (l.z < h.z)
+		h.z = -1;
+	else
+	{
+		l.z = h.z;
+		h.z = +1;
 	}
-	return N;
+
+	if (l.x > l.y)
+	{
+		h.x = 0;
+		if (l.y > l.z)
+			h.y = 0;
+		else
+			h.z = 0;
+	}
+	else
+	{
+		h.y = 0;
+		if (l.x > l.z)
+			h.x = 0;
+		else
+			h.z = 0;
+	}
+	return h;
 }
 
 #ifdef TRI_PLUCKER