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
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;
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
00070 lonorm[0] = 0;
00071 lo = 1;
00072 } else {
00073
00074 lonorm[1] = 0;
00075 lo = 0;
00076 }
00077
00078 if (tymax < txmax) {
00079 tmax = tymax;
00080
00081
00082 hinorm[0] = 0;
00083 hi = 1;
00084 } else {
00085
00086 hinorm[1] = 0;
00087 hi = 0;
00088 }
00089
00090
00091 if ( (tmin > tzmax) || (tzmin > tmax) )
00092 return;
00093
00094 if (tzmin > tmin) {
00095 tmin = tzmin;
00096
00097
00098 lonorm[lo] = 0;
00099 } else {
00100
00101 lonorm[2] = 0;
00102 }
00103
00104 if (tzmax < tmax) {
00105
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
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