57 } |
57 } |
58 |
58 |
59 /* http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm */ |
59 /* http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter3.htm */ |
60 bool BBox::intersect(const Ray &ray, Float &a, Float &b) |
60 bool BBox::intersect(const Ray &ray, Float &a, Float &b) |
61 { |
61 { |
62 Float tnear = -FLT_MAX; |
62 register Float tnear = -Inf; |
63 Float tfar = FLT_MAX; |
63 register Float tfar = Inf; |
64 Float t1, t2; |
64 register Float t1, t2; |
65 |
65 |
66 for (int i = 0; i < 3; i++) |
66 for (int i = 0; i < 3; i++) |
67 { |
67 { |
68 if (ray.dir.cell[i] == 0) { |
68 if (ray.dir[i] == 0) { |
69 /* ray is parallel to these planes */ |
69 /* ray is parallel to these planes */ |
70 if (ray.o.cell[i] < L.cell[i] || ray.o.cell[i] > H.cell[i]) |
70 if (ray.o[i] < L[i] || ray.o[i] > H[i]) |
71 return false; |
71 return false; |
72 } else |
72 } else |
73 { |
73 { |
74 /* compute the intersection distance of the planes */ |
74 /* compute the intersection distance of the planes */ |
75 t1 = (L.cell[i] - ray.o.cell[i]) / ray.dir.cell[i]; |
75 t1 = (L[i] - ray.o[i]) / ray.dir[i]; |
76 t2 = (H.cell[i] - ray.o.cell[i]) / ray.dir.cell[i]; |
76 t2 = (H[i] - ray.o[i]) / ray.dir[i]; |
77 |
77 |
78 if (t1 > t2) |
78 if (t1 > t2) |
79 swap(t1, t2); |
79 swap(t1, t2); |
80 |
80 |
81 if (t1 > tnear) |
81 if (t1 > tnear) |
82 tnear = t1; /* want largest Tnear */ |
82 tnear = t1; /* want largest Tnear */ |
83 if (t2 < tfar) |
83 if (t2 < tfar) |
84 tfar = t2; /* want smallest Tfar */ |
84 tfar = t2; /* want smallest Tfar */ |
85 if (tnear > tfar) |
85 if (tnear > tfar || tfar < 0) |
86 return false; /* box missed */ |
86 return false; /* box missed; box is behind ray */ |
87 if (tfar < 0) |
|
88 return false; /* box is behind ray */ |
|
89 } |
87 } |
90 } |
88 } |
91 |
89 |
92 a = tnear; |
90 a = tnear; |
93 b = tfar; |
91 b = tfar; |
165 return BBox(center - radius, center + radius); |
164 return BBox(center - radius, center + radius); |
166 } |
165 } |
167 |
166 |
168 bool Box::intersect(const Ray &ray, Float &dist) const |
167 bool Box::intersect(const Ray &ray, Float &dist) const |
169 { |
168 { |
170 Float a,b; |
169 register Float tnear = -Inf; |
171 if (get_bbox().intersect(ray, a, b) && a < dist) |
170 register Float tfar = Inf; |
172 { |
171 register Float t1, t2; |
173 dist = a; |
172 |
|
173 for (int i = 0; i < 3; i++) |
|
174 { |
|
175 if (ray.dir[i] == 0) { |
|
176 /* ray is parallel to these planes */ |
|
177 if (ray.o[i] < L[i] || ray.o[i] > H[i]) |
|
178 return false; |
|
179 } |
|
180 else |
|
181 { |
|
182 /* compute the intersection distance of the planes */ |
|
183 t1 = (L[i] - ray.o[i]) / ray.dir[i]; |
|
184 t2 = (H[i] - ray.o[i]) / ray.dir[i]; |
|
185 |
|
186 if (t1 > t2) |
|
187 swap(t1, t2); |
|
188 |
|
189 if (t1 > tnear) |
|
190 tnear = t1; /* want largest Tnear */ |
|
191 if (t2 < tfar) |
|
192 tfar = t2; /* want smallest Tfar */ |
|
193 if (tnear > tfar || tfar < 0) |
|
194 return false; /* box missed; box is behind ray */ |
|
195 } |
|
196 } |
|
197 |
|
198 if (tnear < dist) |
|
199 { |
|
200 dist = tnear; |
174 return true; |
201 return true; |
175 } |
202 } |
176 else |
203 return false; |
177 return false; |
|
178 } |
204 } |
179 |
205 |
180 bool Box::intersect_bbox(const BBox &bbox) const |
206 bool Box::intersect_bbox(const BBox &bbox) const |
181 { |
207 { |
182 return ( |
208 return ( |
185 H.z > bbox.L.z && L.z < bbox.H.z); |
211 H.z > bbox.L.z && L.z < bbox.H.z); |
186 } |
212 } |
187 |
213 |
188 const Vector3 Box::normal(const Vector3 &P) const |
214 const Vector3 Box::normal(const Vector3 &P) const |
189 { |
215 { |
190 Vector3 N; |
216 register Vector3 l = P - L; |
191 for (int i = 0; i < 3; i++) |
217 register Vector3 h = H - P; |
192 { |
218 |
193 if (P.cell[i] >= L.cell[i]-Eps && P.cell[i] <= L.cell[i]+Eps) |
219 if (l.x < h.x) |
194 //if (P.cell[i] == L.cell[i]) |
220 h.x = -1; |
195 { |
221 else |
196 N.cell[i] = -1.0; |
222 { |
197 break; |
223 l.x = h.x; |
198 } |
224 h.x = +1; |
199 if (P.cell[i] >= H.cell[i]-Eps && P.cell[i] <= H.cell[i]+Eps) |
225 } |
200 //if (P.cell[i] == H.cell[i]) |
226 |
201 { |
227 if (l.y < h.y) |
202 N.cell[i] = +1.0; |
228 h.y = -1; |
203 break; |
229 else |
204 } |
230 { |
205 } |
231 l.y = h.y; |
206 return N; |
232 h.y = +1; |
|
233 } |
|
234 |
|
235 if (l.z < h.z) |
|
236 h.z = -1; |
|
237 else |
|
238 { |
|
239 l.z = h.z; |
|
240 h.z = +1; |
|
241 } |
|
242 |
|
243 if (l.x > l.y) |
|
244 { |
|
245 h.x = 0; |
|
246 if (l.y > l.z) |
|
247 h.y = 0; |
|
248 else |
|
249 h.z = 0; |
|
250 } |
|
251 else |
|
252 { |
|
253 h.y = 0; |
|
254 if (l.x > l.z) |
|
255 h.x = 0; |
|
256 else |
|
257 h.z = 0; |
|
258 } |
|
259 return h; |
207 } |
260 } |
208 |
261 |
209 #ifdef TRI_PLUCKER |
262 #ifdef TRI_PLUCKER |
210 inline void Plucker(const Vector3 &p, const Vector3 &q, Float* pl) |
263 inline void Plucker(const Vector3 &p, const Vector3 &q, Float* pl) |
211 { |
264 { |