Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r860 - in trunk: Core/Geometry Interface Model/Groups scenes


Chronological Thread 
  • From: abe@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r860 - in trunk: Core/Geometry Interface Model/Groups scenes
  • Date: Mon, 23 Jan 2006 03:08:55 -0700 (MST)

Author: abe
Date: Mon Jan 23 03:08:54 2006
New Revision: 860

Added:
   trunk/Model/Groups/VerticalKDTree-stub.cc
   trunk/Model/Groups/VerticalKDTree.cc
      - copied, changed from r858, trunk/Model/Groups/KDTree.cc
   trunk/Model/Groups/VerticalKDTree.h
      - copied, changed from r858, trunk/Model/Groups/KDTree.h
Modified:
   trunk/Core/Geometry/BBox.h
   trunk/Interface/RayPacket.h
   trunk/Model/Groups/CMakeLists.txt
   trunk/Model/Groups/KDTree.cc
   trunk/Model/Groups/KDTree.h
   trunk/scenes/boeing777.cc
Log:



Fixed Real float/double conflict.
M    Core/Geometry/BBox.h

Added methods to access individual vertical components of direction, origin 
etc.
M    Interface/RayPacket.h

Added VerticalKDTree traversal implementation. The code compiles but doesn't 
work yet.

VerticalKDTree contains a vertical implementation of the traversal (and 
eventually the triangle intersection). After this implementation is finished 
we will add a SSE implementation based on the vertical implementation.

The code currently requires that Real==float. The stub implementation will be 
used in cases where Real==double.

Currently the size of the vertical "traversal packet" is configurable in 
CMake. For sse it would be 4 but this will allow us to experiment with 
different sizes. The parameter is configured by 
KdtreeParameters.h.CMakeTemplate

A    Model/Groups/VerticalKDTree.cc
A    Model/Groups/VerticalKDTree.h
M    Model/Groups/KDTree.cc
M    Model/Groups/KDTree.h
A    Model/Groups/VerticalKDTree-stub.cc
M    Model/Groups/CMakeLists.txt

Added -vertical command line option to scene.
M    scenes/boeing777.cc

Modified: trunk/Core/Geometry/BBox.h
==============================================================================
--- trunk/Core/Geometry/BBox.h  (original)
+++ trunk/Core/Geometry/BBox.h  Mon Jan 23 03:08:54 2006
@@ -56,7 +56,7 @@
       return bounds[1] - bounds[0];
     }
     Point center() const {
-      return Interpolate(bounds[0], bounds[1], 0.5);
+      return Interpolate(bounds[0], bounds[1], (Real)0.5);
     }
 
     template< typename T >

Modified: trunk/Interface/RayPacket.h
==============================================================================
--- trunk/Interface/RayPacket.h (original)
+++ trunk/Interface/RayPacket.h Mon Jan 23 03:08:54 2006
@@ -183,6 +183,7 @@
       return Ray(Point(data->origin[0][which], data->origin[1][which], 
data->origin[2][which]),
                  Vector(data->direction[0][which], 
data->direction[1][which], data->direction[2][which]));
     }
+
     void setOrigin(int which, const Point& origin)
     {
       for(int i=0;i<3;i++)
@@ -193,18 +194,56 @@
       for(int i=0;i<3;i++)
         data->direction[i][which] = direction[i];
     }
+
+    
///////////////////////////////////////////////////////////////////////////
+    // GET ORIGIN
     Point getOrigin(int which) const
     {
       return Point(data->origin[0][which], data->origin[1][which], 
data->origin[2][which]);
     }
+
+    Real &getOrigin(int which, int i)
+    {
+      return data->origin[i][which];
+    }
+    const Real &getOrigin(int which, int i) const
+    {
+      return data->origin[i][which];
+    }
+
+    
///////////////////////////////////////////////////////////////////////////
+    // GET DIRECTION
     Vector getDirection(int which) const
     {
       return Vector(data->direction[0][which], data->direction[1][which], 
data->direction[2][which]);
     }
+
+    Real &getDirection(int which, int i)
+    {
+      return data->direction[i][which];
+    }
+    const Real &getDirection(int which, int i) const
+    {
+      return data->direction[i][which];
+    }
+
+    
///////////////////////////////////////////////////////////////////////////
+    // GET INVERSE DIRECTION
     Vector getInverseDirection(int which) const
     {
       return Vector(data->inverseDirection[0][which], 
data->inverseDirection[1][which], data->inverseDirection[2][which]);
     }
+
+    Real &getInverseDirection(int which, int i)
+    {
+      return data->inverseDirection[i][which];
+    }
+    
+    const Real &getInverseDirection(int which, int i) const
+    {
+      return data->inverseDirection[i][which];
+    }    
+    
     void normalizeDirections()
     {
       if(flags & NormalizedDirections)
@@ -283,7 +322,7 @@
       data->hitMatl[which] = 0;
       data->minT[which] = maxt;
     }
-    Real getMinT(int which) const
+    Real &getMinT(int which) const
     {
       return data->minT[which];
     }

Modified: trunk/Model/Groups/CMakeLists.txt
==============================================================================
--- trunk/Model/Groups/CMakeLists.txt   (original)
+++ trunk/Model/Groups/CMakeLists.txt   Mon Jan 23 03:08:54 2006
@@ -1,23 +1,49 @@
 
+# Configure the parameters for the KDTrees
+SET(MANTA_TRAVERSALPACKET_SIZE 4 CACHE STRING "Size to use for vertical 
kdtree traversal packets.")
+CONFIGURE_FILE(
+  ${CMAKE_SOURCE_DIR}/Model/Groups/KdtreeParameters.h.CMakeTemplate
+  ${CMAKE_SOURCE_DIR}/Model/Groups/KdtreeParameters.h
+  )
+  
+
 SET (Manta_Groups_SRCS
-     Groups/BVH.h
      Groups/BVH.cc
-     Groups/GriddedGroup.h
+     Groups/BVH.h
      Groups/GriddedGroup.cc
-     Groups/Group.h
+     Groups/GriddedGroup.h
      Groups/Group.cc
-     Groups/KDTree.h
+     Groups/Group.h
      Groups/KDTree.cc
-     Groups/TransparentKDTree.h
-     Groups/TransparentKDTree.cc
-     Groups/KDTreeLoader.h
+     Groups/KDTree.h
      Groups/KDTreeLoader.cc
-     #Groups/FrustumKDTree.h
-     #Groups/FrustumKDTree.cc
+     Groups/KDTreeLoader.h
+     Groups/KdtreeParameters.h
      Groups/PsiGammaTable.cc
      Groups/PsiGammaTable.h
-     Groups/RealisticBvh.h
      Groups/RealisticBvh.cc
+     Groups/RealisticBvh.h
+     Groups/TransparentKDTree.cc
+     Groups/TransparentKDTree.h
      Groups/VolumeGrid.h
      Groups/varray.h
 )
+
+# Determine if VerticalKDTree can be included
+IF(${MANTA_REAL} MATCHES float)
+  SET(Manta_Groups_SRCS
+    ${Manta_Groups_SRCS}
+    Groups/VerticalKDTree.h
+    Groups/VerticalKDTree.cc
+    )
+
+# Otherwise include a stub implementation.
+ELSE(${MANTA_REAL} MATCHES float)
+  SET(Manta_Groups_SRCS
+    ${Manta_Groups_SRCS}
+    Groups/VerticalKDTree.h
+    Groups/VerticalKDTree-stub.cc
+    )
+ENDIF(${MANTA_REAL} MATCHES float)
+
+

Modified: trunk/Model/Groups/KDTree.cc
==============================================================================
--- trunk/Model/Groups/KDTree.cc        (original)
+++ trunk/Model/Groups/KDTree.cc        Mon Jan 23 03:08:54 2006
@@ -289,9 +289,13 @@
       travStack[exitPos].prev = tmp;
     }
 
