Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r1107 - trunk/Model/Groups


Chronological Thread 
  • From: boulos@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r1107 - trunk/Model/Groups
  • Date: Thu, 8 Jun 2006 20:47:08 -0600 (MDT)

Author: boulos
Date: Thu Jun  8 20:47:06 2006
New Revision: 1107

Modified:
   trunk/Model/Groups/DynBVH.cc
   trunk/Model/Groups/DynBVH.h
Log:
Adding a general interval arithmetic test to 
the DynBVH code.  Although it seems to still
product correct output, the simple scene I 
tested is only marginally faster overall (7%).


Modified: trunk/Model/Groups/DynBVH.cc
==============================================================================
--- trunk/Model/Groups/DynBVH.cc        (original)
+++ trunk/Model/Groups/DynBVH.cc        Thu Jun  8 20:47:06 2006
@@ -13,13 +13,39 @@
     rays.computeInverseDirections();
     rays.computeSigns();
 
-    intersectNode(0,context,rays);
+
+    // compute IntervalArithmetic Data
+    IAData ia_data;
+    for (int axis = 0; axis < 3; axis++ )
+    {
+        ia_data.min_rcp[axis]     =  DBL_MAX;
+        ia_data.max_rcp[axis]     = -DBL_MAX;
+        ia_data.min_org_rcp[axis] =  DBL_MAX;
+        ia_data.max_org_rcp[axis] = -DBL_MAX;
+    }
+
+    for (int ray = rays.begin(); ray < rays.end(); ray++ )
+    {
+        for (int axis = 0; axis < 3; axis++)
+        {
+            const Real new_rcp     = rays.getInverseDirection(ray, axis);
+            const Real new_org_rcp = rays.getOrigin(ray,axis) * new_rcp;
+
+            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_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);
+        }
+    }
+
+    intersectNode(0,context,rays, ia_data);
 }
 
-void DynBVH::intersectNode(int nodeID, const RenderContext& context, 
RayPacket& rays) const
+void DynBVH::intersectNode(int nodeID, const RenderContext& context, 
RayPacket& rays, const IAData& ia_data) const
 {
     const BVHNode& node = nodes[nodeID];
-    int firstActive = firstIntersects(node.bounds, rays);
+    int firstActive = firstIntersects(node.bounds, rays, ia_data);
 
     if (firstActive != rays.end())
     {
@@ -49,8 +75,8 @@
             RayPacket subpacket(rays, firstActive, rays.end());
 
             // recurse
-            intersectNode(node.child+0, context, subpacket);
-            intersectNode(node.child+1, context, subpacket);
+            intersectNode(node.child+0, context, subpacket, ia_data);
+            intersectNode(node.child+1, context, subpacket, ia_data);
         }
     }
 }
@@ -59,7 +85,7 @@
 // forward and backward search?
 
 // return the first index (between [rays.begin(),rays.end()]) which hits the 
box
-int DynBVH::firstIntersects(const BBox& box, const RayPacket& rays) const
+int DynBVH::firstIntersects(const BBox& box, const RayPacket& rays, const 
IAData& ia_data) const
 {
     for (int ray = rays.begin(); ray < rays.end(); ray++ )
     {
@@ -93,6 +119,39 @@
         if ( minimum_maximum >= z_minimum &&
              maximum_minimum <= z_maximum )
             return ray; // found a hit
+
+        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++)
+            {
+                float a = box[0][axis]*ia_data.min_rcp[axis];
+                float b = box[0][axis]*ia_data.max_rcp[axis];
+                if (a > b)
+                    std::swap(a,b);
+                float c = box[1][axis]*ia_data.min_rcp[axis];
+                float d = box[1][axis]*ia_data.max_rcp[axis];
+                if (c > d)
+                    std::swap(c,d);
+
+                a = std::min(a,c);
+                b = std::max(b,d);
+
+                a -= ia_data.max_org_rcp[axis];
+                b -= ia_data.min_org_rcp[axis];
+                tmin_frustum = std::max(tmin_frustum, a);
+                tmax_frustum = std::min(tmax_frustum, b);
+            }
+
+            if (tmin_frustum > tmax_frustum) // frustum exit
+            {
+                return rays.end();
+            }
+        }
+
     }
     return rays.end();
 }

Modified: trunk/Model/Groups/DynBVH.h
==============================================================================
--- trunk/Model/Groups/DynBVH.h (original)
+++ trunk/Model/Groups/DynBVH.h Thu Jun  8 20:47:06 2006
@@ -10,6 +10,14 @@
     class DynBVH : public Group
     {
     public:
+        struct IAData
+        {
+            Real min_rcp[3];
+            Real max_rcp[3];
+            Real min_org_rcp[3];
+            Real max_org_rcp[3];
+        };
+
         struct BVHNode
         {
             BBox bounds;
@@ -52,11 +60,11 @@
 
         void preprocess(const PreprocessContext&);
         void intersect(const RenderContext& context, RayPacket& rays) const;
-        void intersectNode(int nodeID, const RenderContext& context, 
RayPacket& rays) const;
+        void intersectNode(int nodeID, const RenderContext& context, 
RayPacket& rays, const IAData& ia_data) const;
 
 
         // return the first index (between [rays.begin(),rays.end()]) which 
hits the box
-        int firstIntersects(const BBox& box, const RayPacket& rays) const;
+        int firstIntersects(const BBox& box, const RayPacket& rays, const 
IAData& ia_data) const;
         // return the last index which hits the box
         int lastIntersects(const BBox& box, const RayPacket& rays) const;
 




  • [MANTA] r1107 - trunk/Model/Groups, boulos, 06/08/2006

Archive powered by MHonArc 2.6.16.

Top of page