Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1235 - trunk/Model/Groups


Chronological Thread 
  • From: boulos@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1235 - trunk/Model/Groups
  • Date: Sun, 12 Nov 2006 05:45:12 -0700 (MST)

Author: boulos
Date: Sun Nov 12 05:45:11 2006
New Revision: 1235

Modified:
   trunk/Model/Groups/DynBVH.cc
Log:
Rewriting firstIntersect in MANTA_SSE begin/end
style.  Ensuring that box test has cmple instead
of cmplt


Modified: trunk/Model/Groups/DynBVH.cc
==============================================================================
--- trunk/Model/Groups/DynBVH.cc        (original)
+++ trunk/Model/Groups/DynBVH.cc        Sun Nov 12 05:45:11 2006
@@ -15,7 +15,6 @@
     rays.computeInverseDirections();
     rays.computeSigns();
 
-
     // compute IntervalArithmetic Data
     IAData ia_data;
     for (int axis = 0; axis < 3; axis++ )
@@ -36,17 +35,7 @@
             const Real new_rcp     = rays.getInverseDirection(ray, axis);
             const Real new_org     = rays.getOrigin(ray,axis);
             const Real new_org_rcp = new_org * new_rcp;
-#define USE_STDMINMAX 0
-#if USE_STDMINMAX
-            ia_data.min_rcp[axis] = std::min(ia_data.min_rcp[axis], new_rcp);
-            ia_data.max_rcp[axis] = std::max(ia_data.max_rcp[axis], new_rcp);
-
-            ia_data.min_org[axis] = std::min(ia_data.min_org[axis], new_org);
-            ia_data.max_org[axis] = std::max(ia_data.max_org[axis], new_org);
 
-            ia_data.min_org_rcp[axis] = std::min(ia_data.min_org_rcp[axis], 
new_org_rcp);
-            ia_data.max_org_rcp[axis] = std::max(ia_data.max_org_rcp[axis], 
new_org_rcp);
-#else
             ia_data.min_rcp[axis] = (ia_data.min_rcp[axis] < new_rcp) ? 
ia_data.min_rcp[axis] : new_rcp;
             ia_data.max_rcp[axis] = (ia_data.max_rcp[axis] < new_rcp) ? 
new_rcp : ia_data.max_rcp[axis];
 
@@ -57,7 +46,7 @@
                 ia_data.min_org_rcp[axis] : new_org_rcp;
             ia_data.max_org_rcp[axis] = (ia_data.max_org_rcp[axis] < 
new_org_rcp) ?
                 new_org_rcp : ia_data.max_org_rcp[axis];
-#endif
+
         }
     }
 
@@ -158,24 +147,10 @@
             RayPacket subpacket(rays, firstActive, rays.end());
 
             // recurse
-#if 0 // for erw6 this actually hurts slightly
-            int sign_bit = subpacket.getSign(subpacket.begin(), 
static_cast<int>(node.axis));
-            // in manta sign_bit is 1 if direction is < 0
-            // if signbit is < 0, want left child first
-            intersectNode(node.child+(1-sign_bit), context, subpacket, 
ia_data);
-            intersectNode(node.child+sign_bit, context, subpacket, ia_data);
-#else
-#if 1
             int front_son = subpacket.getDirection(subpacket.begin(),
                                                    
static_cast<int>(node.axis)) > 0 ? 0 : 1;
             intersectNode(node.child+front_son, context, subpacket, ia_data);
             intersectNode(node.child+1-front_son, context, subpacket, 
ia_data);
-#else
-            intersectNode(node.child+0, context, subpacket, ia_data);
-            intersectNode(node.child+1, context, subpacket, ia_data);
-#endif
-#endif
-
         }
     }
 }
@@ -183,250 +158,213 @@
 // return the first index (between [rays.begin(),rays.end()]) which hits the 