+    
///////////////////////////////////////////////////////////////////////////
+    
///////////////////////////////////////////////////////////////////////////
     // Check to see if we found a non-empty leaf node.
     if (nearNode) {
 
+      
/////////////////////////////////////////////////////////////////////////
+      
/////////////////////////////////////////////////////////////////////////
       // Intersect the ray with a list of triangles.
       if (intersectTriangles(origin, direction,
                              nearNode->listBegin(), nearNode->listSize(),
@@ -317,16 +321,11 @@
             triFlags->set(i, pickedFlag);
         }
 
-        // Check against the hit record, Note that tex coord mapper is null.
+        
///////////////////////////////////////////////////////////////////////
+        
///////////////////////////////////////////////////////////////////////
+        // Check against the hit record.
         if (rays.hit(which, isectData.rayHit.t, getMaterial(), this, 0 )) {
 
-          // if (isectData.rayHit.t > t_epsilon) {
-          // e.hitInfo.set_hit(isectData.rayHit.t, material, this, 0 );
-
-          // e.normal = normals[isectData.rayHitTriIndex];
-
-          //e.hitInfo.scratchpad<ScratchPadInfo>().normal  = 
normals[isectData.rayHitTriIndex];
-
           // Interpolate between the three vertices.
           Vectorf &n0 = normals[isectData.rayHitTriIndex][0];
           Vectorf &n1 = normals[isectData.rayHitTriIndex][1];
@@ -368,9 +367,6 @@
             } else
               scratch_pad.payload = 
tris->get(isectData.rayHitTriIndex).payload;
 #endif
-          // Check to make sure the found hit is inside the current cell.
-          // if ((isectData.rayHit.t <= travStack[exitPos].t)/* && 
(isectData.rayHit.t > travStack[entryPos].t)*/)
-          // break;
         }
       }
     }

Modified: trunk/Model/Groups/KDTree.h
==============================================================================
--- trunk/Model/Groups/KDTree.h (original)
+++ trunk/Model/Groups/KDTree.h Mon Jan 23 03:08:54 2006
@@ -286,6 +286,7 @@
 
       // Transparent KDTree will use data owned by this kdtree.
       friend class TransparentKDTree;
