diff -r 907a634e5c02 -r ce6abe0aeeae src/scene.cc --- a/src/scene.cc Sun Apr 27 14:19:37 2008 +0200 +++ b/src/scene.cc Sun Apr 27 19:56:23 2008 +0200 @@ -107,3 +107,45 @@ b = tfar; return true; } + +// rewrite of BBox::intersect for ray packets +__m128 BBox::intersect_packet(const RayPacket &rays, __m128 &a, __m128 &b) +{ + register __m128 tnear = mZero; + register __m128 tfar = mInf; + register __m128 t1, t2; + register __m128 mask = mAllSet; + + for (int i = 0; i < 3; i++) + { + const __m128 mL = _mm_set_ps1(L[i]); + const __m128 mH = _mm_set_ps1(H[i]); + mask = _mm_and_ps(mask, + _mm_or_ps( + _mm_or_ps(_mm_cmplt_ps(rays.dir.ma[i], mMEps), _mm_cmpgt_ps(rays.dir.ma[i], mEps)), + _mm_and_ps(_mm_cmpge_ps(rays.o.ma[i], mL), _mm_cmple_ps(rays.o.ma[i], mH)) + )); + if (!_mm_movemask_ps(mask)) + return mask; + + /* compute the intersection distance of the planes */ + t1 = _mm_div_ps(_mm_sub_ps(mL, rays.o.ma[i]), rays.dir.ma[i]); + t2 = _mm_div_ps(_mm_sub_ps(mH, rays.o.ma[i]), rays.dir.ma[i]); + + __m128 t = _mm_min_ps(t1, t2); + t2 = _mm_max_ps(t1, t2); + t1 = t; + + tnear = _mm_max_ps(tnear, t1); /* want largest Tnear */ + tfar = _mm_min_ps(tfar, t2); /* want smallest Tfar */ + + mask = _mm_and_ps(mask, + _mm_and_ps(_mm_cmple_ps(tnear, tfar), _mm_cmpge_ps(tfar, mZero))); + if (!_mm_movemask_ps(mask)) + return mask; + } + + a = tnear; + b = tfar; + return mask; +}