52 } |
52 } |
53 } |
53 } |
54 return false; |
54 return false; |
55 } |
55 } |
56 |
56 |
|
57 __m128 Sphere::intersect_packet(const RayPacket &rays, __m128 &dists) |
|
58 { |
|
59 VectorPacket V = rays.o - VectorPacket(center); |
|
60 register __m128 d = _mm_sub_ps(mZero, dot(V, rays.dir)); |
|
61 register __m128 Det = _mm_sub_ps(_mm_mul_ps(d, d), |
|
62 _mm_sub_ps(dot(V,V), _mm_set_ps1(sqr_radius))); |
|
63 register __m128 t1, t2, mask; |
|
64 |
|
65 mask = _mm_cmpgt_ps(Det, mZero); |
|
66 if (!_mm_movemask_ps(mask)) |
|
67 return mask; |
|
68 |
|
69 Det = _mm_sqrt_ps(Det); |
|
70 t1 = _mm_sub_ps(d, Det); |
|
71 t2 = _mm_add_ps(d, Det); |
|
72 |
|
73 mask = _mm_and_ps(mask, _mm_cmpgt_ps(t2, mZero)); |
|
74 |
|
75 const __m128 cond1 = _mm_and_ps(_mm_cmpgt_ps(t1, mZero), _mm_cmplt_ps(t1, dists)); |
|
76 const __m128 cond2 = _mm_and_ps(_mm_cmple_ps(t1, mZero), _mm_cmplt_ps(t2, dists)); |
|
77 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 dists = _mm_or_ps(_mm_and_ps(mask, newdists), _mm_andnot_ps(mask, dists)); |
|
80 return mask; |
|
81 } |
|
82 |
57 /* if there should be CSG sometimes, this may be needed... */ |
83 /* if there should be CSG sometimes, this may be needed... */ |
58 bool Sphere::intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const |
84 bool Sphere::intersect_all(const Ray &ray, Float dist, vector<Float> &allts) const |
59 { |
85 { |
60 //allts = new vector<Float>(); |
86 //allts = new vector<Float>(); |
61 |
87 |
147 return true; |
173 return true; |
148 } |
174 } |
149 return false; |
175 return false; |
150 } |
176 } |
151 |
177 |
|
178 __m128 Box::intersect_packet(const RayPacket &rays, __m128 &dists) |
|
179 { |
|
180 register __m128 tnear = mZero; |
|
181 register __m128 tfar = mInf; |
|
182 register __m128 t1, t2; |
|
183 register __m128 mask = mAllSet; |
|
184 |
|
185 for (int i = 0; i < 3; i++) |
|
186 { |
|
187 const __m128 mL = _mm_set_ps1(L[i]); |
|
188 const __m128 mH = _mm_set_ps1(H[i]); |
|
189 mask = _mm_and_ps(mask, |
|
190 _mm_or_ps( |
|
191 _mm_or_ps(_mm_cmplt_ps(rays.dir.ma[i], mMEps), _mm_cmpgt_ps(rays.dir.ma[i], mEps)), |
|
192 _mm_and_ps(_mm_cmpge_ps(rays.o.ma[i], mL), _mm_cmple_ps(rays.o.ma[i], mH)) |
|
193 )); |
|
194 if (!_mm_movemask_ps(mask)) |
|
195 return mask; |
|
196 |
|
197 /* compute the intersection distance of the planes */ |
|
198 t1 = _mm_div_ps(_mm_sub_ps(mL, rays.o.ma[i]), rays.dir.ma[i]); |
|
199 t2 = _mm_div_ps(_mm_sub_ps(mH, rays.o.ma[i]), rays.dir.ma[i]); |
|
200 |
|
201 __m128 t = _mm_min_ps(t1, t2); |
|
202 t2 = _mm_max_ps(t1, t2); |
|
203 t1 = t; |
|
204 |
|
205 tnear = _mm_max_ps(tnear, t1); /* want largest Tnear */ |
|
206 tfar = _mm_min_ps(tfar, t2); /* want smallest Tfar */ |
|
207 |
|
208 mask = _mm_and_ps(mask, |
|
209 _mm_and_ps(_mm_cmple_ps(tnear, tfar), _mm_cmpge_ps(tfar, mZero))); |
|
210 if (!_mm_movemask_ps(mask)) |
|
211 return mask; |
|
212 } |
|
213 |
|
214 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)); |
|
216 return mask; |
|
217 } |
|
218 |
152 bool Box::intersect_bbox(const BBox &bbox) const |
219 bool Box::intersect_bbox(const BBox &bbox) const |
153 { |
220 { |
154 return ( |
221 return ( |
155 H.x > bbox.L.x && L.x < bbox.H.x && |
222 H.x > bbox.L.x && L.x < bbox.H.x && |
156 H.y > bbox.L.y && L.y < bbox.H.y && |
223 H.y > bbox.L.y && L.y < bbox.H.y && |
387 mask = _mm_and_ps(mask, _mm_and_ps(_mm_cmpge_ps(gamma, mZero), |
454 mask = _mm_and_ps(mask, _mm_and_ps(_mm_cmpge_ps(gamma, mZero), |
388 _mm_cmple_ps(_mm_add_ps(beta, gamma), mOne))); |
455 _mm_cmple_ps(_mm_add_ps(beta, gamma), mOne))); |
389 if (!_mm_movemask_ps(mask)) |
456 if (!_mm_movemask_ps(mask)) |
390 return mask; |
457 return mask; |
391 |
458 |
392 for (int i = 0; i < 4; i++) |
459 dists = _mm_or_ps(_mm_andnot_ps(mask, dists), _mm_and_ps(mask, t)); |
393 if ((_mm_movemask_ps(mask)>>i)&1) |
|
394 ((float*)&dists)[i] = ((float*)&t)[i]; |
|
395 return mask; |
460 return mask; |
396 } |
461 } |
397 #endif |
462 #endif |
398 |
463 |
399 bool Triangle::intersect_bbox(const BBox &bbox) const |
464 bool Triangle::intersect_bbox(const BBox &bbox) const |