box
 int DynBVH::firstIntersects(const BBox& box, const RayPacket& rays, const 
IAData& ia_data, float* out_tmin) const
 {
-#define DYNBVH_NEW_SSE MANTA_SSE
-
-#if DYNBVH_NEW_SSE
-    int sse_begin = (rays.begin() + 3)&(~3);
-    int sse_end   = rays.end() & (~3);
-    const RayPacketData* data = rays.data;
-#endif
-    // we always want to do the first ray and IA in C not SIMD
-    for (int ray = rays.begin(); ray < rays.end(); ray++ )
-    {
+#ifdef MANTA_SSE
+    int b = (rays.rayBegin + 3) & (~3);
+    int e = rays.rayEnd & (~3);
+    if (b==e) {
+      for (int i = rays.begin(); i < rays.end(); i++) {
         float tmin = 1e-5f;
-        float tmax = rays.getMinT(ray);
+        float tmax = rays.getMinT(i);
 
         for (int c = 0; c < 3; c++) {
-            float t0 = (box[0][c] - rays.getOrigin(ray,c)) * 
rays.getInverseDirection(ray,c);
-            float t1 = (box[1][c] - rays.getOrigin(ray,c)) * 
rays.getInverseDirection(ray,c);
+            float t0 = (box[0][c] - rays.getOrigin(i,c)) * 
rays.getInverseDirection(i,c);
+            float t1 = (box[1][c] - rays.getOrigin(i,c)) * 
rays.getInverseDirection(i,c);
 
             float near = (t0 < t1) ? t0 : t1;
             float far  = (t0 < t1) ? t1 : t0;
-            //tmin = (tmin < near) ? near : tmin; // max of tmin, near
-            //tmax = (far <  tmax) ? far : tmax;  // min of tmax, far
-            tmin = (near < tmin) ? tmin : near; // non nan-safe max of tmin, 
near
-            tmax = (tmax < far)  ? tmax : far; // non nan-safe min of tmax, 
far
+            tmin = (tmin < near) ? near : tmin; // max of tmin, near
+            tmax = (far <  tmax) ? far : tmax;  // min of tmax, far
         }
         if (tmin <= tmax) {  // valid intersection
             *out_tmin = tmin;
-            return ray;
+            return i;
         }
+      }
+    } else {
+      int i = rays.rayBegin;
+      for(;i<b;i++) {
+        float tmin = 1e-5f;
+        float tmax = rays.getMinT(i);
 
-#if 1 // enable/disable frustum test (goes from 15 fps to 21 fps)
-        if (ray == rays.begin())
-        {
-            // try a frustum miss
-            float tmin_frustum = 1e-5;
-            float tmax_frustum = FLT_MAX;
-
-            for (int axis = 0; axis < 3; axis++)
-            {
-#if 1 // (box - orgIA) * rcpIA
-                // the subtraction is really (boxIA + -orgIA)
-                // or boxIA + [-max_org, -min_org]
-                // [box_min, box_max] + [-max_org, -min_org]
-                float a = box[0][axis]-ia_data.max_org[axis];
-                float b = box[1][axis]-ia_data.min_org[axis];
-
-                // now for multiplication
-                float ar0 = a * ia_data.min_rcp[axis];
-                float ar1 = a * ia_data.max_rcp[axis];
-                float br0 = b * ia_data.min_rcp[axis];
-                float br1 = b * ia_data.max_rcp[axis];
-
-                // [a,b] is valid intersection interval so a is min
-                // and b is max t-value
-
-                //a = std::min(ar0, std::min(ar1, std::min(br0, br1)));
-                a = (br0 < br1) ? br0 : br1;
-                a = (a   < ar1) ?   a : ar1;
-                a = (a   < ar0) ?   a : ar0;
-
-                //b = std::max(ar0, std::max(ar1, std::max(br0, br1)));
-                b = (br0 < br1) ? br1 : br0;
-                b = (b   < ar1) ? ar1 : b;
-                b = (b   < ar0) ? ar0 : b;
-#else //box * rcpIA - org_rcpIA
-                float a = box[0][axis]*ia_data.min_rcp[axis];
-                float b = box[0][axis]*ia_data.max_rcp[axis];
-                float first_min = (a < b) ? a : b;
-                float first_max = (a < b) ? b : a;
-
-                float c = box[1][axis]*ia_data.min_rcp[axis];
-                float d = box[1][axis]*ia_data.max_rcp[axis];
-
-                float second_min = (c < d) ? c : d;
-                float second_max = (c < d) ? d : c;
-
-                a = (first_min < second_min) ? first_min : second_min;
-                b = (first_max > second_max) ? first_max : second_max;
-
-                a -= ia_data.max_org_rcp[axis];
-                b -= ia_data.min_org_rcp[axis];
-#endif
-                tmin_frustum = (tmin_frustum < a) ? a : tmin_frustum;
-                tmax_frustum = (tmax_frustum > b) ? b : tmax_frustum;
-            }
+        for (int c = 0; c < 3; c++) {
+          float t0 = (box[0][c] - rays.getOrigin(i,c)) * 
rays.getInverseDirection(i,c);
+          float t1 = (box[1][c] - rays.getOrigin(i,c)) * 
rays.getInverseDirection(i,c);
 
-            if (tmin_frustum > tmax_frustum) // frustum exit
-            {
-                return rays.end();
-            }
+          float near = (t0 < t1) ? t0 : t1;
+          float far  = (t0 < t1) ? t1 : t0;
+          tmin = (tmin < near) ? near : tmin; // max of tmin, near
+          tmax = (far <  tmax) ? far : tmax;  // min of tmax, far
+        }
+        if (tmin <= tmax) {  // valid intersection
+          *out_tmin = tmin;
+          return i;
         }
-#endif // do frustum test
-#if (DYNBVH_NEW_SSE && 1)
-        // if we can use simd now, jump out (redoes some work for SIMD 
aligned rays)
-        if ( ray == sse_begin || ray == sse_begin - 1 )
-            break;
-#endif
-    }
-
-#if DYNBVH_NEW_SSE
-    // process simds now
-
-    // TODO(boulos): replace operator overloads with direct access
-#if 1
-    int pack_begin = sse_begin >> 2;
-    int pack_end   = sse_end   >> 2;
-    __m128 box_x0 = _mm_set1_ps(box[0][0]);
-    __m128 box_x1 = _mm_set1_ps(box[1][0]);
-
-    __m128 box_y0 = _mm_set1_ps(box[0][1]);
-    __m128 box_y1 = _mm_set1_ps(box[1][1]);
 
-    __m128 box_z0 = _mm_set1_ps(box[0][2]);
-    __m128 box_z1 = _mm_set1_ps(box[1][2]);
+        if (i == rays.rayBegin) {
+          // try a frustum miss
+          float tmin_frustum = 1e-5;
+          float tmax_frustum = FLT_MAX;
+
+          for (int axis = 0; axis < 3; axis++) {
+            // the subtraction is really (boxIA + -orgIA)
+            // or boxIA + [-max_org, -min_org]
+            // [box_min, box_max] + [-max_org, -min_org]
+            float a = box[0][axis]-ia_data.max_org[axis];
+            float b = box[1][axis]-ia_data.min_org[axis];
+
+            // now for multiplication
+            float ar0 = a * ia_data.min_rcp[axis];
+            float ar1 = a * ia_data.max_rcp[axis];
+            float br0 = b * ia_data.min_rcp[axis];
+            float br1 = b * ia_data.max_rcp[axis];
+
+            // [a,b] is valid intersection interval so a is min
+            // and b is max t-value
+
+            //a = std::min(ar0, std::min(ar1, std::min(br0, br1)));
+            a = (br0 < br1) ? br0 : br1;
+            a = (a   < ar1) ?   a : ar1;
+            a = (a   < ar0) ?   a : ar0;
+
+            //b = std::max(ar0, std::max(ar1, std::max(br0, br1)));
+            b = (br0 < br1) ? br1 : br0;
+            b = (b   < ar1) ? ar1 : b;
+            b = (b   < ar0) ? ar0 : b;
+
+            tmin_frustum = (tmin_frustum < a) ? a : tmin_frustum;
+            tmax_frustum = (tmax_frustum > b) ? b : tmax_frustum;
+          }
+
+          // frustum exit
+          if (tmin_frustum > tmax_frustum) {
+            return rays.end();
+          }
+        }
+      }
 
-    for (int pack = pack_begin, ray = sse_begin; pack < pack_end; ++pack, 
ray += 4)
-    {
-        __m128 x0 = _mm_mul_ps(_mm_sub_ps(box_x0, 
_mm_load_ps(&data->origin[0][ray])),
-                               _mm_load_ps(&data->inverseDirection[0][ray]));
-        __m128 x1 = _mm_mul_ps(_mm_sub_ps(box_x1, 
_mm_load_ps(&data->origin[0][ray])),
-                               _mm_load_ps(&data->inverseDirection[0][ray]));
+      RayPacketData* data = rays.data;
+      __m128 box_x0 = _mm_set1_ps(box[0][0]);
+      __m128 box_x1 = _mm_set1_ps(box[1][0]);
+
+      __m128 box_y0 = _mm_set1_ps(box[0][1]);
+      __m128 box_y1 = _mm_set1_ps(box[1][1]);
+
+      __m128 box_z0 = _mm_set1_ps(box[0][2]);
+      __m128 box_z1 = _mm_set1_ps(box[1][2]);
+
+      for(;i<e;i+=4){
+        __m128 x0 = _mm_mul_ps(_mm_sub_ps(box_x0, 
_mm_load_ps(&data->origin[0][i])),
+                               _mm_load_ps(&data->inverseDirection[0][i]));
+        __m128 x1 = _mm_mul_ps(_mm_sub_ps(box_x1, 
_mm_load_ps(&data->origin[0][i])),
+                               _mm_load_ps(&data->inverseDirection[0][i]));
 
         __m128 xmin = _mm_min_ps(x0,x1);
         __m128 xmax = _mm_max_ps(x0,x1);
 
-        __m128 y0 = _mm_mul_ps(_mm_sub_ps(box_y0, 
_mm_load_ps(&data->origin[1][ray])),
-                               _mm_load_ps(&data->inverseDirection[1][ray]));
-        __m128 y1 = _mm_mul_ps(_mm_sub_ps(box_y1, 
_mm_load_ps(&data->origin[1][ray])),
-                               _mm_load_ps(&data->inverseDirection[1][ray]));
+        __m128 y0 = _mm_mul_ps(_mm_sub_ps(box_y0, 
_mm_load_ps(&data->origin[1][i])),
+                               _mm_load_ps(&data->inverseDirection[1][i]));
+        __m128 y1 = _mm_mul_ps(_mm_sub_ps(box_y1, 
_mm_load_ps(&data->origin[1][i])),
+                               _mm_load_ps(&data->inverseDirection[1][i]));
 
         __m128 ymin = _mm_min_ps(y0,y1);
         __m128 ymax = _mm_max_ps(y0,y1);
 
-        __m128 z0 = _mm_mul_ps(_mm_sub_ps(box_z0, 
_mm_load_ps(&data->origin[2][ray])),
-                               _mm_load_ps(&data->inverseDirection[2][ray]));
-        __m128 z1 = _mm_mul_ps(_mm_sub_ps(box_z1, 
_mm_load_ps(&data->origin[2][ray])),
-                               _mm_load_ps(&data->inverseDirection[2][ray]));
+        __m128 z0 = _mm_mul_ps(_mm_sub_ps(box_z0, 
_mm_load_ps(&data->origin[2][i])),
+                               _mm_load_ps(&data->inverseDirection[2][i]));
+        __m128 z1 = _mm_mul_ps(_mm_sub_ps(box_z1, 
_mm_load_ps(&data->origin[2][i])),
+                               _mm_load_ps(&data->inverseDirection[2][i]));
 
         __m128 zmin = _mm_min_ps(z0,z1);
         __m128 zmax = _mm_max_ps(z0,z1);
 
         __m128 maximum_minimum = 
_mm_max_ps(xmin,_mm_max_ps(ymin,_mm_max_ps(zmin, _mm_set1_ps(1e-5f))));
-        __m128 minimum_maximum = 
_mm_min_ps(xmax,_mm_min_ps(ymax,_mm_min_ps(zmax,_mm_load_ps(&data->minT[ray]))));
-        __m128 valid_intersect = 
_mm_cmplt_ps(maximum_minimum,minimum_maximum);
+        __m128 minimum_maximum = 
_mm_min_ps(xmax,_mm_min_ps(ymax,_mm_min_ps(zmax,_mm_load_ps(&data->minT[i]))));
+        __m128 valid_intersect = 
_mm_cmple_ps(maximum_minimum,minimum_maximum);
         if (_mm_movemask_ps(valid_intersect) != 0x0)
-            return ray;
-    }
-#else // different more register efficient version
-    // NOTE(boulos): This code had a severe bug that may have made it look 
more efficient than it is...
-    // two regs for box
-    __m128 box0 = _mm_set_ps(0.f, box[0][2], box[0][1], box[0][0]);
-    __m128 box1 = _mm_set_ps(0.f, box[1][2], box[1][1], box[1][0]);
-    for (int ray = sse_begin; ray < sse_end; ray += 4) {
-        // two regs for interval tracking
-        __m128 tmin = _mm_set1_ps(1e-5f);
-        __m128 tmax = _mm_load_ps(&data->minT[ray]);
-        // current is 4
-        // 1 for inv dir, 1 for ray org, 1 for shuffle output
-
-        __m128 t0 = _mm_mul_ps( _mm_sub_ps( _mm_shuffle_ps(box0, box0, 
_MM_SHUFFLE(0,0,0,0)),
-                                            
_mm_load_ps(&data->origin[0][ray])),
-                                _mm_load_ps(&data->inverseDirection[0][ray]) 
);
-        __m128 t1 = _mm_mul_ps( _mm_sub_ps( _mm_shuffle_ps(box1, box1, 
_MM_SHUFFLE(0,0,0,0)),
-                                            
_mm_load_ps(&data->origin[0][ray])),
-                                _mm_load_ps(&data->inverseDirection[0][ray]) 
);
-        tmin = _mm_max_ps(tmin, _mm_min_ps(t0, t1));
-        tmax = _mm_min_ps(tmax, _mm_max_ps(t0, t1));
-
-        t0 = _mm_mul_ps( _mm_sub_ps( _mm_shuffle_ps(box0, box0, 
_MM_SHUFFLE(1,1,1,1)),
-                                     _mm_load_ps(&data->origin[1][ray])),
-                         _mm_load_ps(&data->inverseDirection[1][ray]) );
-        t1 = _mm_mul_ps( _mm_sub_ps( _mm_shuffle_ps(box1, box1, 
_MM_SHUFFLE(1,1,1,1)),
-                                     _mm_load_ps(&data->origin[1][ray])),
-                         _mm_load_ps(&data->inverseDirection[1][ray]) );
-
-        tmin = _mm_max_ps(tmin, _mm_min_ps(t0, t1));
-        tmax = _mm_min_ps(tmax, _mm_max_ps(t0, t1));
-
-        t0 = _mm_mul_ps( _mm_sub_ps( _mm_shuffle_ps(box0, box0, 
_MM_SHUFFLE(2,2,2,2)),
-                                     _mm_load_ps(&data->origin[2][ray])),
-                         _mm_load_ps(&data->inverseDirection[2][ray]) );
-        t1 = _mm_mul_ps( _mm_sub_ps( _mm_shuffle_ps(box1, box1, 
_MM_SHUFFLE(2,2,2,2)),
-                                     _mm_load_ps(&data->origin[2][ray])),
-                         _mm_load_ps(&data->inverseDirection[2][ray]) );
-
-        tmin = _mm_max_ps(tmin, _mm_min_ps(t0, t1));
-        tmax = _mm_min_ps(tmax, _mm_max_ps(t0, t1));
-
-        __m128 valid_intersect = _mm_cmple_ps(tmin, tmax);
-        if (_mm_movemask_ps(valid_intersect) != 0x0) {
-            sse_t min_with_inf = _mm_or_ps(_mm_and_ps(valid_intersect, tmin),
-                                           _mm_andnot_ps(valid_intersect, 
_mm_set1_ps(1e150f)));
-            // a = (t0, t0, t1, t1)
-            sse_t a = _mm_unpacklo_ps(min_with_inf,min_with_inf);
-            // b = (t2, t2, t3, t3)
-            sse_t b = _mm_unpackhi_ps(min_with_inf,min_with_inf);
-            // c = (min(t0,t2), min(t0, t2), min(t1, t3), min(t1, t3))
-            sse_t c = _mm_min_ps(a, b);
-            // The movehl will move the high 2 values to the low 2 values.
-            // This will allow us to compare min(t0,t2) with min(t1, t3).
-            sse_t result = _mm_min_ss(c, _mm_movehl_ps(c, c));
-            // Return the first value.
-            *out_tmin = *((float*)&result);
-            return ray;
+            return i;
+      }
+
+      for(;i<rays.rayEnd;i++) {
+        float tmin = 1e-5f;
+        float tmax = rays.getMinT(i);
+
+        for (int c = 0; c < 3; c++) {
+            float t0 = (box[0][c] - rays.getOrigin(i,c)) * 
rays.getInverseDirection(i,c);
+            float t1 = (box[1][c] - rays.getOrigin(i,c)) * 
rays.getInverseDirection(i,c);
+
+            float near = (t0 < t1) ? t0 : t1;
+            float far  = (t0 < t1) ? t1 : t0;
+            tmin = (tmin < near) ? near : tmin; // max of tmin, near
+            tmax = (far <  tmax) ? far : tmax;  // min of tmax, far
+        }
+        if (tmin <= tmax) {  // valid intersection
+            *out_tmin = tmin;
+            return i;
         }
+      }
     }
-#endif
-    // get remaining rays
-    for (int ray = sse_begin+1; ray < rays.end(); ++ray) {
-        float maximum_minimum = 1e-5;
-        float minimum_maximum = rays.getMinT(ray);
-
-        float x_minimum = (box[rays.getSign(ray,0)][0]   - 
rays.getOrigin(ray,0)) * rays.getInverseDirection(ray,0);
-        float x_maximum = (box[1-rays.getSign(ray,0)][0] - 
rays.getOrigin(ray,0)) * rays.getInverseDirection(ray,0);
-
-        float y_minimum = (box[rays.getSign(ray,1)][1]   - 
rays.getOrigin(ray,1)) * rays.getInverseDirection(ray,1);
-        float y_maximum = (box[1-rays.getSign(ray,1)][1] - 
rays.getOrigin(ray,1)) * rays.getInverseDirection(ray,1);
-
-        float z_minimum = (box[rays.getSign(ray,2)][2]   - 
rays.getOrigin(ray,2)) * rays.getInverseDirection(ray,2);
-        float z_maximum = (box[1-rays.getSign(ray,2)][2] - 
rays.getOrigin(ray,2)) * rays.getInverseDirection(ray,2);
-
-        if ( minimum_maximum < x_minimum ||
-             maximum_minimum > x_maximum )
-            continue;
-        if ( minimum_maximum > x_maximum )
-            minimum_maximum = x_maximum;
-        if ( maximum_minimum < x_minimum )
-            maximum_minimum = x_minimum;
-        if ( minimum_maximum < y_minimum ||
-             maximum_minimum > y_maximum )
-            continue;
-        if ( minimum_maximum > y_maximum )
-                minimum_maximum = y_maximum;
-        if ( maximum_minimum < y_minimum )
-            maximum_minimum = y_minimum;
-
-        if ( minimum_maximum >= z_minimum &&
-             maximum_minimum <= z_maximum )
-        {
-            *out_tmin = (maximum_minimum < z_minimum) ? maximum_minimum : 
z_minimum;
-            return ray; // found a hit
+    return rays.end();
+#else
+    for (int i = rays.begin(); i < rays.end(); i++) {
+      float tmin = 1e-5f;
+      float tmax = rays.getMinT(ray);
+
+      for (int c = 0; c < 3; c++) {
+        float t0 = (box[0][c] - rays.getOrigin(i,c)) * 
rays.getInverseDirection(i,c);
+        float t1 = (box[1][c] - rays.getOrigin(i,c)) * 
rays.getInverseDirection(i,c);
+
+        float near = (t0 < t1) ? t0 : t1;
+        float far  = (t0 < t1) ? t1 : t0;
+        tmin = (tmin < near) ? near : tmin; // max of tmin, near
+        tmax = (far <  tmax) ? far : tmax;  // min of tmax, far
+      }
+      if (tmin <= tmax) {  // valid intersection
+        *out_tmin = tmin;
+        return ray;
+      }
+
+      if (i == rays.begin()) {
+        // try a frustum miss
+        float tmin_frustum = 1e-5;
+        float tmax_frustum = FLT_MAX;
+
+        for (int axis = 0; axis < 3; axis++) {
+          // the subtraction is really (boxIA + -orgIA)
+          // or boxIA + [-max_org, -min_org]
+          // [box_min, box_max] + [-max_org, -min_org]
+          float a = box[0][axis]-ia_data.max_org[axis];
+          float b = box[1][axis]-ia_data.min_org[axis];
+
+          // now for multiplication
+          float ar0 = a * ia_data.min_rcp[axis];
+          float ar1 = a * ia_data.max_rcp[axis];
+          float br0 = b * ia_data.min_rcp[axis];
+          float br1 = b * ia_data.max_rcp[axis];
+
+          // [a,b] is valid intersection interval so a is min
+          // and b is max t-value
+
+          //a = std::min(ar0, std::min(ar1, std::min(br0, br1)));
+          a = (br0 < br1) ? br0 : br1;
+          a = (a   < ar1) ?   a : ar1;
+          a = (a   < ar0) ?   a : ar0;
+
+          //b = std::max(ar0, std::max(ar1, std::max(br0, br1)));
+          b = (br0 < br1) ? br1 : br0;
+          b = (b   < ar1) ? ar1 : b;
+          b = (b   < ar0) ? ar0 : b;
+
+          tmin_frustum = (tmin_frustum < a) ? a : tmin_frustum;
+          tmax_frustum = (tmax_frustum > b) ? b : tmax_frustum;
+          }
+
+        // frustum exit
+        if (tmin_frustum > tmax_frustum) {
+          return rays.end();
         }
+      }
     }
 #endif
-    return rays.end();
 }
 
 // return the last index which hits the box




  • [MANTA] r1235 - trunk/Model/Groups, boulos, 11/12/2006

Archive powered by MHonArc 2.6.16.

Top of page