+      friend class VerticalKDTree;
 
       // The Kdtree::load(...) function is used to load data into the kdtree.
       friend int Manta::Kdtree::load( KDTree *kdtree, const char *filename,

Added: trunk/Model/Groups/VerticalKDTree-stub.cc
==============================================================================
--- (empty file)
+++ trunk/Model/Groups/VerticalKDTree-stub.cc   Mon Jan 23 03:08:54 2006
@@ -0,0 +1,65 @@
+
+
+/*
+  For more information, please see: http://software.sci.utah.edu

+  The MIT License

+  Copyright (c) 2006
+  Scientific Computing and Imaging Institute, University of Utah
+  

+  License for the specific language governing rights and limitations under
+  Permission is hereby granted, free of charge, to any person obtaining a
+  copy of this software and associated documentation files (the "Software"),
+  to deal in the Software without restriction, including without limitation
+  the rights to use, copy, modify, merge, publish, distribute, sublicense,
+  and/or sell copies of the Software, and to permit persons to whom the
+  Software is furnished to do so, subject to the following conditions:

+  The above copyright notice and this permission notice shall be included
+  in all copies or substantial portions of the Software.

+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+  DEALINGS IN THE SOFTWARE.
+*/
+
+#include <Model/Groups/VerticalKDTree.h>
+
+#include <SCIRun/Core/Exceptions/InternalError.h>
+
+using namespace Manta;
+using namespace Manta::Kdtree;
+using namespace SCIRun;
+
+// This is the Manta interface method.
+void VerticalKDTree::intersect(const RenderContext& context, RayPacket& 
rays) const { }
+
+///////////////////////////////////////////////////////////////////////////////
+// Simple kdtree functions.
+///////////////////////////////////////////////////////////////////////////////
+
+VerticalKDTree::VerticalKDTree( KDTree *kdtree_, Material *material_ )
+  : PrimitiveCommon( material_ ),
+    rootNode( kdtree_->rootNode ),
+    triIndices( kdtree_->triIndices ),
+    tris( kdtree_->tris ),
+    normals( kdtree_->normals )
+{
+  throw InternalError( "Manta::Real == float required for VerticalKDTree", 
__FILE__, __LINE__ ); 
+}
+VerticalKDTree::~VerticalKDTree() { };
+
+void VerticalKDTree::computeNormal(const RenderContext& /*context*/,
+                           RayPacket& rays) const { }
+
+void VerticalKDTree::computeBounds(const PreprocessContext&, BBox &box_ ) 
const { }
+
+void VerticalKDTree::computeBounds( BBox &box_ ) const { }
+
+

Copied: trunk/Model/Groups/VerticalKDTree.cc (from r858, 
trunk/Model/Groups/KDTree.cc)
==============================================================================
--- trunk/Model/Groups/KDTree.cc        (original)
+++ trunk/Model/Groups/VerticalKDTree.cc        Mon Jan 23 03:08:54 2006
@@ -6,7 +6,7 @@
   The MIT License
  
   Copyright (c) 2005
-  Silicon Graphics Inc. Mountain View California.
+  Scientific Computing and Imaging Institute, University of Utah
  
   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
@@ -28,7 +28,7 @@
   DEALINGS IN THE SOFTWARE.
 */
 
-#include <Model/Groups/KDTree.h>
+#include <Model/Groups/VerticalKDTree.h>
 #include <Model/Groups/varray.h>
 
 #include <Model/Intersections/AxisAlignedBox.h>
@@ -88,50 +88,57 @@
 // INTERSECT TRIANGLES  INTERSECT TRIANGLES  INTERSECT TRIANGLES  INTERSECT 
TRI
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
-int KDTree::intersectTriangles(const Pointf& origin, const Vectorf& 
direction,
-                               unsigned int listBegin, unsigned int listSize,
-                               float maxDist,
-                               RayTriIntersectUserData& isectData) const
-{
-  float nearest_u, nearest_v;
-  int nearest_tri = -1;
 
-  // Intersect the ray with all the triangles.
-  unsigned int listEnd = listBegin+listSize;
+void VerticalKDTree::intersectTriangles(IntersectPacket &intersect_packet,
+                                       const RayPacket &rays,
+                                       int which,
+                                       unsigned int listBegin,
+                                       unsigned int listSize ) const {
+
+  // Keep track of the max value of a possible intersection.
+  float maxDist[TraversalPacketSize];
+  
+  // Initialize nearset variables.
+  for (int p=0;p<TraversalPacketSize;++p) {
+    maxDist[p] = rays.getMinT(which+p);
+  }
 
-#ifndef __sgi
+  // Iterate over all of the triangles.
+  unsigned int listEnd = listBegin+listSize;
 #pragma swp
-#endif
-  for (unsigned int i = listBegin; i < listEnd; ++i) {
-    int triIdx = triIndices->get(i);
+  for (unsigned int i = listBegin; i<listEnd; ++i) {
+
+    int triIdx    = triIndices->get(i);
     Triangle &tri = tris->get(triIdx);
-    float t, u, v;
 
-    if(intersect_triangle3_edge( origin.getDataPtr(), direction.getDataPtr(),
-                                 &tri[0][0],
-                                 &t, &u, &v,
-                                 tri.edge1.getDataPtr(),
-                                 tri.edge2.getDataPtr() ))
-      {
+    // Use horizontal intersection for now...
+    for (int p=0;p<TraversalPacketSize;++p) {
+
+      // Convert origin and direction to float
+      Pointf origin     = rays.getOrigin(which+p);
+      Vectorf direction = rays.getDirection(which+p);
+      
+      float t, u, v;      
+      if(intersect_packet.active_mask[p] &&
+         intersect_triangle3_edge( origin.getDataPtr(),
+                                   direction.getDataPtr(),
+                                   &tri[0][0],
+                                   &t, &u, &v,
+                                   tri.edge1.getDataPtr(),
+                                   tri.edge2.getDataPtr() )) {
+        
         // Check to see if the t value is closer.
-        if (t < maxDist) {
-          maxDist = t;
-          nearest_u = u;
-          nearest_v = v;
-          nearest_tri = triIdx;
+        if (t < maxDist[p]) {
+          intersect_packet.t[p] = t;
+          intersect_packet.u[p] = u;
+          intersect_packet.v[p] = v;
+          intersect_packet.hit_index[p] = triIdx;
+
+          // Specify that a valid hit was found.
+          intersect_packet.hit_mask[p] = Mask::True;
         }
       }
-  }
-
-  if (nearest_tri >= 0) {
-    isectData.rayHit.t = maxDist;
-    isectData.rayHit.u = nearest_u;
-    isectData.rayHit.v = nearest_v;
-    isectData.rayHitTriIndex = nearest_tri;
-    return 1;
-               
-  } else {
-    return 0;
+    }
   }
 }
 
@@ -140,47 +147,46 @@
 // This is the Manta interface method.
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
-void KDTree::intersect(const RenderContext& context, RayPacket& rays) const
+
+void VerticalKDTree::intersect(const RenderContext& context, RayPacket& 
rays) const
 {
   rays.normalizeDirections();
   rays.computeInverseDirections();
   rays.computeSigns();
 
-  RayTriIntersectUserData isectData;
-
-  for(int i=rays.begin();i<rays.end();i++) {
-
-    Real minDist, maxDist;
-
-    // Intersect the ray with the bounding box for the group.
-    if (Intersection::intersectAaBox( bbox,
-                                      minDist, maxDist,
-                                      rays.getRay(i),
-                                      rays.getSigns(i),
-                                      rays.getInverseDirection(i)))
-      {
-        // Determine the actual minimum distance.
-        minDist = SCIRun::Max( minDist, T_EPSILON );
-        maxDist = SCIRun::Min( maxDist, rays.getMinT(i) );
-
-        // Send the ray to the _intersect function.
-        isectData.rayHitTriIndex = -1;
-        isectData.duplicate = 0;
-        intersect_node( rootNode, rays, i, isectData, context, 
(float)minDist, (float)maxDist);
-
-      }
-  }
-}
+  // Mask to keep track of which rays are valid.
+  Mask valid_mask( Mask::False );
+  
+  // Iterate over sub groups of rays.
+  for(int which=rays.begin();which<rays.end();which+=TraversalPacketSize) {
+
+    float minDist[TraversalPacketSize];
+    float maxDist[TraversalPacketSize];
+
+    // Compute min and max distance for the kdtree.
+    for (int p=0;(p<TraversalPacketSize)&&((which+p)<rays.end());++p) {
+      
+      // Intersect the ray with the bounding box for the group.
+      valid_mask[p] = Intersection::intersectAaBox( bbox,
+                                                    minDist[p],
+                                                    maxDist[p],
+                                                    rays.getRay(which+p),
+                                                    rays.getSigns(which+p),
+                                                    
rays.getInverseDirection(which+p));
+
+      
+      
+      // Determine the actual minimum distance.
+      minDist[p] = SCIRun::Max( minDist[p], (float)T_EPSILON );
+      maxDist[p] = SCIRun::Min( maxDist[p], (float)rays.getMinT(which+p) );
+    }
 
-///////////////////////////////////////////////////////////////////////////////
-// This function performs the KD-Tree Traversal.
-///////////////////////////////////////////////////////////////////////////////
-void KDTree::computeNormal(const RenderContext& /*context*/,
-                           RayPacket& rays) const {
+    // Check to see if a traversal is necessary.
+    if (any(valid_mask)) {
 
-  // Copy the normal out of the KDTree::ScratchPadInfo structure.
-  for (int i=rays.begin();i<rays.end();++i) {
-    rays.setNormal(i, rays.scratchpad<ScratchPadInfo>(i).normal);
+      // Intersect the subpacket with the tree.
+      intersect_node( context, valid_mask, rays, which, minDist, maxDist );
+    }
   }
 }
 
@@ -192,43 +198,53 @@
 
 // Traversal Stack Entry.
 struct TravStackEntry {
+  float       t[TraversalPacketSize];
   KDTreeNode* node;  // 8 bytes(64 bit builds), 4 bytes(32 bit builds)
-  float t;           // 4 bytes
-  int prev;          // 4 bytes
+  int         prev;  // 4 bytes
+  int         padding;
+  
 };
 
-void KDTree::intersect_node( KDTreeNode *startNode,
-                             RayPacket& rays, int which,
-                             RayTriIntersectUserData &isectData,
-                             const RenderContext &context,
-                             float minDist, float maxDist) const
+void VerticalKDTree::intersect_node( const RenderContext &context,
+                                     const Mask &valid_mask,
+                                     RayPacket &rays,
+                                     int which,
+                                     float minDist[TraversalPacketSize],
+                                     float maxDist[TraversalPacketSize] ) 
const
 {
-  KDTreeNode *nearNode = startNode;
+
+  
/////////////////////////////////////////////////////////////////////////////
+  // Stack pointers.
+  KDTreeNode *nearNode = rootNode;
   KDTreeNode *farNode;
   int entryPos = 0;
   int exitPos = 1;
 
+  
/////////////////////////////////////////////////////////////////////////////
   // Keep a stack of entry and exit positions into the traversal nodes.
-#ifdef __ia64__
-  // __declspec(align(128))
-#endif
-  TravStackEntry travStack[128];
+  __declspec(align(128)) TravStackEntry travStack[128];
 
   // Initialize the first two entries on the stack.
-  travStack[entryPos].node = startNode;
+  travStack[entryPos].node = rootNode;
+  travStack[entryPos].prev = 1;
+  
   // Check for the case that the minimum intersection point is behind
   // the origin.
-  travStack[entryPos].t = minDist < 0 ? 0 : minDist;
-  travStack[entryPos].prev = 1;
-
+  for (int p=0;p<TraversalPacketSize;++p) {
+    travStack[entryPos].t[p] = SCIRun::Max( 0.0f, minDist[p] );
+  }
+  
   travStack[exitPos].node = NULL;
-  travStack[exitPos].t = maxDist;
   travStack[exitPos].prev = 0;

+  for (int p=0;p<TraversalPacketSize;++p) {
+    travStack[exitPos].t[p] = maxDist[p];
+  }
 
-  Pointf  origin    = rays.getOrigin(which);
-  Vectorf direction = rays.getDirection(which);
-  Vectorf invDirection = rays.getInverseDirection(which);
-
+  
/////////////////////////////////////////////////////////////////////////////
+  // Mask to keep track of rays that still need to find closest 
intersections.
+  Mask active_mask = valid_mask;
+  
   while (travStack[entryPos].prev) {
 
     // Traverse down until we find a leaf node.
@@ -240,42 +256,78 @@
       // Determine the axis and the split point.
       int axis = nearNode->axis();
       float split = nearNode->split();
-
+      
       // Find where along the axis the ray enters and exits.
-      float entryPos_coord_on_axis =
-        travStack[entryPos].t*direction[axis] + origin[axis];
-      float exitPos_coord_on_axis =
-        travStack[exitPos].t*direction[axis] + origin[axis];
-
+      float entry_axis[TraversalPacketSize];
+      float exit_axis [TraversalPacketSize];
+      
+      for (int p=0;p<TraversalPacketSize;++p) {
+        if (active_mask[p]) {
+          entry_axis[p] =
+            travStack[entryPos].t[p] *
+            rays.getDirection(which+p,axis) +
+            rays.getOrigin   (which+p,axis);
+
+          exit_axis[p] =
+            travStack[exitPos].t[p] *
+            rays.getDirection(which+p,axis) +
+            rays.getOrigin   (which+p,axis);
+        }
+      }
+      
+      
/////////////////////////////////////////////////////////////////////////
       // Check to see which side of the split the ray enters first.
-      if (entryPos_coord_on_axis <= split) {
+      // if (entryPos_coord_on_axis <= split) {
+      Mask cmp_result;
+      set_lte( cmp_result, entry_axis, split );
+      if (all( active_mask, cmp_result )) {
 
+        
///////////////////////////////////////////////////////////////////////
         // Check to see if entry and exit are on the
         // same side of the split.
-        if (exitPos_coord_on_axis <= split) {
+        // if (exitPos_coord_on_axis <= split) {
+        set_lte( cmp_result, exit_axis, split );
+        if (all( active_mask, cmp_result )) {
+
+          
/////////////////////////////////////////////////////////////////////
+          // Case "A"
 
           // Same side of the split, so the original interval is ok.
           nearNode = nearNode->left();
           continue;
         }
 
+        
///////////////////////////////////////////////////////////////////////
+        // Case "B"
+
         // Otherwise update the near and far nodes, and then update
         // the interval below.
         farNode = nearNode->right();
         nearNode = nearNode->left();
       }
       else {
+
         // Check to see if entry and exit are on the same side.
-        if (exitPos_coord_on_axis >= split) {
+        // if (exitPos_coord_on_axis >= split) {
+        set_gte( cmp_result, exit_axis, split );
+        if (all(active_mask, cmp_result)) {
+
+          
/////////////////////////////////////////////////////////////////////
+          // Case "C"
+          
           nearNode = nearNode->right();
           continue;
         }
 
+        
/////////////////////////////////////////////////////////////////////..
+        // Case "D"
+
         // Update otherwise.
         farNode = nearNode->left();
         nearNode = nearNode->right();
       }
 
+      
/////////////////////////////////////////////////////////////////////////
       // Update location on the traversal stack.
       int tmp = exitPos;
 
@@ -285,99 +337,86 @@
       // Update the far node.
       // Specify a new exit node.
       travStack[exitPos].node = farNode;
-      travStack[exitPos].t = (split - origin[axis])* invDirection[axis];
       travStack[exitPos].prev = tmp;
+      
+      // Compute t value for exit position.
+      for (int p=0;p<TraversalPacketSize;++p) {
+        travStack[exitPos].t[p] =
+          (split - rays.getOrigin(which+p,axis)) *
+           rays.getInverseDirection(which+p,axis);
+      }
     }
 
+    
///////////////////////////////////////////////////////////////////////////
+    
///////////////////////////////////////////////////////////////////////////
     // Check to see if we found a non-empty leaf node.
     if (nearNode) {
 
-      // Intersect the ray with a list of triangles.
-      if (intersectTriangles(origin, direction,
-                             nearNode->listBegin(), nearNode->listSize(),
-                             rays.getMinT(which), isectData)
-          && (isectData.rayHitTriIndex >= 0)) {
-
-        if (isPickingEnabled()) {
-          pickedTri = isectData.rayHitTriIndex;
-          // cerr << "picked " << pickedTri << "\n";
-          pickedBeginIndex = pickedEndIndex = pickedTri;
-          while (pickedBeginIndex > 0 &&
-                 triToGroupMap->get(pickedBeginIndex-1)
-                 == triToGroupMap->get(pickedBeginIndex))
-            pickedBeginIndex --;
-          while (pickedEndIndex < tris->getLen()-1 &&
-                 triToGroupMap->get(pickedEndIndex+1)
-                 == triToGroupMap->get(pickedEndIndex))
-            pickedEndIndex ++;
-          // cerr << "picked begin " << pickedBeginIndex << " end " << 
pickedEndIndex << "\n";
-
-          // cerr << "picked flag: " << (int)pickedFlag << std::endl;
-          for (int i=pickedBeginIndex; i<=pickedEndIndex; i++)
-            triFlags->set(i, pickedFlag);
+      
/////////////////////////////////////////////////////////////////////////
+      
/////////////////////////////////////////////////////////////////////////
+      // Intersect the rays with a list of triangles.
+      IntersectPacket intersect_packet( active_mask );
+      intersectTriangles(intersect_packet,
+                         rays,
+                         which,
+                         nearNode->listBegin(),
+                         nearNode->listSize());
+
+
+      // IntersectPacket::hit_mask[p] must reflect triangleindex >= 0
+
+      ///////////////////////////////////////////////////////////////////////
+      ///////////////////////////////////////////////////////////////////////
+      // Check against the hit record.        
+      for (int p=0;p<TraversalPacketSize;++p) {
+        if (intersect_packet.hit_mask[p]) {
+
+          // Check the hit t against the ray packet min t.
+          intersect_packet.hit_mask[p] = rays.hit( which+p,
+                                                   intersect_packet.t[p],
+                                                   getMaterial(), this, 0 );
         }
+      }
 
-        // Check against the hit record, Note that tex coord mapper is null.
-        if (rays.hit(which, isectData.rayHit.t, getMaterial(), this, 0 )) {
-
-          // if (isectData.rayHit.t > t_epsilon) {
-          // e.hitInfo.set_hit(isectData.rayHit.t, material, this, 0 );
-
-          // e.normal = normals[isectData.rayHitTriIndex];
-
-          //e.hitInfo.scratchpad<ScratchPadInfo>().normal  = 
normals[isectData.rayHitTriIndex];
+      
/////////////////////////////////////////////////////////////////////////
+      // Interpolate normals for successful hits.
+      // normal = (n1 * u) + (n2 * v) + (n0 * (1 - u - v));
+      for (int p=0;p<TraversalPacketSize;++p) {
 
+        if (intersect_packet.hit_mask[p]) {
+        
           // Interpolate between the three vertices.
-          Vectorf &n0 = normals[isectData.rayHitTriIndex][0];
-          Vectorf &n1 = normals[isectData.rayHitTriIndex][1];
-          Vectorf &n2 = normals[isectData.rayHitTriIndex][2];
-
-          float u = isectData.rayHit.u;
-          float v = isectData.rayHit.v;
-
-          ScratchPadInfo& scratch_pad = 
rays.scratchpad<ScratchPadInfo>(which);
+          Vectorf &n0 = normals[intersect_packet.hit_index[p]][0];
+          Vectorf &n1 = normals[intersect_packet.hit_index[p]][1];
+          Vectorf &n2 = normals[intersect_packet.hit_index[p]][2];
+          
+          float u = intersect_packet.u[p];
+          float v = intersect_packet.v[p];
+          
+          ScratchPadInfo& scratch_pad = 
rays.scratchpad<ScratchPadInfo>(which+p);
           scratch_pad.normal = (n1 * u) + (n2 * v) + (n0 * (1 - u - v));
-
-#if SHOW_DUPLICATES
-          if (isectData.duplicate == 0)
-            scratch_pad.payload = Color(RGB(1.0,1.0,1.0));
-          else if (isectData.duplicate > 16)
-            scratch_pad.payload = Color(RGB(1.0,0.0,1.0));
-          else if (isectData.duplicate > 8)
-            scratch_pad.payload = Color(RGB(1.0,0.0,0.0));
-          else if (isectData.duplicate > 4)
-            scratch_pad.payload = Color(RGB(1.0,1.0,0.0));
-          else
-            scratch_pad.payload = Color(RGB(0.0,0.0,1.0));
-#else
-          unsigned char flag;
-          if ( pickedTri > 0 &&
-               /*pickedBeginIndex <= isectData.rayHitTriIndex &&
-                 isectData.rayHitTriIndex <= pickedEndIndex*/
-               (flag=triFlags->get(isectData.rayHitTriIndex))!=0) 
-            {
-              switch(flag) {
-              case PICK_HIGHLIGHT:
-                scratch_pad.payload = Color(RGB(1,1,1))-
-                  tris->get(isectData.rayHitTriIndex).payload;
-                break;
-              case PICK_REMOVE:
-                scratch_pad.payload = Color(RGB(0,0,0));
-                break;
-              }
-            } else
-              scratch_pad.payload = 
tris->get(isectData.rayHitTriIndex).payload;
-#endif
-          // Check to make sure the found hit is inside the current cell.
-          // if ((isectData.rayHit.t <= travStack[exitPos].t)/* && 
(isectData.rayHit.t > travStack[entryPos].t)*/)
-          // break;
-        }
+          scratch_pad.payload = 
tris->get(intersect_packet.hit_index[p]).payload;
+        }          
       }
     }
 
+    /////////////////////////////////////////////////////////////////////
     // Check to see if the hit is inside the current cell.
-    if (rays.getMinT(which) <= travStack[exitPos].t)
+    // if (rays.getMinT(which) <= travStack[exitPos].t)
+    //   break
+    
+    // Update the active_mask.
+    Mask cmp_result;
+    set_gt( cmp_result, &rays.getMinT(which), travStack[exitPos].t );
+
+    // And the active mask with the result of the comparsion.
+    // (only pay attention to bits which are both active and passed the 
comparsion )
+    set_and( active_mask, active_mask, cmp_result );
+    
+    // Check to see if any rays are active any longer.
+    if (none(active_mask)) {
       break;
+    }
 
     // Move to the next
     entryPos = exitPos;
@@ -386,6 +425,41 @@
   }
 }
 
+
+///////////////////////////////////////////////////////////////////////////////
+// Simple kdtree functions.
+///////////////////////////////////////////////////////////////////////////////
+
+VerticalKDTree::VerticalKDTree( KDTree *kdtree_, Material *material_ )
+  : PrimitiveCommon( material_ ),
+    rootNode( kdtree_->rootNode ),
+    triIndices( kdtree_->triIndices ),
+    tris( kdtree_->tris ),
+    normals( kdtree_->normals )
+{
+  bbox.extendByBox( bbox );
+}
+VerticalKDTree::~VerticalKDTree() { };
+
+void VerticalKDTree::computeNormal(const RenderContext& /*context*/,
+                           RayPacket& rays) const {
+
+  // Copy the normal out of the KDTree::ScratchPadInfo structure.
+  for (int i=rays.begin();i<rays.end();++i) {
+    rays.setNormal(i, rays.scratchpad<ScratchPadInfo>(i).normal);
+  }
+}
+
+void VerticalKDTree::computeBounds(const PreprocessContext&, BBox &box_ ) 
const {
+
+  box_.extendByBox( bbox );
+}
+
+void VerticalKDTree::computeBounds( BBox &box_ ) const {
+
+  box_.extendByBox( bbox );
+}
+
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
@@ -607,18 +681,6 @@
   return 1;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-// KDTree Texture.
-///////////////////////////////////////////////////////////////////////////////
-///////////////////////////////////////////////////////////////////////////////
-void KDTreeTexture::mapValues(const RenderContext& /*context*/,
-                              RayPacket& rays, Color results[]) const {
-
-  for (int i=rays.begin();i<rays.end();++i) {
-    results[i] = rays.scratchpad<Kdtree::KDTree::ScratchPadInfo>(i).payload;
-  }
-}
 
 
 

Copied: trunk/Model/Groups/VerticalKDTree.h (from r858, 
trunk/Model/Groups/KDTree.h)
==============================================================================
--- trunk/Model/Groups/KDTree.h (original)
+++ trunk/Model/Groups/VerticalKDTree.h Mon Jan 23 03:08:54 2006
@@ -3,8 +3,8 @@
 
   The MIT License
 
-  Copyright (c) 2005
-  Silicon Graphics Inc. Mountain View California.
+  Copyright (c) 2006
+  Scientific Computing and Imaging Institute, Univeristy of Utah
 
   License for the specific language governing rights and limitations under
   Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,276 +26,162 @@
   DEALINGS IN THE SOFTWARE.
 */
 
-#ifndef __KD_TREE_H__
-#define __KD_TREE_H__
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// NOTE: Manta::Real must be "float" in order for CMake to include this code.
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+// Abe Stephens
+
+#ifndef __VERTICAL_KD_TREE_H__
+#define __VERTICAL_KD_TREE_H__
+
 
-#include <Model/Groups/Group.h>
 #include <Core/Geometry/PointVector.h>
 #include <Core/Geometry/BBox.h>
 
 #include <Interface/RayPacket.h>
-
-#include <Model/Primitives/PrimitiveCommon.h>
-
 #include <Interface/Texture.h>
-#include <Model/Groups/KDTreeLoader.h>
 
+#include <Model/Groups/KDTree.h>
 #include <Model/Groups/varray.h>
+#include <Model/Groups/KdtreeParameters.h>
 
 namespace Manta {
 
-  // Note: Kdtree is the namespace: KDTree, KDTreeTransparent are classes
+  // Note: Kdtree is the namespace: KDTree, VerticalKDTree are classes
   // in the namespace.
   namespace Kdtree {
 
-    // These values are used by both the KDTree and the TransparentKDTree
-    enum { KDNODE_AXIS_MASK = 0x0003,
-           KDNODE_LEFT_CHILD_MASK = 0x0008,
-           KDNODE_RIGHT_CHILD_MASK = 0x0010,
-           KDNODE_INTERNAL_MASK = ( KDNODE_LEFT_CHILD_MASK |
-                                    KDNODE_RIGHT_CHILD_MASK )
-    };
-    
-    // Data is stored in 32 bit floats.
-    typedef VectorT<float,3> Vectorf;
-    typedef PointT <float,3> Pointf;
-
     
///////////////////////////////////////////////////////////////////////////
-    // TRIANGLE  TRIANGLE  TRIANGLE  TRIANGLE  TRIANGLE  TRIANGLE  TRIANGLE  
TR
     
///////////////////////////////////////////////////////////////////////////
-    class Triangle/*: public Geometry*/ {
+    // MASK  MASK  MASK  MASK  MASK  MASK  MASK  MASK  MASK  MASK  MASK  MASK
+    
///////////////////////////////////////////////////////////////////////////
+    
///////////////////////////////////////////////////////////////////////////
+    class Mask {
     public:
-      Pointf  v[3];         // 3*3 floats = 9*4 bytes = 36 bytes
-      Color   payload;      //
-      Vectorf edge1, edge2; // 2*3 floats = 6*4 bytes = 24 bytes
-      // the above are exactly 64 bytes
-
-      Triangle()/* : Geometry()*/ {  }
-
-      Triangle(const float *tri, const Color &p) {
-        v[0] = *(Pointf*)tri;
-        v[1] = *(Pointf*)(tri+3);
-        v[2] = *(Pointf*)(tri+6);
-        payload = p;
-      }
-      Triangle(const Pointf *v_, const Color &p) {
-        v[0] = v_[0]; v[1] = v_[1]; v[2] = v_[2];
-        payload = p;
-      }
-      Triangle(const Pointf &v0_, const Pointf &v1_, const Pointf &v2_,
-               const Color &p) {
-        v[0] = v0_; v[1] = v1_; v[2] = v2_;
-        payload = p;
-      }
+      // Mask values.
+      typedef int Bool;
+      enum { True  = 1,
+             False = 0 };
+  
+      // Accessors.
+      Bool &operator[] (int i)             { return data[i]; }
+      const Bool &operator[] (int i) const { return data[i]; }
 
-      // Access an individual vertex.
-      Pointf &operator[] (int i) { return v[i]; }
-      const Pointf &operator[] (int i) const { return v[i]; }
-
-      void getBound(BBox &bounds_) {
-        bounds_.extendByPoint( v[0] );
-        bounds_.extendByPoint( v[1] );
-        bounds_.extendByPoint( v[2] );
+      // Constructor.
+      Mask() { };
+      Mask( Bool bool_ ) {
+        for (int p=0;p<TraversalPacketSize;++p) {
+          data[p] = bool_;
+        }
       }
-    };
-
-    
///////////////////////////////////////////////////////////////////////////
-    // TRIANGLE NORMALS  TRIANGLE NORMALS  TRIANGLE NORMALS  TRIANGLE 
NORMALS 
-    
///////////////////////////////////////////////////////////////////////////
-    class TriangleNormal {
+  
     private:
-      Vectorf normal[3];
-    public:
-      Vectorf &operator[] ( int i ) { return normal[i]; };
-      const Vectorf &operator[] ( int i ) const { return normal[i]; };
+      // Actual stored values.
+      int data[TraversalPacketSize];
     };
-    
+
     
///////////////////////////////////////////////////////////////////////////
-    // PACKED TRIANGLES  PACKED TRIANGLES  PACKED TRIANGLES  PACKED TRIANGLES
     
///////////////////////////////////////////////////////////////////////////
-    class PackedTriangles {
-      VArray<Pointf> *_v0;
-      VArray<Pointf> *_v1;
-      VArray<Pointf> *_v2;
-      VArray<int>    *_payload;
-    public:
-      void pack(VArray<Triangle> *tris);
-      Pointf& getV0(int i) { return _v0->_get(i); }
-      Pointf& getV1(int i) { return _v1->_get(i); }
-      Pointf& getV2(int i) { return _v2->_get(i); }
-      int&    getPayload(int i) { return _payload->_get(i); }
-    };
-
-
+    // MASK OPERATORS  MASK OPERATORS  MASK OPERATORS  MASK OPERATORS  MASK 
OPE
     
///////////////////////////////////////////////////////////////////////////
-    // Swap the endianness of a variable.
-    template< typename T >
-    T endian_swap( T in ) {
-      T out;
-      char *pin = (char *)&in;
-      char *pout = (char *)&out;
-
-      for (int i=0;i<sizeof(T);++i) {
-        pout[i] = pin[sizeof(T)-1-i];
+    
///////////////////////////////////////////////////////////////////////////   
 
+    
+    static inline void set_lte( Mask &result, float 
vec[TraversalPacketSize], float scalar ) {
+      for (int p=0;p<TraversalPacketSize;++p) {
+        result[p] = (vec[p] <= scalar);
       }
-
-      return out;
     }
 
-    // Check the endianness of this machine.
-    inline bool is_big_endian() {
-
-      unsigned int x = 0x00112233;
-      char *p = (char *)&x;
-
-      return (p[0] == 0x00);
+    static inline void set_gte( Mask &result, float 
vec[TraversalPacketSize], float scalar ) {
+      for (int p=0;p<TraversalPacketSize;++p) {
+        result[p] = (vec[p] >= scalar);
+      }
     }
 
-    
///////////////////////////////////////////////////////////////////////////
-    // KDTREE INTERNAL NODE
-    
///////////////////////////////////////////////////////////////////////////
-    struct KDTreeInternalNode {
-      unsigned char flags;
-      unsigned int left;
-      float split;
-
-      void endian_swap() {
-        left  = Manta::Kdtree::endian_swap( left );
-        split = Manta::Kdtree::endian_swap( split );
+    static inline void set_gt( Mask &result, float 
vec0[TraversalPacketSize], float vec1[TraversalPacketSize] ) {
+      for (int p=0;p<TraversalPacketSize;++p) {
+        result[p] = (vec0[p] > vec1[p]);
       }
-    };
+    }
 
-    
///////////////////////////////////////////////////////////////////////////
-    // KDTREE LEAF NODE
-    
///////////////////////////////////////////////////////////////////////////
-    struct KDTreeLeafNode {
-      unsigned char flags;
-      unsigned int listBegin;
-      unsigned int listLen;
-
-      void endian_swap() {
-        listBegin = Manta::Kdtree::endian_swap( listBegin );
-        listLen   = Manta::Kdtree::endian_swap( listLen   );
+    static inline void set_and( Mask &result, const Mask &vec0, const Mask 
&vec1 ) {
+      for (int p=0;p<TraversalPacketSize;++p) {
+        result[p] = (vec0[p] && vec1[p]);
       }
-    };
-
-    
///////////////////////////////////////////////////////////////////////////
-    // KDTREE NODE
-    
///////////////////////////////////////////////////////////////////////////
-    union KDTreeNode {
-      KDTreeInternalNode internal;
-      KDTreeLeafNode leaf;
+    }
 
-      bool hasLeftChild()  const {
-        return internal.flags & KDNODE_LEFT_CHILD_MASK;
-      }
-      bool hasRightChild() const {
-        return internal.flags & KDNODE_RIGHT_CHILD_MASK;
-      }
-      KDTreeNode* left()   { return hasLeftChild()?this+internal.left : 
NULL; }
-      KDTreeNode* right()  {
-        return hasRightChild()?
-          (hasLeftChild()?this+internal.left+1:this+internal.left) : 0;
+    static inline bool all( const Mask &active, const Mask &mask ) {
+      bool result = mask[0];
+      for (int p=1;p<TraversalPacketSize;++p) {
+        result = result && (mask[p] || (!active[p]));
       }
+      return result;
+    }
 
-      KDTreeNode *getChild( short int i ) {
-        return this + internal.left +
-          (i & ((internal.flags&KDNODE_LEFT_CHILD_MASK) >> 3));
-      };
-      
-      float split()        const { return internal.split; }
-      bool isInternal()    const {
-        return internal.flags & KDNODE_INTERNAL_MASK;
+    static inline bool any( const Mask &mask ) {
+      bool result = mask[0];
+      for (int p=1;p<TraversalPacketSize;++p) {
+        result = (result || mask[p]);
       }
-      unsigned int axis()  const { return internal.flags & KDNODE_AXIS_MASK; 
}
-
-      unsigned int listBegin() { return leaf.listBegin; }
-      unsigned int listSize()  { return leaf.listLen; }
-
-      void endian_swap() {
-
-        internal.endian_swap();
+    }
 
-        if (hasLeftChild())
-          left()->endian_swap();
-        if (hasRightChild())
-          right()->endian_swap();
-      }
-    };
+    static inline bool none( const Mask &mask ) {
+      return !any( mask );
+    }
 
     
///////////////////////////////////////////////////////////////////////////
-    // RAY HIT TRIANGLE
     
///////////////////////////////////////////////////////////////////////////
-    class RayHit_Triangle {
+    // INTERSECT PACKET  INTERSECT PACKET  INTERSECT PACKET  INTERSECT 
PACKET  
+    
///////////////////////////////////////////////////////////////////////////
+    
///////////////////////////////////////////////////////////////////////////
+    class IntersectPacket {
     public:
+      Mask  active_mask;
+      Mask  hit_mask;
 
-      Real t, u, v;
-
-      RayHit_Triangle() {
-      }
-
-      RayHit_Triangle(Real tt, Real uu, Real vv) {
-        t = tt; u = uu; v = vv;
-      }
-      void computeHitPoint(Point &hitP,
-                           const Point &v0, const Point &v1, const Point &v2)
-      {
-        hitP = Point( Vector(v0)*((Real)1.0 - u - v) +
-                      Vector(v1)*u +
-                      Vector(v2)*v );
-      }
-
-      Real computeDistance2(const Ray &ray,
-                            const Point &v0, const Point &v1, const Point 
&v2)
-      {
-        Point hitP;
-        computeHitPoint( hitP, v0, v1, v2 );
-
-        Vector distance = (hitP - ray.origin());
-        return Dot(distance,distance);
-      }
+      int   hit_index[TraversalPacketSize];
 
-      Real computeDistance2(const Point &point,
-                            Point &v0, const Point &v1, const Point &v2)
-      {
-        Point hitP;
-        computeHitPoint(hitP, v0, v1, v2);
+      float t[TraversalPacketSize];
+      float u[TraversalPacketSize];
+      float v[TraversalPacketSize];
 
-        Vector distance = (hitP - point);
-        return Dot(distance,distance);
-      }
-    };
-
-
-    
///////////////////////////////////////////////////////////////////////////
-    // RAY TRIANGLE INTERSECT USER DATA
-    
///////////////////////////////////////////////////////////////////////////
-    struct RayTriIntersectUserData {
-      int rayHitTriIndex;
-      RayHit_Triangle rayHit;
-      float eyeToHitDist2;
-      int duplicate;
+      IntersectPacket( const Mask &active_mask_ )
+        : active_mask( active_mask_ ) { };
     };
 
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
-    // KDTREE CLASS PROPER
+    // VERTICAL KDTREE CLASS PROPER
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
-    class KDTree : public PrimitiveCommon {
+    class VerticalKDTree : public PrimitiveCommon {
+    public:
+      typedef KDTree::ScratchPadInfo ScratchPadInfo;
 
-      // Transparent KDTree will use data owned by this kdtree.
-      friend class TransparentKDTree;
+      
/////////////////////////////////////////////////////////////////////////
+      // Constructor.
+      VerticalKDTree( KDTree *kdtree_, Material *material_ );      
+      virtual ~VerticalKDTree();
 
-      // The Kdtree::load(...) function is used to load data into the kdtree.
-      friend int Manta::Kdtree::load( KDTree *kdtree, const char *filename,
-                                      int np );
+      
/////////////////////////////////////////////////////////////////////////
+      // Primitive Interface.
+      virtual void intersect(const RenderContext& context, RayPacket& rays) 
const;
+      void computeNormal (const RenderContext& context, RayPacket& rays) 
const;
+      void computeBounds (const PreprocessContext&, BBox &box_ ) const;
+      void computeBounds ( BBox &box_ ) const;
 
-    protected:
+      
/////////////////////////////////////////////////////////////////////////
+      // Accessors.
+      void        setRootNode( KDTreeNode *node ) { rootNode = node; };
+      KDTreeNode *getRootNode()                   { return rootNode; };      
+      
+    private:
       BBox bbox;
       KDTreeNode       *rootNode;
 
-    private:
       VArray<int>      *triIndices;
       VArray<Triangle> *tris;
       TriangleNormal   *normals;
@@ -303,106 +189,29 @@
                        VArray<int> *triToGroupMap;
                        VArray<int> *groupToNameMap;
                        VArray<char> *groupNames;
-                       bool __pickingEnabled;
-                       bool pickingEnabled;
-                       mutable long long pickedTri;
-                       mutable int pickedBeginIndex, pickedEndIndex;
-                       VArray<Color> pickedSavedColors;
                        VArray<unsigned char> *triFlags;
-                       unsigned char pickedFlag;
-               public:
-                       enum {
-                               PICK_HIGHLIGHT = 1,
-                               PICK_REMOVE = 2,
-                       };
-
-                       void enablePicking() {
-                               if (__pickingEnabled)
-                                       pickingEnabled = true;
-                       }
-                       void disablePicking() { pickingEnabled = false; }
-                       bool isPickingEnabled() const { return 
pickingEnabled&&__pickingEnabled; }
-                       void resetPicking() { 
-                               pickedTri = -1; 
-                               triFlags->clear();
-                       }
-                       void __setPicking(bool flag) { __pickingEnabled = 
flag; }
-
-                       void setPickedFlag(unsigned char flag) { pickedFlag = 
flag; }
-                       unsigned char getPickedFlag() { return pickedFlag; }
-
-    protected:
-      // Copy data pointers from another kdtree. (Used by derived classes.)
-      KDTree( KDTree *kdtree_, Material *material_ ) :
-        PrimitiveCommon( material_ ),
-        rootNode( kdtree_->rootNode ), triIndices( kdtree_->triIndices ),
-        tris( kdtree_->tris ), normals( kdtree_->normals )
-      {
-        bbox.extendByBox( bbox );
-               pickedFlag = PICK_HIGHLIGHT;
-      }
 
-      // This method intersects a list of triangles with the ray.
-      int intersectTriangles(const Pointf& origin, const Vectorf& direction,
-                             unsigned int listBegin, unsigned int listSize,
-                             float maxDist,
-                             RayTriIntersectUserData &isectData) const;
+      // This method intersects a list of triangles with the rays.
+      void intersectTriangles(IntersectPacket &intersect_packet,
+                         const RayPacket &rays,
+                         int which,
+                         unsigned int listBegin,
+                         unsigned int listSize ) const;
 
       // This method is called to intersect a single ray with the kdtree.
+      void intersect_node( const RenderContext &context,
+                           const Mask &valid_mask,
+                           RayPacket &rays,
+                           int which,
+                           float minDist[TraversalPacketSize],
+                           float maxDist[TraversalPacketSize] ) const;
+      
       void intersect_node( KDTreeNode *startNode,
                            RayPacket& rays, int which,
                            RayTriIntersectUserData &isectData,
                            const RenderContext &context,
                            float minDist, float maxDist) const;
 
-    public:
-      // Constructor.
-      KDTree( Material *material_ ) : PrimitiveCommon( material_ ) {  
-                 __pickingEnabled = true;
-                 pickingEnabled = false;
-                 pickedTri = -1;
-                 pickedFlag = PICK_HIGHLIGHT;
-         };
-
-      // This structure is used to record info about the hit.
-      struct ScratchPadInfo {
-        Vector normal; // Normal of the intersected face.
-        Color payload; // Payload of the intersected face.
-        Real a, b, c;
-      };
-
-      virtual ~KDTree() {}
-
-      // Primitive Interface.
-      virtual void intersect(const RenderContext& context, RayPacket& rays) 
const;
-      void computeNormal (const RenderContext& context, RayPacket& rays) 
const;
-      void computeBounds (const PreprocessContext& /*context*/,
-                          BBox &box_ ) const
-      {
-        box_.extendByBox( bbox );
-      }
-      void computeBounds ( BBox &box_ ) const { box_.extendByBox( bbox ); }
-
-      // This function is called to load the data.
-      // np specifies the number of workers, for certain loading functions.
-      int load( const char *fn, int np );
-
-      // Accessors (used by gui to examine kdtree).
-      void        setRootNode( KDTreeNode *node ) { rootNode = node; };
-      KDTreeNode *getRootNode()                   { return rootNode; };
-      
-    };
-
-    
///////////////////////////////////////////////////////////////////////////
-    
///////////////////////////////////////////////////////////////////////////
-    // KDTREE TEXTURE (For extracting color information from the kdtree
-    // scratch pad.
-    
///////////////////////////////////////////////////////////////////////////
-    
///////////////////////////////////////////////////////////////////////////
-    class KDTreeTexture : public Texture<Color> {
-    public:
-      virtual void mapValues(const RenderContext& context, RayPacket& rays,
-                             Color results[]) const;
     };
 
   } // end namespace Kdtree

Modified: trunk/scenes/boeing777.cc
==============================================================================
--- trunk/scenes/boeing777.cc   (original)
+++ trunk/scenes/boeing777.cc   Mon Jan 23 03:08:54 2006
@@ -5,7 +5,7 @@
  
  Copyright (c) 2005
  Silicon Graphics Inc. Mountain View California.

+
  License for the specific language governing rights and limitations under
  Permission is hereby granted, free of charge, to any person obtaining a
  copy of this software and associated documentation files (the "Software"),
@@ -46,6 +46,7 @@
 #include <Model/Groups/Group.h>
 #include <Model/Groups/KDTree.h>
 #include <Model/Groups/TransparentKDTree.h>
+#include <Model/Groups/VerticalKDTree.h>
 #include <Model/Lights/PointLight.h>
 #include <Model/Lights/HeadLight.h>
 #include <Model/Materials/Lambertian.h>
@@ -75,6 +76,7 @@
 
 enum CuttingPlaneType { CUTTING_NONE, CUTTING_DEFAULT, CUTTING_SPECIFIED };
 enum MtlType          { MTL_PHONG, MTL_AMBIENT, MTL_FLAT };
+enum TraversalType    { TRAVERSAL_SINGLE, TRAVERSAL_VERTICAL };
 
 ///////////////////////////////////////////////////////////////////////////
 // This function constructs the Boeing 777 Test Scene using a KdTree.
@@ -90,6 +92,8 @@
        int workers_np = 1;
        
   MtlType material_type = MTL_PHONG;
+
+  TraversalType traversal = TRAVERSAL_SINGLE;
   
        Real alpha = 1;
   Real ambient_dist = 5;
@@ -115,7 +119,6 @@
                else if (args[i] == "-alpha") {
     
       // Note this just specifies that a TransparentKDTree should be created 
as well.
-    
                        use_transparency = true;
                        if (!getArg<Real>(i, args, alpha ))
                                throw IllegalArgument("boeing777 -alpha 
<alpha>", i, args);
@@ -150,16 +153,20 @@
     else if (args[i] == "-bg") {
       bg_method = args[++i];
     }
+    else if (args[i] == "-vertical") {
+      traversal = TRAVERSAL_VERTICAL; 
+    }
                else {
                        cerr << "Valid options for boeing777:" << endl;
                        cerr << "-file <filename>"             << endl;
                        cerr << "-np   <num build workers>"    << endl;
                        cerr << "-cutting [<point> <normal>]"  << endl;
                        cerr << "-alpha <alpha>"               << endl;
-      cerr << "-lambertianalt (alpha=1.0 without transparent traversal)" << 
endl;
       cerr << "-phong <exp> <reflection> **default**" << endl;
       cerr << "-ambient <max dist> <secondary rays>"  << endl;
       cerr << "-bg marble  Currently only marble is supported.\n";
+      cerr << "-flat\n";
+      cerr << "-vertical -- Use vertical traversal code.\n";
       
                        throw IllegalArgument( "boeing777", i, args );
                }
@@ -209,16 +216,21 @@
        
        // Determine if we should start with a transparent kdtree or not.
        Primitive *kd_primitive = kdtree;
-       if (use_transparency) {
-               TransparentKDTree *transparent = new TransparentKDTree( 
kdtree,
-                                                            // Just copy the 
color out of the
-                                                            // hit info.
-                                                            new Flat( new 
KDTreeTexture ) );
-               transparent->setAlpha( alpha );
-               kd_primitive = transparent;
-       }
-  
-       
+  if (traversal == TRAVERSAL_SINGLE) {
+    if (use_transparency) {
+      TransparentKDTree *transparent = new TransparentKDTree( kdtree,
+                                                              // Just copy 
the color out of the
+                                                              // hit info.
+                                                              new Flat( new 
KDTreeTexture ) );
+      transparent->setAlpha( alpha );
+      kd_primitive = transparent;
+    }
+  }
+  else if (traversal == TRAVERSAL_VERTICAL) {
+    // Create a vertical kdtree.
+    kd_primitive = new VerticalKDTree( kdtree, kd_material );
+  }
+       
        
////////////////////////////////////////////////////////////////////////////
        // Compute the middle of the model for a cutting plane.
        if (cutting_type == CUTTING_DEFAULT) {




  • [MANTA] r860 - in trunk: Core/Geometry Interface Model/Groups scenes, abe, 01/23/2006

Archive powered by MHonArc 2.6.16.

Top of page