Box.cc

Go to the documentation of this file.
00001 
00005 #include "BoundingBox.h"
00006 #include "Box.h"
00007 #include "HitRecord.h"
00008 #include "Math.h"
00009 #include "Ray.h"
00010 #include "Point.h"
00011 #include <iostream>
00012 #include <stdlib.h>
00013 #include <stdio.h>
00014 using namespace std;
00015 
00016 
00017 Box::Box(Material* material, const Point& lo, const Point& hi)
00018     : Primitive(material)
00019 {
00020     bounds[0] = lo;
00021     bounds[1] = hi;
00022 }
00023 
00024 Box::~Box()
00025 {
00026 }
00027 
00032 void Box::intersect(HitRecord& hit, const RenderContext& context, const Ray& ray) const
00033 {
00034     // Algorithm from Williams et. al.  http://www.cs.utah.edu/~awilliam/box/
00035     float tmin, tmax, txmin, txmax, tymin, tymax, tzmin, tzmax;
00036     float lonorm[3] = { -1, -1, -1 };
00037     float hinorm[3] = {  1,  1,  1 };
00038     int lo, hi;
00039 
00040 
00041     txmin = tmin = (bounds[  ray.is_neg[0]].x() - ray.origin().x()) * ray.inv_direction.x(); 
00042     txmax = tmax = (bounds[1-ray.is_neg[0]].x() - ray.origin().x()) * ray.inv_direction.x(); 
00043     tymin =(bounds[  ray.is_neg[1]].y() - ray.origin().y()) * ray.inv_direction.y(); 
00044     tymax =(bounds[1-ray.is_neg[1]].y() - ray.origin().y()) * ray.inv_direction.y(); 
00045     tzmin = (bounds[  ray.is_neg[2]].z() - ray.origin().z()) * ray.inv_direction.z(); 
00046     tzmax = (bounds[1-ray.is_neg[2]].z() - ray.origin().z()) * ray.inv_direction.z(); 
00047 
00048 
00049     if ( (txmin > tymax) || (tymin > txmax) ) 
00050         return; //  FALSE 
00051 #if 0
00052     Point d = ray.origin() + ray.direction() * 7;
00053     fprintf(stderr, "%g %g %g  -> %g %g %g ( %g %g %g )\n",
00054             ray.origin().x(), ray.origin().y(), ray.origin().z(),
00055             ray.direction().x(), ray.direction().y(), ray.direction().z(),
00056             d.x(), d.y(), d.z() );
00057 
00058     fprintf(stderr, "%g %g %g\n", bounds[0].x(), bounds[0].y(), bounds[0].z());
00059     fprintf(stderr, "%g %g %g\n", bounds[1].x(), bounds[1].y(), bounds[1].z());
00060 
00061 
00062     fprintf(stderr, "X %g %g, Y %g %g Z %g %g\n", txmin, txmax, tymin, tymax, tzmin, tzmax);
00063 #endif
00064 
00065 
00066     if (tymin > txmin) {
00067         tmin = tymin; 
00068 
00069         // it's not txmin
00070         lonorm[0] = 0;
00071         lo = 1;
00072     } else {
00073         // it's not tymin
00074         lonorm[1] = 0;
00075         lo = 0;
00076     }
00077 
00078     if (tymax < txmax) {
00079         tmax = tymax; 
00080 
00081         // it's not txmax
00082         hinorm[0] = 0;
00083         hi = 1;
00084     } else {
00085         // it's not tymax
00086         hinorm[1] = 0;
00087         hi = 0;
00088     }
00089 
00090 
00091     if ( (tmin > tzmax) || (tzmin > tmax) ) 
00092         return; // FALSE 
00093 
00094     if (tzmin > tmin) {
00095         tmin = tzmin; 
00096 
00097         // we're using tzmin
00098         lonorm[lo] = 0;
00099     } else {
00100         // we're NOT using tzmin
00101         lonorm[2] = 0;
00102     }
00103 
00104     if (tzmax < tmax) {
00105         // we're using tzmax
00106         tmax = tzmax;
00107         
00108         hinorm[hi] = 0;
00109     } else {
00110         hinorm[2] = 0;
00111     }
00112 
00113     if ( (tmin < HUGE) && (tmax > 0) ) {
00114         float *p = (float *)&hit.scratchdata[0];
00115 
00116         // hit
00117         if (tmin >= 0.0) {
00118             Point pt = ray.origin() + ray.direction() * tmin;
00119 
00120             if ( hit.hit(tmin, this, matl) ) {
00121                 p[0] = lonorm[0];
00122                 p[1] = lonorm[1];
00123                 p[2] = lonorm[2];
00124             }
00125         } else {
00126             Point pt = ray.origin() + ray.direction() * tmax;
00127             if (hit.hit(tmax, this, matl)) {
00128                 p[0] = hinorm[0];
00129                 p[1] = hinorm[1];
00130                 p[2] = hinorm[2];
00131             }
00132         }
00133     }
00134     ;
00135 }
00136 
00137 void Box::normal(Vector& normal, const RenderContext& ctx,
00138                    const Point& pt, const Ray& ray, const HitRecord& hit) const
00139 {
00140     float *p = (float *)&hit.scratchdata[0];
00141 
00142     normal = Vector(p[0], p[1], p[2]);
00143 
00144 }
00145 
00146 void Box::getBounds(BoundingBox& bbox) const
00147 {
00148   cerr <<  "Box::getBounds() called!" << endl;
00149   bbox.extend(bounds[0]);
00150   bbox.extend(bounds[1]);
00151   exit( 1 );
00152 }
00153 

Generated on Tue Jan 29 21:34:53 2008 for specter by  doxygen 1.4.6