27 #include "shapes.h" |
27 #include "shapes.h" |
28 #include "serialize.h" |
28 #include "serialize.h" |
29 |
29 |
30 bool Sphere::intersect(const Ray &ray, Float &dist) const |
30 bool Sphere::intersect(const Ray &ray, Float &dist) const |
31 { |
31 { |
32 Vector3 V = ray.o - center; |
32 Vector V = ray.o - center; |
33 register Float d = -dot(V, ray.dir); |
33 register Float d = -dot(V, ray.dir); |
34 register Float Det = d * d - (dot(V,V) - sqr_radius); |
34 register Float Det = d * d - (dot(V,V) - sqr_radius); |
35 register Float t1,t2; |
35 register Float t1,t2; |
36 if (Det > 0) { |
36 if (Det > 0) { |
37 Det = sqrtf(Det); |
37 Det = sqrtf(Det); |
52 } |
52 } |
53 } |
53 } |
54 return false; |
54 return false; |
55 } |
55 } |
56 |
56 |
|
57 #ifndef NO_SSE |
57 __m128 Sphere::intersect_packet(const RayPacket &rays, __m128 &dists) |
58 __m128 Sphere::intersect_packet(const RayPacket &rays, __m128 &dists) |
58 { |
59 { |
59 VectorPacket V = rays.o - VectorPacket(center); |
60 VectorPacket V = rays.o - VectorPacket(center); |
60 register __m128 d = _mm_sub_ps(mZero, dot(V, rays.dir)); |
61 register __m128 d = _mm_sub_ps(mZero, dot(V, rays.dir)); |
61 register __m128 Det = _mm_sub_ps(_mm_mul_ps(d, d), |
62 register __m128 Det = _mm_sub_ps(_mm_mul_ps(d, d), |
77 const __m128 newdists = _mm_or_ps(_mm_and_ps(cond1, t1), _mm_and_ps(cond2, t2)); |
78 const __m128 newdists = _mm_or_ps(_mm_and_ps(cond1, t1), _mm_and_ps(cond2, t2)); |
78 mask = _mm_and_ps(mask, _mm_or_ps(cond1, cond2)); |
79 mask = _mm_and_ps(mask, _mm_or_ps(cond1, cond2)); |
79 dists = _mm_or_ps(_mm_and_ps(mask, newdists), _mm_andnot_ps(mask, dists)); |
80 dists = _mm_or_ps(_mm_and_ps(mask, newdists), _mm_andnot_ps(mask, dists)); |
80 return mask; |
81 return mask; |
81 } |
82 } |
|
83 #endif |
82 |
84 |
83 /* if there should be CSG sometimes, this may be needed... */ |
85 /* if there should be CSG sometimes, this may be needed... */ |
84 bool Sphere::intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const |
86 bool Sphere::intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const |
85 { |
87 { |
86 //allts = new vector<Float>(); |
88 //allts = new vector<Float>(); |
87 |
89 |
88 Vector3 V = ((Ray)ray).o - center; |
90 Vector V = ((Ray)ray).o - center; |
89 Float Vd = - dot(V, ray.dir); |
91 Float Vd = - dot(V, ray.dir); |
90 Float Det = Vd * Vd - (dot(V,V) - sqr_radius); |
92 Float Det = Vd * Vd - (dot(V,V) - sqr_radius); |
91 |
93 |
92 if (Det > 0) { |
94 if (Det > 0) { |
93 Det = sqrtf(Det); |
95 Det = sqrtf(Det); |
173 return true; |
175 return true; |
174 } |
176 } |
175 return false; |
177 return false; |
176 } |
178 } |
177 |
179 |
|
180 #ifndef NO_SSE |
178 __m128 Box::intersect_packet(const RayPacket &rays, __m128 &dists) |
181 __m128 Box::intersect_packet(const RayPacket &rays, __m128 &dists) |
179 { |
182 { |
180 register __m128 tnear = mZero; |
183 register __m128 tnear = mZero; |
181 register __m128 tfar = mInf; |
184 register __m128 tfar = mInf; |
182 register __m128 t1, t2; |
185 register __m128 t1, t2; |
213 |
216 |
214 mask = _mm_and_ps(mask, _mm_cmplt_ps(tnear, dists)); |
217 mask = _mm_and_ps(mask, _mm_cmplt_ps(tnear, dists)); |
215 dists = _mm_or_ps(_mm_and_ps(mask, tnear), _mm_andnot_ps(mask, dists)); |
218 dists = _mm_or_ps(_mm_and_ps(mask, tnear), _mm_andnot_ps(mask, dists)); |
216 return mask; |
219 return mask; |
217 } |
220 } |
|
221 #endif |
218 |
222 |
219 bool Box::intersect_bbox(const BBox &bbox) const |
223 bool Box::intersect_bbox(const BBox &bbox) const |
220 { |
224 { |
221 return ( |
225 return ( |
222 H.x > bbox.L.x && L.x < bbox.H.x && |
226 H.x > bbox.L.x && L.x < bbox.H.x && |
223 H.y > bbox.L.y && L.y < bbox.H.y && |
227 H.y > bbox.L.y && L.y < bbox.H.y && |
224 H.z > bbox.L.z && L.z < bbox.H.z); |
228 H.z > bbox.L.z && L.z < bbox.H.z); |
225 } |
229 } |
226 |
230 |
227 const Vector3 Box::normal(const Vector3 &P) const |
231 const Vector Box::normal(const Vector &P) const |
228 { |
232 { |
229 register Vector3 l = P - L; |
233 register Vector l = P - L; |
230 register Vector3 h = H - P; |
234 register Vector h = H - P; |
231 |
235 |
232 if (l.x < h.x) |
236 if (l.x < h.x) |
233 h.x = -1; |
237 h.x = -1; |
234 else |
238 else |
235 { |
239 { |
271 } |
275 } |
272 return h; |
276 return h; |
273 } |
277 } |
274 |
278 |
275 #ifdef TRI_PLUCKER |
279 #ifdef TRI_PLUCKER |
276 inline void Plucker(const Vector3 &p, const Vector3 &q, Float* pl) |
280 inline void Plucker(const Vector &p, const Vector &q, Float* pl) |
277 { |
281 { |
278 pl[0] = p.x*q.y - q.x*p.y; |
282 pl[0] = p.x*q.y - q.x*p.y; |
279 pl[1] = p.x*q.z - q.x*p.z; |
283 pl[1] = p.x*q.z - q.x*p.z; |
280 pl[2] = p.x - q.x; |
284 pl[2] = p.x - q.x; |
281 pl[3] = p.y*q.z - q.y*p.z; |
285 pl[3] = p.y*q.z - q.y*p.z; |
292 Triangle::Triangle(Vertex *aA, Vertex *aB, Vertex *aC, Material *amaterial) |
296 Triangle::Triangle(Vertex *aA, Vertex *aB, Vertex *aC, Material *amaterial) |
293 : A(aA), B(aB), C(aC) |
297 : A(aA), B(aB), C(aC) |
294 { |
298 { |
295 material = amaterial; |
299 material = amaterial; |
296 |
300 |
297 const Vector3 c = B->P - A->P; |
301 const Vector c = B->P - A->P; |
298 const Vector3 b = C->P - A->P; |
302 const Vector b = C->P - A->P; |
299 |
303 |
300 N = cross(c, b); |
304 N = cross(c, b); |
301 N.normalize(); |
305 N.normalize(); |
302 |
306 |
303 #ifdef TRI_PLUCKER |
307 #ifdef TRI_PLUCKER |
361 return true; |
365 return true; |
362 #endif |
366 #endif |
363 |
367 |
364 #if defined(TRI_BARI) || defined(TRI_BARI_PRE) |
368 #if defined(TRI_BARI) || defined(TRI_BARI_PRE) |
365 static const int modulo3[5] = {0,1,2,0,1}; |
369 static const int modulo3[5] = {0,1,2,0,1}; |
366 const Vector3 &O = ray.o; |
370 const Vector &O = ray.o; |
367 const Vector3 &D = ray.dir; |
371 const Vector &D = ray.dir; |
368 register const int u = modulo3[k+1]; |
372 register const int u = modulo3[k+1]; |
369 register const int v = modulo3[k+2]; |
373 register const int v = modulo3[k+2]; |
370 #endif |
374 #endif |
371 #ifdef TRI_BARI_PRE |
375 #ifdef TRI_BARI_PRE |
372 const Float t = (nd - O[k] - nu * O[u] - nv * O[v]) / (D[k] + nu * D[u] + nv * D[v]); |
376 const Float t = (nd - O[k] - nu * O[u] - nv * O[v]) / (D[k] + nu * D[u] + nv * D[v]); |
390 #endif |
394 #endif |
391 |
395 |
392 #ifdef TRI_BARI |
396 #ifdef TRI_BARI |
393 // original barycentric coordinates based intesection |
397 // original barycentric coordinates based intesection |
394 // not optimized, just for reference |
398 // not optimized, just for reference |
395 const Vector3 c = B - A; |
399 const Vector c = B - A; |
396 const Vector3 b = C - A; |
400 const Vector b = C - A; |
397 // distance test |
401 // distance test |
398 const Float t = - dot( (O-A), N) / dot(D,N); |
402 const Float t = - dot( (O-A), N) / dot(D,N); |
399 if (t < Eps || t > dist) |
403 if (t < Eps || t > dist) |
400 return false; |
404 return false; |
401 |
405 |
413 dist = t; |
417 dist = t; |
414 return true; |
418 return true; |
415 #endif |
419 #endif |
416 } |
420 } |
417 |
421 |
418 #ifdef TRI_BARI_PRE |
422 #if not defined(NO_SSE) and defined(TRI_BARI_PRE) |
419 __m128 Triangle::intersect_packet(const RayPacket &rays, __m128 &dists) |
423 __m128 Triangle::intersect_packet(const RayPacket &rays, __m128 &dists) |
420 { |
424 { |
421 static const int modulo3[5] = {0,1,2,0,1}; |
425 static const int modulo3[5] = {0,1,2,0,1}; |
422 register const int u = modulo3[k+1]; |
426 register const int u = modulo3[k+1]; |
423 register const int v = modulo3[k+2]; |
427 register const int v = modulo3[k+2]; |
461 } |
465 } |
462 #endif |
466 #endif |
463 |
467 |
464 bool Triangle::intersect_bbox(const BBox &bbox) const |
468 bool Triangle::intersect_bbox(const BBox &bbox) const |
465 { |
469 { |
466 const Vector3 boxcenter = (bbox.L+bbox.H)*0.5; |
470 const Vector boxcenter = (bbox.L+bbox.H)*0.5; |
467 const Vector3 boxhalfsize = (bbox.H-bbox.L)*0.5; |
471 const Vector boxhalfsize = (bbox.H-bbox.L)*0.5; |
468 const Vector3 v0 = A->P - boxcenter; |
472 const Vector v0 = A->P - boxcenter; |
469 const Vector3 v1 = B->P - boxcenter; |
473 const Vector v1 = B->P - boxcenter; |
470 const Vector3 v2 = C->P - boxcenter; |
474 const Vector v2 = C->P - boxcenter; |
471 const Vector3 e0 = v1-v0; |
475 const Vector e0 = v1-v0; |
472 const Vector3 e1 = v2-v1; |
476 const Vector e1 = v2-v1; |
473 const Vector3 e2 = v0-v2; |
477 const Vector e2 = v0-v2; |
474 |
478 |
475 Float fex = fabsf(e0.x); |
479 Float fex = fabsf(e0.x); |
476 Float fey = fabsf(e0.y); |
480 Float fey = fabsf(e0.y); |
477 Float fez = fabsf(e0.z); |
481 Float fez = fabsf(e0.z); |
478 |
482 |