Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[Manta] r1668 - in trunk: Core/Util Engine/Control Engine/Renderers Interface Maya Model/Cameras Model/Groups Model/Groups/private Model/Instances Model/Materials Model/MiscObjects Model/Primitives scenes


Chronological Thread 
  • From: boulos@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [Manta] r1668 - in trunk: Core/Util Engine/Control Engine/Renderers Interface Maya Model/Cameras Model/Groups Model/Groups/private Model/Instances Model/Materials Model/MiscObjects Model/Primitives scenes
  • Date: Mon, 20 Aug 2007 17:26:43 -0600 (MDT)

Author: boulos
Date: Mon Aug 20 17:26:40 2007
New Revision: 1668

Modified:
   trunk/Core/Util/Preprocessor.h
   trunk/Engine/Control/RTRT.cc
   trunk/Engine/Control/RTRT.h
   trunk/Engine/Renderers/NullRenderer.cc
   trunk/Interface/AccelerationStructure.h
   trunk/Interface/CMakeLists.txt
   trunk/Interface/Context.h
   trunk/Interface/RayPacket.cc
   trunk/Interface/RayPacket.h
   trunk/Maya/MayaScene.cc
   trunk/Model/Cameras/EnvironmentCamera.cc
   trunk/Model/Cameras/FisheyeCamera.cc
   trunk/Model/Cameras/OrthogonalCamera.cc
   trunk/Model/Cameras/PinholeCamera.cc
   trunk/Model/Groups/BVH.cc
   trunk/Model/Groups/DynBVH.cc
   trunk/Model/Groups/DynBVH.h
   trunk/Model/Groups/GriddedGroup.cc
   trunk/Model/Groups/Group.cc
   trunk/Model/Groups/Mesh.cc
   trunk/Model/Groups/RealisticBvh.cc
   trunk/Model/Groups/private/CGT.cc
   trunk/Model/Groups/private/CGT.h
   trunk/Model/Instances/Instance.cc
   trunk/Model/Materials/LitMaterial.cc
   trunk/Model/MiscObjects/CuttingPlane.cc
   trunk/Model/MiscObjects/KeyFrameAnimation.cc
   trunk/Model/Primitives/GridSpheres.cc
   trunk/Model/Primitives/ParticleBVH.cc
   trunk/Model/Primitives/WaldTriangle.cc
   trunk/scenes/primtest.cc
Log:

Core/Util/Preprocessor.h

  Adding a MANTA_FUNC to help

Engine/Control/RTRT.cc
Engine/Control/RTRT.h
Engine/Renderers/NullRenderer.cc
Interface/AccelerationStructure.h
Interface/CMakeLists.txt
Interface/Context.h
Interface/RayPacket.cc
Interface/RayPacket.h
Model/Cameras/EnvironmentCamera.cc
Model/Cameras/FisheyeCamera.cc
Model/Cameras/OrthogonalCamera.cc
Model/Cameras/PinholeCamera.cc
Model/Groups/BVH.cc
Model/Groups/DynBVH.cc
Model/Groups/DynBVH.h
Model/Groups/GriddedGroup.cc
Model/Groups/Group.cc
Model/Groups/Mesh.cc
Model/Groups/RealisticBvh.cc
Model/Groups/private/CGT.cc
Model/Groups/private/CGT.h
Model/Instances/Instance.cc
Model/Materials/LitMaterial.cc
Model/MiscObjects/CuttingPlane.cc
Model/MiscObjects/KeyFrameAnimation.cc
Model/Primitives/GridSpheres.cc
Model/Primitives/ParticleBVH.cc
Model/Primitives/WaldTriangle.cc

 Updating the preprocess context to eventually support parallelism.
 We're going to need to make sure it's easy to use correctly.
 AccelerationStructures also now have a setGroup instead of telling
 rebuild to use a new group.

scenes/primtest.cc

 Removing the manual WaldTriangle::update call as this should be taken
 care of during a preprocess phase.


Modified: trunk/Core/Util/Preprocessor.h
==============================================================================
--- trunk/Core/Util/Preprocessor.h      (original)
+++ trunk/Core/Util/Preprocessor.h      Mon Aug 20 17:26:40 2007
@@ -1,8 +1,13 @@
 #ifndef MANTA_CORE_UTIL_PREPROCESSOR_H_
 #define MANTA_CORE_UTIL_PREPROCESSOR_H_
 
-// NOTE(boulos): ISO C99 defines _Pragma to let you do this.
+#if defined(__GNUC__)
+#define MANTA_FUNC __PRETTY_FUNCTION__
+#else
+#define MANTA_FUNC __func__
+#endif
 
+// NOTE(boulos): ISO C99 defines _Pragma to let you do this.
 #define MANTA_PRAGMA(str) _Pragma (#str)
 
 #if defined(__INTEL_COMPILER)

Modified: trunk/Engine/Control/RTRT.cc
==============================================================================
--- trunk/Engine/Control/RTRT.cc        (original)
+++ trunk/Engine/Control/RTRT.cc        Mon Aug 20 17:26:40 2007
@@ -207,7 +207,7 @@
 
   if(whence == MantaInterface::Relative) {
     frame += animFrameState.frameNumber;
-       }
+        }
   // #endif
 
   oneShots.insert(OneShotMapType::value_type(frame, callback));
@@ -221,7 +221,7 @@
 
   if(whence == MantaInterface::Relative) {
     frame += animFrameState.frameNumber;
-       }
+        }
 
   parallelOneShots.insert(OneShotMapType::value_type(frame, callback));
   callbackLock.writeUnlock();
@@ -381,7 +381,7 @@
   NOT_FINISHED("RTRT::setTimeMode");
 }
 
-#define MANTA_CHECK_POINTER(ptr) if (ptr == 0) throw SCIRun::InvalidState( 
#ptr, __FILE__, __LINE__ ); 
+#define MANTA_CHECK_POINTER(ptr) if (ptr == 0) throw SCIRun::InvalidState( 
#ptr, __FILE__, __LINE__ );
 
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
@@ -398,38 +398,6 @@
   running=true;
   runningLock.unlock();
 
-  // Preprocess
-  MANTA_CHECK_POINTER(scene)
-  
-  LightSet* lights = scene->getLights();
-  MANTA_CHECK_POINTER(lights)
-  
-  
-  PreprocessContext context(this, lights);
-  lights->preprocess(context);
-
-  MANTA_CHECK_POINTER(scene->getBackground())
-  scene->getBackground()->preprocess(context);
-
-  MANTA_CHECK_POINTER(scene->getObject())
-  scene->getObject()->preprocess(context);
-  
-  for(int index = 0;index < static_cast<int>(channels.size());index++){
-    Channel* channel = channels[index];
-    MANTA_CHECK_POINTER(channel)
-    
-    channel->camera->preprocess(context);
-    MANTA_CHECK_POINTER(channel->camera)
-  }
-
-  // Check to see if an image creator has been specified.
-  if(create_image==0)
-    throw InvalidState("Image type was not selected", __FILE__, __LINE__ );
-
-#if NOTFINISHED
-  check for existence of other components;
-#endif
-
   if(workersWanted <= 0){
     runningLock.unlock();
     throw IllegalValue<int>("workersWanted should be positive", 
workersWanted);
@@ -448,12 +416,12 @@
   changedFlags.resize(workersWanted);
 
   // Initialize random number generators.
-  if (create_rng) {  
+  if (create_rng) {
     for (int i=0;i<workersWanted;++i) {
       create_rng->call(rngs[i]);
-    }    
+    }
   }
-  
+
   // Startup rendering threads.
   for(int i=0;i<workersWanted;i++){
     if(i>0 || !blockUntilFinished){
@@ -464,11 +432,11 @@
                    0, Thread::NotActivated);
       t->setStackSize(RENDER_THREAD_STACKSIZE);
       t->activate(false);
-    }      
+    }
   }
 
   // All rendering threads active.
-  
+
   // Block until finished is set while running in bin/manta
   if(blockUntilFinished)
     internalRenderLoop(0, false);
@@ -482,6 +450,32 @@
   workers[0]->join();
 }
 
+void RTRT::doPreprocess(int proc, int numProcs) {
+  // Preprocess
+  MANTA_CHECK_POINTER(scene)
+
+  LightSet* lights = scene->getLights();
+  MANTA_CHECK_POINTER(lights)
+
+  PreprocessContext context(this, proc, numProcs, lights);
+  lights->preprocess(context);
+
+  MANTA_CHECK_POINTER(scene->getBackground())
+  scene->getBackground()->preprocess(context);
+
+  cerr << "About to preprocess the scene (proc " << proc << ")...\n";
+  MANTA_CHECK_POINTER(scene->getObject())
+  scene->getObject()->preprocess(context);
+
+  for(int index = 0;index < static_cast<int>(channels.size());index++){
+    Channel* channel = channels[index];
+    MANTA_CHECK_POINTER(channel)
+
+    channel->camera->preprocess(context);
+    MANTA_CHECK_POINTER(channel->camera)
+  }
+}
+
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
 // MAIN RENDERING LOOP
@@ -497,9 +491,9 @@
 #endif
 
   // Disables denormal handling and set flush to zero
-  int oldMXCSR = _mm_getcsr(); //read the old MXCSR setting 
-  int newMXCSR = oldMXCSR | _MM_FLUSH_ZERO_ON | _MM_DENORM_ZERO_ON; // set 
DAZ and FZ bits 
-  _mm_setcsr( newMXCSR ); //write the new MXCSR setting to the MXCSR 
+  int oldMXCSR = _mm_getcsr(); //read the old MXCSR setting
+  int newMXCSR = oldMXCSR | _MM_FLUSH_ZERO_ON | _MM_DENORM_ZERO_ON; // set 
DAZ and FZ bits
+  _mm_setcsr( newMXCSR ); //write the new MXCSR setting to the MXCSR
 #endif
 
   bool changed = true;
@@ -508,6 +502,22 @@
     firstFrame = false;
     goto skipToRendering;
   }
+
+  // Check to see if an image creator has been specified.
+  if(create_image==0)
+    throw InvalidState("Image type was not selected", __FILE__, __LINE__ );
+
+#if NOTFINISHED
+  check for existence of other components;
+#endif
+
+  // TODO(boulos): Go through and ask each thread to preprocess the
+  // scene.  For now, only thread 0 will do this and pretend there is
+  // only a single thread to emulate the old behavior until we can
+  // ensure everything is thread-safe throughout the tree.
+  if (proc == 0)
+    doPreprocess(proc, 1);
+
   for(;;){
     // P0 update frame number, time, etc.
     if(proc == 0){
@@ -647,7 +657,7 @@
 
         // Allocate thread local storage for each thread.
         thread_storage->allocateStorage( proc );
-        
+
         for(size_t index = 0;index < channels.size();index++){
           Channel* channel = channels[index];
           RenderContext myContext(this, index, proc, workersAnimAndImage,
@@ -688,7 +698,7 @@
         }
         workers.resize(workersRendering == 0?1:workersRendering);
       }
-      
+
       if(proc >= workersRendering) {
 
         // If proc 0 is exiting invoke the termination callbacks.
@@ -700,7 +710,7 @@
           running = false;
           runningLock.unlock();
         }
-        
+
         break;
       }
     }
@@ -745,7 +755,7 @@
 
 #ifdef MANTA_SSE
   // Restore floating point register flags
-  _mm_setcsr( oldMXCSR ); //write the new MXCSR setting to the MXCSR 
+  _mm_setcsr( oldMXCSR ); //write the new MXCSR setting to the MXCSR
 #endif
 }
 
@@ -755,7 +765,7 @@
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
 void RTRT::doParallelAnimationCallbacks(bool& changed, int proc, int 
numProcs) {
-  
+
   // Parallel one shot callbacks.
   ParallelOneShotMapType::iterator iter = parallelOneShots.begin();
   while(iter != parallelOneShots.end() && iter->first < 
animFrameState.frameNumber){
@@ -769,7 +779,7 @@
                                                   
&RTRT::deleteParallelOneShot,
                                                   iter ) );
     }
-    
+
     ++iter;
   }
 
@@ -832,7 +842,7 @@
 
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
-// POST TRANSACTIONS  
+// POST TRANSACTIONS
 
///////////////////////////////////////////////////////////////////////////////
 
///////////////////////////////////////////////////////////////////////////////
 void RTRT::postTransactions(bool& changed)
@@ -990,7 +1000,7 @@
   if (thread_storage != 0)
     delete thread_storage;
   thread_storage = new ThreadStorage( numProcs );
-  
+
   // Setup each channel.
   for(int index = 0;index < static_cast<int>(channels.size());index++){
     Channel* channel = channels[index];
@@ -1068,7 +1078,7 @@
     long which = frame%channel->pipelineDepth;
     bool stereo;
     int xres, yres;
-    
+
     if(channel->images[which])
       channel->images[which]->getResolution(stereo, xres, yres);
     if(!channel->images[which] || channel->stereo != stereo
@@ -1077,13 +1087,13 @@
       // Delete the image if it already exists.
       if(channel->images[which])
         delete channel->images[which];
-      
+
       // Invoke the create image callback.
       channel->create_image->call( channel->stereo,
                                    channel->xres,
                                    channel->yres,
                                    channel->images[which] );
-      
+
     } else {
       if (channel->pipelineDepth > 1)
         channel->images[which]->setValid(false);
@@ -1108,7 +1118,7 @@
 void RTRT::setImageDisplay( int channel, ImageDisplay *display ) {
 
   channels[channel]->display = display;
-  
+
   // Setup the image display with the pipeline.
   pipelineNeedsSetup = true;
 }
@@ -1214,7 +1224,7 @@
   currentShadowAlgorithm = shadows;
 }
 
-ShadowAlgorithm* RTRT::getShadowAlgorithm(void) const 
+ShadowAlgorithm* RTRT::getShadowAlgorithm(void) const
 {
   return currentShadowAlgorithm;
 }

Modified: trunk/Engine/Control/RTRT.h
==============================================================================
--- trunk/Engine/Control/RTRT.h (original)
+++ trunk/Engine/Control/RTRT.h Mon Aug 20 17:26:40 2007
@@ -67,19 +67,19 @@
     // Pipeline Components.
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
-    
+
     // Image Modes (opengl, file, mpeg, etc.)
     virtual int createChannel(ImageDisplay *image_display, Camera* camera, 
bool stereo, int xres, int yres);
 
     virtual ImageDisplay *getImageDisplay( int channel );
     virtual void setImageDisplay( int channel, ImageDisplay *display );
-    
+
     virtual Camera* getCamera(int channel) const;
-               virtual void    setCamera(int channel, Camera *camera );
+                virtual void    setCamera(int channel, Camera *camera );
 
     virtual void getResolution(int channel, bool& stereo, int& xres, int& 
yres);
     virtual void changeResolution(int channel, int xres, int yres, bool 
changePipeline);
-    
+
     // Image Traversers
     virtual void setImageTraverser( ImageTraverser *image_traverser_ );
     virtual ImageTraverser *getImageTraverser() const;
@@ -97,9 +97,9 @@
     virtual LoadBalancer *getLoadBalancer() const;
 
     // PixelSamplers
-               virtual void setPixelSampler( PixelSampler *sampler_ );
+                virtual void setPixelSampler( PixelSampler *sampler_ );
     virtual PixelSampler *getPixelSampler() const;
-    
+
     // Renderers
     virtual void setRenderer( Renderer *renderer_ );
     virtual Renderer* getRenderer() const;
@@ -111,10 +111,10 @@
     // Idle modes
     virtual IdleModeHandle addIdleMode( IdleMode *idle_mode );
     virtual IdleMode *getIdleMode( IdleModeHandle i ) const;
-    
+
     // Scenes
     virtual void setScene(Scene* scene);
-               virtual Scene *getScene();
+                virtual Scene *getScene();
 
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
@@ -127,13 +127,13 @@
 
     // Query functions
     virtual int getCurrentFrame() const { return animFrameState.frameNumber; 
};
-    
+
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
     // Control
     
///////////////////////////////////////////////////////////////////////////
-    
///////////////////////////////////////////////////////////////////////////   
 
-    
+    
///////////////////////////////////////////////////////////////////////////
+
     // Parallel processing
     virtual void changeNumWorkers(int workers);
     virtual TValue<int>& numWorkers();
@@ -142,13 +142,13 @@
     virtual void beginRendering(bool blockUntilFinished) throw 
(SCIRun::Exception &);
     virtual void blockUntilFinished();
     virtual void finish();
-    
+
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
     // Transactions
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
-    
+
     // Transactions
     virtual void addTransaction(TransactionBase* );
 
@@ -157,10 +157,10 @@
     // Callbacks.
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
-    
+
     // Callbacks
     virtual void addOneShotCallback(OneShotTime whence, FrameNumber frame, 
CallbackBase_2Data<int, int>* callback);
-    virtual void addParallelOneShotCallback(OneShotTime whence, FrameNumber 
frame, CallbackBase_2Data<int, int>* callback);    
+    virtual void addParallelOneShotCallback(OneShotTime whence, FrameNumber 
frame, CallbackBase_2Data<int, int>* callback);
 
     virtual CallbackHandle* registerSetupCallback(SetupCallback*);
     virtual CallbackHandle* 
registerSerialAnimationCallback(CallbackBase_3Data<int, int, bool&>*);
@@ -169,15 +169,15 @@
     virtual CallbackHandle* 
registerParallelPreRenderCallback(CallbackBase_2Data<int, int>*);
     virtual CallbackHandle* registerTerminationCallback( CallbackBase_1Data< 
MantaInterface *> *);
     virtual void unregisterCallback(CallbackHandle*);
-    
+
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
     // Debug
     
///////////////////////////////////////////////////////////////////////////
-    
///////////////////////////////////////////////////////////////////////////   
 
-    
-               // Debug:
-               virtual void shootOneRay( Color &result_color, RayPacket 
&result_rays, Real image_x, Real image_y, int channel_index );
+    
///////////////////////////////////////////////////////////////////////////
+
+                // Debug:
+                virtual void shootOneRay( Color &result_color, RayPacket 
&result_rays, Real image_x, Real image_y, int channel_index );
 
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
@@ -190,8 +190,8 @@
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
-       
-       protected:
+
+        protected:
     void internalRenderLoop(int workerIndex, bool lateComerFlag);
 
     
///////////////////////////////////////////////////////////////////////////
@@ -215,7 +215,7 @@
     };
     typedef vector<Channel*> ChannelListType;
     ChannelListType channels;
-    
+
     
///////////////////////////////////////////////////////////////////////////
     
///////////////////////////////////////////////////////////////////////////
     // Worker class for the RTRT Pipeline.
@@ -225,7 +225,7 @@
     public:
       Worker(RTRT* rtrt, int workerIndex, bool lateComerFlag);
       virtual ~Worker();
-      
+
       virtual void run();
     private:
       RTRT* rtrt;
@@ -237,7 +237,7 @@
     
///////////////////////////////////////////////////////////////////////////
     // Pipeline Configuration.
     
///////////////////////////////////////////////////////////////////////////
-    
///////////////////////////////////////////////////////////////////////////   
 
+    
///////////////////////////////////////////////////////////////////////////
 
     ImageTraverser*  currentImageTraverser;
     LoadBalancer*    currentLoadBalancer;
@@ -248,7 +248,7 @@
 
     CreateImageCallback* create_image;
     CreateRNGCallback*   create_rng;
-    
+
   private:
     RTRT(const RTRT&);
     RTRT& operator=(const RTRT&);
@@ -256,13 +256,14 @@
     // Callback Helpers.
     void doParallelAnimationCallbacks(bool& changed, int proc, int numProcs);
     void doSerialAnimationCallbacks(bool& changed, int proc, int numProcs);
-    
+
+    void doPreprocess(int proc, int numProcs);
     void doParallelPreRenderCallbacks(int proc, int numProcs);
     void doSerialPreRenderCallbacks(int proc, int numProcs);
 
     void doIdleModeCallbacks(bool changed, bool firstFrame, bool& 
pipelineNeedsSetup, int proc, int numProcs);
     void doTerminationCallbacks();
-    
+
     void resizeImages(long frameNumber);
     void setupPipelines(int numProcs);
 
@@ -294,7 +295,7 @@
 
     typedef multimap<long, CallbackBase_2Data<int, int>*, less<long> > 
OneShotMapType;
     typedef multimap<long, CallbackBase_2Data<int, int>*, less<long> > 
ParallelOneShotMapType;
-    
+
     OneShotMapType         oneShots;
     ParallelOneShotMapType parallelOneShots;
 
@@ -344,7 +345,7 @@
 
     // RandomNumberGenerator
     vector<RandomNumberGenerator*> rngs;
-    
+
     Scene* scene;
 
     SCIRun::Mutex channel_create_lock;

Modified: trunk/Engine/Renderers/NullRenderer.cc
==============================================================================
--- trunk/Engine/Renderers/NullRenderer.cc      (original)
+++ trunk/Engine/Renderers/NullRenderer.cc      Mon Aug 20 17:26:40 2007
@@ -53,7 +53,7 @@
   int b = (rays.rayBegin + 3) & (~3);
   int e = rays.rayEnd & (~3);
   RayPacketData* data = rays.data;
-  if(b == e){
+  if(b >= e){
     for(int i=rays.begin();i<rays.end();i++){
       rays.setColor(i, color);
     }
@@ -78,7 +78,7 @@
       data->color[2][i] = color[2];
     }
   }
-#else    
+#else
   for(int i=rays.begin();i<rays.end();i++){
     rays.setColor(i, color);
   }

Modified: trunk/Interface/AccelerationStructure.h
==============================================================================
--- trunk/Interface/AccelerationStructure.h     (original)
+++ trunk/Interface/AccelerationStructure.h     Mon Aug 20 17:26:40 2007
@@ -9,18 +9,26 @@
 
   class AccelerationStructure : public Object {
   public:
+    // Tell the acceleration structure that it's working on a new
+    // group.  However, you should not actually perform any
+    // "construction" work yet as that is reserved for the update and
+    // rebuild functions which are called during the preprocess phases
+    // of Manta.  setGroup can be called when "building" your scene.
+    virtual void setGroup(Group* new_group) = 0;
 
-    //TODO: decide whether we want a seperate rebuild and update
-    //function or let the acceleration structure decide which to use.
-
-    // NOTE(boulos): Due to a deadline this won't be done correctly
-    // requiring everyone to implement this until we get a chance to
-    // come back to it.
-    virtual void update(int proc=0, int numProcs=1) {}
-
-    virtual void rebuild(Group *group, int proc=0, int numProcs=1) = 0;
-    //virtual void update() = 0;
+    // update tells the acceleration structure that the underlying
+    // geometry has probably "moved" so that the bounds need to be
+    // updated. No actual changes in the amount of geometry has
+    // occurred (so do not call this function for that purpose).  For
+    // some data structures (e.g. a BVH) this can be more efficient
+    // than rebuilding. By default, however, this will be a call to
+    // rebuild.
+    virtual void update(int proc=0, int numProcs=1) {
+      rebuild(proc, numProcs);
+    }
 
+    // rebuild the data structure over the current group.
+    virtual void rebuild(int proc=0, int numProcs=1) = 0;
   };
 }
 #endif //Manta_Interface_AccelerationStructure_h

Modified: trunk/Interface/CMakeLists.txt
==============================================================================
--- trunk/Interface/CMakeLists.txt      (original)
+++ trunk/Interface/CMakeLists.txt      Mon Aug 20 17:26:40 2007
@@ -14,6 +14,7 @@
         Camera.h
         Clonable.h
         Context.h
+        Context.cc
         Fragment.h
         IdleMode.cc
         IdleMode.h

Modified: trunk/Interface/Context.h
==============================================================================
--- trunk/Interface/Context.h   (original)
+++ trunk/Interface/Context.h   Mon Aug 20 17:26:40 2007
@@ -2,6 +2,10 @@
 #ifndef Manta_Interface_Context_h
 #define Manta_Interface_Context_h
 
+namespace SCIRun {
+  class Barrier;
+};
+
 namespace Manta {
   class Camera;
   class FrameState;
@@ -16,7 +20,7 @@
   class XWindow;
   class ThreadStorage;
   class RandomNumberGenerator;
-  
+
   class ReadContext {
   public:
     ReadContext(MantaInterface* rtrt_int)
@@ -32,7 +36,7 @@
 
 
 
-  
+
   
/////////////////////////////////////////////////////////////////////////////
   // Setup context is used to configure rendering stack components.
 
@@ -46,7 +50,7 @@
                  LoadBalancer* loadBalancer,  PixelSampler* pixelSampler,
                  Renderer* renderer,
                  ThreadStorage *storage_allocator_ )
-      
+
       : rtrt_int(rtrt_int),
         channelIndex(channelIndex), numChannels(numChannels),
         proc(proc), numProcs(numProcs),
@@ -82,7 +86,7 @@
     LoadBalancer* loadBalancer;
     PixelSampler* pixelSampler;
     Renderer* renderer;
-    
+
     ThreadStorage *storage_allocator;
     mutable XWindow* masterWindow;
 
@@ -179,27 +183,34 @@
     const Scene* scene;
 
     mutable ThreadStorage *storage_allocator;
-    
+
     RandomNumberGenerator* rng;
   private:
     RenderContext(const RenderContext&);
     RenderContext& operator=(const RenderContext&);
   };
+
   class PreprocessContext {
   public:
-    PreprocessContext() {}
-    PreprocessContext(MantaInterface* manta_interface, LightSet* 
globalLights)
-      : manta_interface(manta_interface), globalLights(globalLights)
-    {
-    }
-    ~PreprocessContext()
-    {
-    }
+    PreprocessContext();
+    PreprocessContext(MantaInterface* manta_interface,
+                      int proc,
+                      int numProcs,
+                      LightSet* globalLights);
+    ~PreprocessContext();
+
+    // Call this when you're done changing your state values during a
+    // preprocess call.  It ensures that all the threads finish
+    // together.
+    void done() const;
 
     MantaInterface* manta_interface;
+    int proc;
+    int numProcs;
     LightSet* globalLights;
-
   private:
+    mutable SCIRun::Barrier* barrier;
+
     PreprocessContext(const PreprocessContext&);
     PreprocessContext& operator=(const PreprocessContext&);
   };

Modified: trunk/Interface/RayPacket.cc
==============================================================================
--- trunk/Interface/RayPacket.cc        (original)
+++ trunk/Interface/RayPacket.cc        Mon Aug 20 17:26:40 2007
@@ -2,6 +2,10 @@
 #include <Interface/RayPacket.h>
 #include <MantaSSE.h>
 
+#include <sgi_stl_warnings_off.h>
+#include <iostream>
+#include <sgi_stl_warnings_on.h>
+
 using namespace Manta;
 
 void RayPacket::actualNormalizeDirections()
@@ -9,7 +13,7 @@
 #ifdef MANTA_SSE
   int b = (rayBegin + 3) & (~3);
   int e = rayEnd & (~3);
-  if(b == e){
+  if(b >= e){
     for(int i=rayBegin;i<rayEnd;i++){
       Real sum = 0;
       for(int j=0;j<3;j++)
@@ -81,7 +85,7 @@
 #if MANTA_SSE
   int b = (rayBegin + 3) & (~3);
   int e = rayEnd & (~3);
-  if (b == e) {
+  if (b >= e) {
     for(int i=rayBegin;i<rayEnd;i++)
       for(int j=0;j<3;j++)
         data->inverseDirection[j][i] = (Real)1/data->direction[j][i];
@@ -113,35 +117,35 @@
 void RayPacket::actualComputeHitPositions()
 {
 #ifdef MANTA_SSE
-       int b = (rayBegin + 3) & (~3);
-       int e = rayEnd & (~3);
-       if(b == e){
-               for(int i = begin(); i < end(); i++){
-                       for(int j=0;j<3;j++)
-                               data->hitPosition[j][i] = data->origin[j][i] 
+ data->direction[j][i] * data->minT[i];
-               }
-       } else {
-               int i = rayBegin;
-               for(;i<b;i++){
-                       for(int j=0;j<3;j++)
-                               data->hitPosition[j][i] = data->origin[j][i] 
+ data->direction[j][i] * data->minT[i];
-               }
-               for(;i<e;i+=4){
-                       __m128 minT = _mm_load_ps(&data->minT[i]);
-                       _mm_store_ps(&data->hitPosition[0][i], 
_mm_add_ps(_mm_load_ps(&data->origin[0][i]), 
_mm_mul_ps(_mm_load_ps(&data->direction[0][i]), minT)));
-                       _mm_store_ps(&data->hitPosition[1][i], 
_mm_add_ps(_mm_load_ps(&data->origin[1][i]), 
_mm_mul_ps(_mm_load_ps(&data->direction[1][i]), minT)));
-                       _mm_store_ps(&data->hitPosition[2][i], 
_mm_add_ps(_mm_load_ps(&data->origin[2][i]), 
_mm_mul_ps(_mm_load_ps(&data->direction[2][i]), minT)));
-               }
-               for(;i<rayEnd;i++){
-                       for(int j=0;j<3;j++)
-                               data->hitPosition[j][i] = data->origin[j][i] 
+ data->direction[j][i] * data->minT[i];
-               }
-       }
+        int b = (rayBegin + 3) & (~3);
+        int e = rayEnd & (~3);
+        if(b >= e){
+                for(int i = begin(); i < end(); i++){
+                        for(int j=0;j<3;j++)
+                                data->hitPosition[j][i] = data->origin[j][i] 
+ data->direction[j][i] * data->minT[i];
+                }
+        } else {
+                int i = rayBegin;
+                for(;i<b;i++){
+                        for(int j=0;j<3;j++)
+                                data->hitPosition[j][i] = data->origin[j][i] 
+ data->direction[j][i] * data->minT[i];
+                }
+                for(;i<e;i+=4){
+                        __m128 minT = _mm_load_ps(&data->minT[i]);
+                        _mm_store_ps(&data->hitPosition[0][i], 
_mm_add_ps(_mm_load_ps(&data->origin[0][i]), 
_mm_mul_ps(_mm_load_ps(&data->direction[0][i]), minT)));
+                        _mm_store_ps(&data->hitPosition[1][i], 
_mm_add_ps(_mm_load_ps(&data->origin[1][i]), 
_mm_mul_ps(_mm_load_ps(&data->direction[1][i]), minT)));
+                        _mm_store_ps(&data->hitPosition[2][i], 
_mm_add_ps(_mm_load_ps(&data->origin[2][i]), 
_mm_mul_ps(_mm_load_ps(&data->direction[2][i]), minT)));
+                }
+                for(;i<rayEnd;i++){
+                        for(int j=0;j<3;j++)
+                                data->hitPosition[j][i] = data->origin[j][i] 
+ data->direction[j][i] * data->minT[i];
+                }
+        }
 #else
-       for(int i = rayBegin; i < rayEnd; i++){
-               for(int j=0;j<3;j++)
-                       data->hitPosition[j][i] = data->origin[j][i] + 
data->direction[j][i] * data->minT[i];
-       }
+        for(int i = rayBegin; i < rayEnd; i++){
+                for(int j=0;j<3;j++)
+                        data->hitPosition[j][i] = data->origin[j][i] + 
data->direction[j][i] * data->minT[i];
+        }
 #endif
   flags |= HaveHitPositions;
 }
@@ -222,4 +226,15 @@
   }
 
   flags |= HaveTexture3;
+}
+namespace Manta {
+  std::ostream& operator<< (std::ostream& os, const RayPacket& rays) {
+    for (int i = rays.begin(); i < rays.end(); i++) {
+      os << "ray_index " << i << " depth " << rays.getDepth() << " origin";
+      os << " " << rays.getOrigin(i) << " direction " << 
rays.getDirection(i);
+      os << " minT " << rays.getMinT(i) << " matl " << 
rays.getHitMaterial(i);
+      os << std::endl;
+    }
+    return os;
+  }
 }

Modified: trunk/Interface/RayPacket.h
==============================================================================
--- trunk/Interface/RayPacket.h (original)
+++ trunk/Interface/RayPacket.h Mon Aug 20 17:26:40 2007
@@ -48,9 +48,9 @@
 #include <Core/Math/SSEDefs.h>
 #endif
 
-// #include <sgi_stl_warnings_off.h>
-// #include <iostream>
-// #include <sgi_stl_warnings_on.h>
+#include <sgi_stl_warnings_off.h>
+#include <iosfwd>
+#include <sgi_stl_warnings_on.h>
 
 namespace Manta {
   class Material;
@@ -309,9 +309,9 @@
     }
 
     Real &getDirection(int which, int i)
-                       {
-                               return data->direction[i][which];
-                       }
+                        {
+                                return data->direction[i][which];
+                        }
     const Real &getDirection(int which, int i) const
     {
       return data->direction[i][which];
@@ -388,7 +388,7 @@
 #ifdef MANTA_SSE
       int b = (rayBegin + 3) & (~3);
       int e = rayEnd & (~3);
-      if(b == e){
+      if(b >= e){
         for(int i = rayBegin; i < rayEnd; i++){
           data->hitMatl[i] = 0;
           data->minT[i] = MAXT;
@@ -572,7 +572,7 @@
     }
     // No mask
     inline __m128 hit(int start, __m128 t, const Material* matl,
-                                                                             
          const Primitive* prim, const TexCoordMapper* tex) {
+                                                                             
           const Primitive* prim, const TexCoordMapper* tex) {
       __m128 mask = _mm_cmpgt_ps(t, _mm_set1_ps(T_EPSILON));
       return hitFinal(start, mask, t, matl, prim, tex);
     }
@@ -635,15 +635,15 @@
     {
       data->hitTex[which] = tex;
     }
-    const Material* getHitMaterial(int which)
+    const Material* getHitMaterial(int which) const
     {
       return data->hitMatl[which];
     }
-    const Primitive* getHitPrimitive(int which)
+    const Primitive* getHitPrimitive(int which) const
     {
       return data->hitPrim[which];
     }
-    const TexCoordMapper* getHitTexCoordMapper(int which)
+    const TexCoordMapper* getHitTexCoordMapper(int which) const
     {
       return data->hitTex[which];
     }
@@ -826,6 +826,7 @@
 
   typedef MANTA_ALIGN(16) Color::ComponentType 
ColorArray[Color::NumComponents][RayPacket::MaxSize];
 
+  std::ostream& operator<< (std::ostream& os, const RayPacket& rays);
 } // end namespace Manta
 
 #endif

Modified: trunk/Maya/MayaScene.cc
==============================================================================
--- trunk/Maya/MayaScene.cc     (original)
+++ trunk/Maya/MayaScene.cc     Mon Aug 20 17:26:40 2007
@@ -42,6 +42,7 @@
 #include <Image/NRRDFile.h>
 #include <Image/TGAFile.h>
 #include <Interface/AccelerationStructure.h>
+#include <Interface/Context.h>
 #include <Interface/LightSet.h>
 #include <Interface/MantaInterface.h>
 #include <Interface/Scene.h>
@@ -85,10 +86,10 @@
 using namespace MantaPlugin;
 
 #define USE_MANTA_MESH 1
-// Due to a current bug in Manta with instanced Meshes, we can't do
-// this yet
+// NOTE(boulos): Instances in Manta don't currently work quite right
+// (like normals and such...) so only use for debugging.
 #define USE_INSTANCES 0
-
+#define USE_REAL_ACCEL 1
 
 
 class MyMesh {
@@ -177,14 +178,22 @@
     mesh.engine = engine;
 
     Mesh* new_mesh = new Mesh();
+#if USE_REAL_ACCEL
     AccelerationStructure* mesh_accel = new DynBVH();
+#else
+    Group* mesh_accel = new Group();
+#endif
     status = mesh.setup(result, iter, new_mesh);
     MANTA_CHECK_STATUS_RETURN( status, me+"::setup()");
 
     mesh.processSets(result, new_mesh);
     MANTA_CHECK_STATUS_RETURN( status, me+"::processSets()");
 
-    mesh_accel->rebuild(new_mesh);
+#if USE_REAL_ACCEL
+    mesh_accel->setGroup(new_mesh);
+#else
+    mesh_accel->add(new_mesh);
+#endif
 
 #if USE_INSTANCES
     // TODO(boulos): Stick an instance around the mesh and use local
@@ -201,8 +210,7 @@
                                            mesh_transform);
 
     geometry->add(mesh_instance);
-    cerr << "Mesh Transform is " << mesh_transform << endl;
-    //geometry->add(mesh_accel);
+    cerr << "Mesh Transform is:\n " << mesh_transform << endl;
 #else
     geometry->add(mesh_accel);
 #endif
@@ -234,7 +242,8 @@
   scene->setLights( lights );
 
   // Process the geometry
-  toplevel_accel->rebuild(geometry);
+  cerr << "Assigning group to top level acceleration structure\n";
+  toplevel_accel->setGroup(geometry);
 
   status = MayaCamera::GetCamera(result, scene, engine);
   if (status.error()) {
@@ -293,7 +302,6 @@
 
     for(unsigned int i = 0; i < vertices.length(); ++i) {
       mesh->vertices.push_back(maya2manta(vertices[i]));
-      cerr << "Vertex " << i << " = " << mesh->vertices[i] << endl;
     }
     for(unsigned int i = 0; i < fNormalArray.length(); ++i) {
       mesh->vertexNormals.push_back(maya2manta(fNormalArray[i]));

Modified: trunk/Model/Cameras/EnvironmentCamera.cc
==============================================================================
--- trunk/Model/Cameras/EnvironmentCamera.cc    (original)
+++ trunk/Model/Cameras/EnvironmentCamera.cc    Mon Aug 20 17:26:40 2007
@@ -74,6 +74,11 @@
 
 void EnvironmentCamera::preprocess(const PreprocessContext& context)
 {
+  if (context.proc != 0) {
+    context.done();
+    return;
+  }
+
   Scene* scene = context.manta_interface->getScene();
   if(!haveCamera){
     const BasicCameraData* bookmark = scene->currentBookmark();
@@ -87,6 +92,8 @@
     }
     haveCamera = true;
   }
+
+  context.done();
 }
 
 void EnvironmentCamera::getBasicCameraData(BasicCameraData& cam) const

Modified: trunk/Model/Cameras/FisheyeCamera.cc
==============================================================================
--- trunk/Model/Cameras/FisheyeCamera.cc        (original)
+++ trunk/Model/Cameras/FisheyeCamera.cc        Mon Aug 20 17:26:40 2007
@@ -240,6 +240,11 @@
 
 void FisheyeCamera::preprocess(const PreprocessContext& context)
 {
+  if (context.proc != 0) {
+    context.done();
+    return;
+  }
+
   Scene* scene = context.manta_interface->getScene();
   if(!haveCamera){
     const BasicCameraData* bookmark = scene->currentBookmark();
@@ -254,4 +259,6 @@
     }
     haveCamera = true;
   }
+
+  context.done();
 }

Modified: trunk/Model/Cameras/OrthogonalCamera.cc
==============================================================================
--- trunk/Model/Cameras/OrthogonalCamera.cc     (original)
+++ trunk/Model/Cameras/OrthogonalCamera.cc     Mon Aug 20 17:26:40 2007
@@ -225,6 +225,11 @@
 
 void OrthogonalCamera::preprocess(const PreprocessContext& context)
 {
+  if (context.proc != 0) {
+    context.done();
+    return;
+  }
+
   Scene* scene = context.manta_interface->getScene();
   if(!haveCamera){
     const BasicCameraData* bookmark = scene->currentBookmark();
@@ -238,4 +243,6 @@
     }
     haveCamera = true;
   }
+
+  context.done();
 }

Modified: trunk/Model/Cameras/PinholeCamera.cc
==============================================================================
--- trunk/Model/Cameras/PinholeCamera.cc        (original)
+++ trunk/Model/Cameras/PinholeCamera.cc        Mon Aug 20 17:26:40 2007
@@ -439,6 +439,11 @@
 
 void PinholeCamera::preprocess(const PreprocessContext& context)
 {
+  if (context.proc != 0) {
+    context.done();
+    return;
+  }
+
   Scene* scene = context.manta_interface->getScene();
   if(!haveCamera){
     const BasicCameraData* bookmark = scene->currentBookmark();
@@ -457,4 +462,6 @@
     }
     haveCamera = true;
   }
+
+  context.done();
 }

Modified: trunk/Model/Groups/BVH.cc
==============================================================================
--- trunk/Model/Groups/BVH.cc   (original)
+++ trunk/Model/Groups/BVH.cc   Mon Aug 20 17:26:40 2007
@@ -2,6 +2,7 @@
 #include <Model/Groups/BVH.h>
 #include <Core/Util/Args.h>
 #include <Core/Exceptions/IllegalArgument.h>
+#include <Interface/Context.h>
 #include <Interface/RayPacket.h>
 #include <Core/Containers/StringUtil.h>
 #include <Core/Exceptions/InternalError.h>
@@ -65,6 +66,7 @@
 void BVH::preprocess(const PreprocessContext& context)
 {
   Group::preprocess(context);
+  if (context.proc != 0) { context.done(); return; }
 
   double start_time = Time::currentSeconds();
   int nprims = static_cast<int>(objs.size());
@@ -295,6 +297,7 @@
   //  throw InternalError("BVH tree corrupt");
   double dt = Time::currentSeconds()-start_time;
   stats << "BVH preprocessed " << nprims << " primitives in " << dt << " 
seconds, build mode is " << buildMode << '\n';
+  context.done();
 }
 
 #if 0

Modified: trunk/Model/Groups/DynBVH.cc
==============================================================================
--- trunk/Model/Groups/DynBVH.cc        (original)
+++ trunk/Model/Groups/DynBVH.cc        Mon Aug 20 17:26:40 2007
@@ -17,43 +17,50 @@
 
 void DynBVH::intersect(const RenderContext& context, RayPacket& rays) const
 {
-    rays.computeInverseDirections();
+  bool debugFlag = rays.getFlag(RayPacket::DebugPacket);
+  if (debugFlag) {
+    //cerr << __func__ << " called\n";
+    cerr << MANTA_FUNC << " called\n";
+    cerr << "Rays are : \n" << rays << endl;
+  }
+
+  rays.computeInverseDirections();
 #if USE_DYNBVH_PORTS
-    templatedTraverse(context, rays);
+  templatedTraverse(context, rays);
 #else
-    rays.computeSigns();
+  rays.computeSigns();
 
-    // compute IntervalArithmetic Data
-    IAData ia_data;
-    for (int axis = 0; axis < 3; axis++ )
+  // compute IntervalArithmetic Data
+  IAData ia_data;
+  for (int axis = 0; axis < 3; axis++ )
     {
-        ia_data.min_rcp[axis]     =  std::numeric_limits<float>::max();
-        ia_data.max_rcp[axis]     = -std::numeric_limits<float>::max();
-        ia_data.min_org[axis]     =  std::numeric_limits<float>::max();
-        ia_data.max_org[axis]     = -std::numeric_limits<float>::max();
-        ia_data.min_org_rcp[axis] =  std::numeric_limits<float>::max();
-        ia_data.max_org_rcp[axis] = -std::numeric_limits<float>::max();
+      ia_data.min_rcp[axis]     =  std::numeric_limits<float>::max();
+      ia_data.max_rcp[axis]     = -std::numeric_limits<float>::max();
+      ia_data.min_org[axis]     =  std::numeric_limits<float>::max();
+      ia_data.max_org[axis]     = -std::numeric_limits<float>::max();
+      ia_data.min_org_rcp[axis] =  std::numeric_limits<float>::max();
+      ia_data.max_org_rcp[axis] = -std::numeric_limits<float>::max();
     }
 
-    // TODO(boulos): provide an SSE version
-    for (int ray = rays.begin(); ray < rays.end(); ray++ )
+  // TODO(boulos): provide an SSE version
+  for (int ray = rays.begin(); ray < rays.end(); ray++ )
     {
-        for (int axis = 0; axis < 3; axis++)
+      for (int axis = 0; axis < 3; axis++)
         {
-            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;
-
-            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];
-
-            ia_data.min_org[axis] = (ia_data.min_org[axis] < new_org) ? 
ia_data.min_org[axis] : new_org;
-            ia_data.max_org[axis] = (ia_data.max_org[axis] < new_org) ? 
new_org : ia_data.max_org[axis];
-
-            ia_data.min_org_rcp[axis] = (ia_data.min_org_rcp[axis] < 
new_org_rcp) ?
-                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];
+          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;
+
+          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];
+
+          ia_data.min_org[axis] = (ia_data.min_org[axis] < new_org) ? 
ia_data.min_org[axis] : new_org;
+          ia_data.max_org[axis] = (ia_data.max_org[axis] < new_org) ? 
new_org : ia_data.max_org[axis];
+
+          ia_data.min_org_rcp[axis] = (ia_data.min_org_rcp[axis] < 
new_org_rcp) ?
+            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];
 
         }
     }
@@ -61,27 +68,27 @@
 #define USE_ASSERTED_PARENT 0
 
 #if USE_ASSERTED_PARENT
-    const BVHNode& root_node = nodes[0];
-    float tmin;
-    int firstActive = firstIntersects(root_node.bounds, rays, ia_data, 
&tmin);
-    if (firstActive != rays.end()) {
-        if (root_node.isLeaf()) {
-            int lastActive = lastIntersects(root_node.bounds, rays);
-            // build a subpacket from firstActive to lastActive (inclusive, 
hence +1)
-            RayPacket subpacket(rays, firstActive, lastActive+1);
+  const BVHNode& root_node = nodes[0];
+  float tmin;
+  int firstActive = firstIntersects(root_node.bounds, rays, ia_data, &tmin);
+  if (firstActive != rays.end()) {
+    if (root_node.isLeaf()) {
+      int lastActive = lastIntersects(root_node.bounds, rays);
+      // build a subpacket from firstActive to lastActive (inclusive, hence 
+1)
+      RayPacket subpacket(rays, firstActive, lastActive+1);
 
-            for (int i = 0; i < root_node.children; i++ )
-            {
-                const int object_id = object_ids[root_node.child+i];
-                currGroup->get(object_id)->intersect(context,subpacket);
-            }
-        } else {
-            RayPacket subpacket(rays, firstActive, rays.end());
-            intersectNode(root_node.child, context, subpacket, ia_data);
+      for (int i = 0; i < root_node.children; i++ )
+        {
+          const int object_id = object_ids[root_node.child+i];
+          currGroup->get(object_id)->intersect(context,subpacket);
         }
+    } else {
+      RayPacket subpacket(rays, firstActive, rays.end());
+      intersectNode(root_node.child, context, subpacket, ia_data);
     }
+  }
 #else
-    intersectNode(0,context,rays, ia_data);
+  intersectNode(0,context,rays, ia_data);
 #endif // asserted parent or not
 
 #endif // dynbvh port or not
@@ -89,78 +96,78 @@
 
 #if USE_ASSERTED_PARENT
 void DynBVH::intersectNode(int nodeID, const RenderContext& context, 
RayPacket& rays, const IAData& ia_data) const {
-    const BVHNode& left_node  = nodes[nodeID+0];
-    const BVHNode& right_node = nodes[nodeID+1];
-    float left_tmin, right_tmin;
-
-    int leftFirstActive  = firstIntersects(left_node.bounds,  rays, ia_data, 
&left_tmin);
-    int rightFirstActive = firstIntersects(right_node.bounds, rays, ia_data, 
&right_tmin);
-
-    const BVHNode* child_nodes[2] = { (left_tmin < right_tmin) ? &left_node  
: &right_node,
-                                      (left_tmin < right_tmin) ? &right_node 
: &left_node };
-    int firstActive[2] = { (left_tmin < right_tmin) ? leftFirstActive  : 
rightFirstActive,
-                           (left_tmin < right_tmin) ? rightFirstActive : 
leftFirstActive };
-
-    for (int which = 0; which < 2; ++which) {
-        if (firstActive[which] != rays.end()) {
-            const BVHNode* node = child_nodes[which];
-            if (node->isLeaf()) {
-                int lastActive = lastIntersects(node->bounds, rays);
-
-                // build a subpacket from firstActive to lastActive 
(inclusive, hence +1)
-                RayPacket subpacket(rays, firstActive[which], lastActive+1);
-
-                for (int i = 0; i < node->children; i++ )
-                {
-                    const int object_id = object_ids[node->child+i];
-                    currGroup->get(object_id)->intersect(context,subpacket);
-                }
-            } else {
-                RayPacket subpacket(rays, firstActive[which], rays.end());
-                intersectNode(node->child, context, subpacket, ia_data);
-            }
-        }
+  const BVHNode& left_node  = nodes[nodeID+0];
+  const BVHNode& right_node = nodes[nodeID+1];
+  float left_tmin, right_tmin;
+
+  int leftFirstActive  = firstIntersects(left_node.bounds,  rays, ia_data, 
&left_tmin);
+  int rightFirstActive = firstIntersects(right_node.bounds, rays, ia_data, 
&right_tmin);
+
+  const BVHNode* child_nodes[2] = { (left_tmin < right_tmin) ? &left_node  : 
&right_node,
+                                    (left_tmin < right_tmin) ? &right_node : 
&left_node };
+  int firstActive[2] = { (left_tmin < right_tmin) ? leftFirstActive  : 
rightFirstActive,
+                         (left_tmin < right_tmin) ? rightFirstActive : 
leftFirstActive };
+
+  for (int which = 0; which < 2; ++which) {
+    if (firstActive[which] != rays.end()) {
+      const BVHNode* node = child_nodes[which];
+      if (node->isLeaf()) {
+        int lastActive = lastIntersects(node->bounds, rays);
+
+        // build a subpacket from firstActive to lastActive (inclusive, 
hence +1)
+        RayPacket subpacket(rays, firstActive[which], lastActive+1);
+
+        for (int i = 0; i < node->children; i++ )
+          {
+            const int object_id = object_ids[node->child+i];
+            currGroup->get(object_id)->intersect(context,subpacket);
+          }
+      } else {
+        RayPacket subpacket(rays, firstActive[which], rays.end());
+        intersectNode(node->child, context, subpacket, ia_data);
+      }
     }
+  }
 }
 #else
 void DynBVH::intersectNode(int nodeID, const RenderContext& context, 
RayPacket& rays, const IAData& ia_data) const
 {
-    const BVHNode& node = nodes[nodeID];
-    float tmin;
-    int firstActive = firstIntersects(node.bounds, rays, ia_data, &tmin);
+  const BVHNode& node = nodes[nodeID];
+  float tmin;
+  int firstActive = firstIntersects(node.bounds, rays, ia_data, &tmin);
 
-    if (firstActive != rays.end())
+  if (firstActive != rays.end())
     {
-        if (node.isLeaf())
+      if (node.isLeaf())
         {
-            // we already know that one of the rays from begin to end
-            // hits the object, so lastActive is going to find something
-            // we need not create a subpacket to help it stop early
-
-            // actually if we're just one ray it'll look more than it
-            // needs to since it will reintersect the firstActive ray...
-            int lastActive = lastIntersects(node.bounds, rays);
+          // we already know that one of the rays from begin to end
+          // hits the object, so lastActive is going to find something
+          // we need not create a subpacket to help it stop early
+
+          // actually if we're just one ray it'll look more than it
+          // needs to since it will reintersect the firstActive ray...
+          int lastActive = lastIntersects(node.bounds, rays);
 
-            // build a subpacket from firstActive to lastActive (inclusive, 
hence +1)
-            RayPacket subpacket(rays, firstActive, lastActive+1);
+          // build a subpacket from firstActive to lastActive (inclusive, 
hence +1)
+          RayPacket subpacket(rays, firstActive, lastActive+1);
 
-            for (int i = 0; i < node.children; i++ )
+          for (int i = 0; i < node.children; i++ )
             {
-                const int object_id = object_ids[node.child+i];
+              const int object_id = object_ids[node.child+i];
 
-                currGroup->get(object_id)->intersect(context,subpacket);
+              currGroup->get(object_id)->intersect(context,subpacket);
             }
         }
-        else
+      else
         {
-            // make a subpacket from the (possibly) new firstActive to the 
current end
-            RayPacket subpacket(rays, firstActive, rays.end());
+          // make a subpacket from the (possibly) new firstActive to the 
current end
+          RayPacket subpacket(rays, firstActive, rays.end());
 
-            // recurse
-            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);
+          // recurse
+          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);
         }
     }
 }
@@ -169,153 +176,30 @@
 int DynBVH::firstIntersects(const BBox& box, const RayPacket& rays, const 
IAData& ia_data, float* out_tmin) const
 {
 #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(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;
-        }
-      }
-    } else {
-      int i = rays.rayBegin;
-      for(;i<b;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;
-        }
-
-        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;
-          }
+  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(i);
 
-          // frustum exit
-          if (tmin_frustum > tmax_frustum) {
-            return rays.end();
-          }
-        }
-      }
+      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);
 
-      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][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][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[i]))));
-        __m128 valid_intersect = 
_mm_cmple_ps(maximum_minimum,minimum_maximum);
-        if (_mm_movemask_ps(valid_intersect) != 0x0)
-            return i;
+        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
       }
-
-      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;
-        }
+      if (tmin <= tmax) {  // valid intersection
+        *out_tmin = tmin;
+        return i;
       }
     }
-    return rays.end();
-#else
-    for (int i = rays.begin(); i < rays.end(); i++) {
+  } else {
+    int i = rays.rayBegin;
+    for(;i<b;i++) {
       float tmin = 1e-5f;
       float tmax = rays.getMinT(i);
 
@@ -333,7 +217,7 @@
         return i;
       }
 
-      if (i == rays.begin()) {
+      if (i == rays.rayBegin) {
         // try a frustum miss
         float tmin_frustum = 1e-5;
         float tmax_frustum = FLT_MAX;
@@ -374,113 +258,250 @@
         }
       }
     }
-    return rays.end();
+
+    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][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][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[i]))));
+      __m128 valid_intersect = _mm_cmple_ps(maximum_minimum,minimum_maximum);
+      if (_mm_movemask_ps(valid_intersect) != 0x0)
+        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;
+      }
+    }
+  }
+  return rays.end();
+#else
+  for (int i = rays.begin(); i < rays.end(); 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;
+    }
+
+    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();
+      }
+    }
+  }
+  return rays.end();
 #endif
 }
 
 // return the last index which hits the box
 int DynBVH::lastIntersects(const BBox& box, const RayPacket& rays) const
 {
-    // TODO(boulos): Consider adding SIMD march here too
-    for (int ray = rays.end() - 1; ray > rays.begin(); ray-- )
+  // TODO(boulos): Consider adding SIMD march here too
+  for (int ray = rays.end() - 1; ray > rays.begin(); ray-- )
     {
-        float maximum_minimum = 1e-5;
-        float minimum_maximum = rays.getMinT(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 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 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);
 
-        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 )
-            return ray; // found a hit
+      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 )
+        return ray; // found a hit
     }
-    return rays.begin();
+  return rays.begin();
+}
+
+void DynBVH::setGroup(Group* new_group) {
+  if (new_group != currGroup)
+    group_changed = true;
+  currGroup = new_group;
 }
 
 void DynBVH::preprocess(const PreprocessContext& context)
 {
-  if (currGroup)
+  //cerr << MANTA_FUNC << endl;
+  // First preprocess the underlying group (so for example the
+  // positions of underlying WaldTriangles are correct)
+  if (currGroup) {
     currGroup->preprocess(context);
+
+    // Call rebuild (may call update underneath)
+    rebuild(context.proc, context.numProcs);
+
+    // NOTE(boulos): We allow rebuild to set the group_changed flag so
+    // that you're not required to call preprocess in order to do an
+    // update/rebuild.
+  }
 }
 
 void DynBVH::update(int proc, int numProcs) {
   PreprocessContext context;
   parallelUpdateBounds(context, proc, numProcs);
+  // TODO(boulos): Wait until everyone has gone through update to
+  // disable group_changed (requires another barrier)
+  if (proc == 0)
+    group_changed = false;
 }
 
-void DynBVH::rebuild(Group *group, int proc, int numProcs)
+void DynBVH::rebuild(int proc, int numProcs)
 {
-  //  if (proc > 0) return; //TODO: make this parallel (at least some of it).
-
-  //for now we rebuild if the number of primitives is different and
-  //update otherwise. This of course isn't always best, so if someone
-  //wants to improve on that, go for it.
-  PreprocessContext context;
-
-  if(currGroup && currGroup->size() == group->size()) {
-    currGroup = group;
-    parallelUpdateBounds(context, proc, numProcs);
+  if (!group_changed) {
+    update(proc, numProcs);
+    return;
   }
-  else {
-    if (proc > 0) return;
-
-    cerr << "\nDynBVH::preprocess START\n";
-    double start = SCIRun::Time::currentSeconds();
-
-    if(group->size() > object_ids.size()) {
-      nodes.resize(2*group->size());
-      object_ids.resize(group->size());
-      // TODO(boulos): Free these after construction? or keep around
-      // for rebuild?
-      obj_bounds.resize(group->size());
-      obj_centroids.resize(group->size());
-    }
-
-
-    currGroup = group;
+  PreprocessContext context;
 
-    for ( size_t i = 0; i < currGroup->size(); i++ ) {
-      object_ids[i] = i;
-      currGroup->get(i)->computeBounds(context, obj_bounds[i]);
-      obj_centroids[i] = obj_bounds[i].center();
-    }
+  // TODO(boulos/bigler/thiago/wald/sparker): Parallel rebuild ;)
+  if (proc > 0) return;
 
-    num_nodes = 1; // root node
-    int nextFree = 1;
-    double build_start = SCIRun::Time::currentSeconds();
-    build(context, 0, 0, currGroup->size(), nextFree);
-    double updateBound_start = SCIRun::Time::currentSeconds();
-    updateBounds(context, 0);
-    double end = SCIRun::Time::currentSeconds();
-    cerr << "\nDynBVH build time: Total ("<<end-start<<")\n"
-         << "object_ids initialization ("<<build_start-start<<")\n"
-         << "build ("<<updateBound_start-build_start<<")\n"
-         << "updateBounds ("<<end-updateBound_start<<")\n"
-         << "BBox = ("<<nodes[0].bounds.getMin()<<", 
"<<nodes[0].bounds.getMax()<<"\n\n";
+  cerr << "\nDynBVH::preprocess START (" << currGroup->size() << " 
objects)\n";
+  double start = SCIRun::Time::currentSeconds();
 
+  if(currGroup->size() > object_ids.size()) {
+    nodes.resize(2*currGroup->size());
+    object_ids.resize(currGroup->size());
+    // TODO(boulos): Free these after construction? or keep around
+    // for rebuild?
+    obj_bounds.resize(currGroup->size());
+    obj_centroids.resize(currGroup->size());
+  }
 
+  for ( size_t i = 0; i < currGroup->size(); i++ ) {
+    object_ids[i] = i;
+    currGroup->get(i)->computeBounds(context, obj_bounds[i]);
+    obj_centroids[i] = obj_bounds[i].center();
   }
+
+  num_nodes = 1; // root node
+  int nextFree = 1;
+  double build_start = SCIRun::Time::currentSeconds();
+  build(context, 0, 0, currGroup->size(), nextFree);
+  double updateBound_start = SCIRun::Time::currentSeconds();
+  updateBounds(context, 0);
+  double end = SCIRun::Time::currentSeconds();
+  cerr << "\nDynBVH build time: Total ("<<end-start<<")\n"
+       << "object_ids initialization ("<<build_start-start<<")\n"
+       << "build ("<<updateBound_start-build_start<<")\n"
+       << "updateBounds ("<<end-updateBound_start<<")\n"
+       << "BBox = ("<<nodes[0].bounds.getMin()<<", 
"<<nodes[0].bounds.getMax()<<")\n\n";
+
+  // NOTE(boulos): As of 17-Aug-2007 we don't have a parallel build so
+  // this is implicity proc0 anyway and requires no barrier.
+  group_changed = false;
 }
 
 void DynBVH::build(const PreprocessContext& context,
@@ -488,63 +509,58 @@
                    int& nextFree, int depth)
 {
 
-    if (objectEnd <= objectBegin)
-    {
-        printf("ERROR! Tried building BVH over 
%d,%d\n",objectBegin,objectEnd);
-        exit(-1);
-    }
+  if (objectEnd <= objectBegin) {
+    printf("ERROR! Tried building BVH over %d,%d\n",objectBegin,objectEnd);
+    exit(-1);
+  }
 
-    BVHNode& node = nodes[nodeID];
+  BVHNode& node = nodes[nodeID];
 
-    int bestAxis = -1;
-    int split = -1;
+  int bestAxis = -1;
+  int split = -1;
 
-#if USE_APPROXIMATE_BUILD // 30% slower for certain datasets.
-    int num_objects = objectEnd - objectBegin;
-    if (num_objects < 32) {
-      split = partitionSAH(context, objectBegin,objectEnd,bestAxis);
-    } else {
-      split = partitionApproxSAH(context, objectBegin,objectEnd,bestAxis);
-    }
-#else
+  // NOTE(abe): 30% slower rendering for a single CAD dataset.
+#if USE_APPROXIMATE_BUILD
+  int num_objects = objectEnd - objectBegin;
+  if (num_objects < 32) {
     split = partitionSAH(context, objectBegin,objectEnd,bestAxis);
+  } else {
+    split = partitionApproxSAH(context, objectBegin,objectEnd,bestAxis);
+  }
+#else
+  split = partitionSAH(context, objectBegin,objectEnd,bestAxis);
 #endif
 
-    if (bestAxis == -1)
-    {
-        // make leaf
-        node.makeLeaf(objectBegin, objectEnd-objectBegin);
-
-        
std::sort(object_ids.begin()+objectBegin,object_ids.begin()+objectEnd);
+  if (bestAxis == -1) {
+    // make leaf
+    node.makeLeaf(objectBegin, objectEnd-objectBegin);
 
-        num_nodes++;
-    }
-    else
-    {
-        // make internal node
-        node.makeInternal(nextFree, bestAxis);
-        num_nodes++;
-        // allocate two spots
-        nextFree += 2;
+    std::sort(object_ids.begin()+objectBegin,object_ids.begin()+objectEnd);
 
-        build(context, node.child+0,objectBegin,split,nextFree,depth+1);
-        build(context, node.child+1, split, objectEnd,nextFree,depth+1);
-    }
+    num_nodes++;
+  } else {
+    // make internal node
+    node.makeInternal(nextFree, bestAxis);
+    num_nodes++;
+    // allocate two spots
+    nextFree += 2;
 
-    if (depth == 0)
-    {
-        printf("DynBVH Build Complete\n");
-    }
+    build(context, node.child+0,objectBegin,split,nextFree,depth+1);
+    build(context, node.child+1, split, objectEnd,nextFree,depth+1);
+  }
 
+  if (depth == 0) {
+    printf("DynBVH Build Complete (used %d nodes)\n", nextFree);
+  }
 }
 
 void DynBVH::parallelUpdateBounds(const PreprocessContext& context,
                                   int proc, int numProcs)
 {
   //XXXX this is super naive hackish code! FIXME!
-  if (numProcs == 1)
+  if (numProcs == 1) {
     updateBounds(context, 0);
-  else {
+  } else {
     BVHNode& node = nodes[0];
     int left_son = node.child;
     int right_son = left_son + 1;
@@ -566,35 +582,31 @@
 
 void DynBVH::updateBounds(const PreprocessContext& context, int ID)
 {
-    BVHNode& node = nodes[ID];
-    if (node.isLeaf())
-    {
-        node.bounds.reset();
-        for (int i = 0; i < node.children; i++ )
-        {
-            BBox temp;
-            int obj_id = object_ids[node.child + i];
-            currGroup->get(obj_id)->computeBounds(context,temp);
+  BVHNode& node = nodes[ID];
+  if (node.isLeaf()) {
+    node.bounds.reset();
+    for (int i = 0; i < node.children; i++ ) {
+      BBox temp;
+      int obj_id = object_ids[node.child + i];
+      currGroup->get(obj_id)->computeBounds(context,temp);
 
-            node.bounds.extendByBox(temp);
-        }
-        node.axis = 0;
-        node.axis_sign = 0;
+      node.bounds.extendByBox(temp);
     }
-    else
-    {
-        int left_son = node.child;
-        int right_son = left_son + 1;
-        updateBounds(context, left_son);
-        updateBounds(context, right_son);
-
-        node.bounds.reset();
-        const BVHNode& left_node = nodes[left_son];
-        const BVHNode& right_node = nodes[right_son];
+    node.axis = 0;
+    node.axis_sign = 0;
+  } else {
+    int left_son = node.child;
+    int right_son = left_son + 1;
+    updateBounds(context, left_son);
+    updateBounds(context, right_son);
 
-        node.bounds.extendByBox(left_node.bounds);
-        node.bounds.extendByBox(right_node.bounds);
-    }
+    node.bounds.reset();
+    const BVHNode& left_node = nodes[left_son];
+    const BVHNode& right_node = nodes[right_son];
+
+    node.bounds.extendByBox(left_node.bounds);
+    node.bounds.extendByBox(right_node.bounds);
+  }
 }
 
 int DynBVH::partitionApproxSAH(const PreprocessContext& context,
@@ -753,73 +765,61 @@
 int DynBVH::partitionSAH(const PreprocessContext& context,
                          int objBegin, int objEnd, int& output_axis)
 {
-    int num_objects = objEnd - objBegin;
-    if ( num_objects == 1 )
-    {
-        output_axis = -1;
-        return -1;
-    }
+  int num_objects = objEnd - objBegin;
+  if ( num_objects == 1 ) {
+      output_axis = -1;
+      return -1;
+  }
 
-    BVHCostEval best_cost;
-    best_cost.cost = BVH_C_isec * num_objects;
-    best_cost.axis = -1;
-    best_cost.position = FLT_MAX;
-    best_cost.event = -1;
+  BVHCostEval best_cost;
+  best_cost.cost = BVH_C_isec * num_objects;
+  best_cost.axis = -1;
+  best_cost.position = FLT_MAX;
+  best_cost.event = -1;
 
-    for ( int axis = 0; axis < 3; axis++ )
-    {
-        BVHCostEval new_cost;
-        if ( buildEvents(context, objBegin,objEnd,axis,new_cost) )
-        {
-            if ( new_cost.cost < best_cost.cost )
-            {
-                best_cost = new_cost;
-            }
-        }
+  for ( int axis = 0; axis < 3; axis++ ) {
+    BVHCostEval new_cost;
+    if ( buildEvents(context, objBegin,objEnd,axis,new_cost) ) {
+      if ( new_cost.cost < best_cost.cost ) {
+        best_cost = new_cost;
+      }
     }
+  }
 
-    output_axis = best_cost.axis;
-    if ( output_axis != -1 )
-    {
-        // build the events and sort them
-        std::vector<BVHSAHEvent> events;
-        for ( int i = objBegin; i < objEnd; i++ )
-        {
-            BVHSAHEvent new_event;
-            BBox tri_box;
-            currGroup->get(object_ids[i])->computeBounds(context, tri_box);
-            new_event.position = tri_box.center()[output_axis];
-            new_event.obj_id   = object_ids[i];
-            events.push_back(new_event);
-        }
+  output_axis = best_cost.axis;
+  if ( output_axis != -1 ) {
+    // build the events and sort them
+    std::vector<BVHSAHEvent> events;
+    for ( int i = objBegin; i < objEnd; i++ ) {
+      BVHSAHEvent new_event;
+      BBox tri_box;
+      currGroup->get(object_ids[i])->computeBounds(context, tri_box);
+      new_event.position = tri_box.center()[output_axis];
+      new_event.obj_id   = object_ids[i];
+      events.push_back(new_event);
+    }
 
-        std::sort(events.begin(), events.end(), CompareBVHSAHEvent());
+    std::sort(events.begin(), events.end(), CompareBVHSAHEvent());
 
-        for ( int i = objBegin; i < objEnd; i++ )
-        {
-            object_ids[i] = events[i-objBegin].obj_id;
-        }
+    for ( int i = objBegin; i < objEnd; i++ ) {
+      object_ids[i] = events[i-objBegin].obj_id;
+    }
 
-        int result = objBegin + best_cost.event;
+    int result = objBegin + best_cost.event;
 
-        if ( result == objBegin || result == objEnd )
-        {
-            if ( num_objects < 8 )
-            {
-                output_axis = -1;
-                return 0;
-            }
-            result = objBegin + num_objects/2;
-            return result;
-        }
-        else
-            return result;
-    }
-    else
-    {
-        return 0; // making a leaf anyway
+    if ( result == objBegin || result == objEnd ) {
+      if ( num_objects < 8 ) {
+        output_axis = -1;
+        return 0;
+      }
+      result = objBegin + num_objects/2;
+      return result;
+    } else {
+      return result;
     }
+  }
 
+  return 0; // making a leaf anyway
 }
 
 bool DynBVH::buildEvents(const PreprocessContext& context,
@@ -828,78 +828,72 @@
                          int axis,
                          BVHCostEval& best_eval)
 {
-    BBox overall_box;
-    std::vector<BVHSAHEvent> events;
-    for ( int i = first; i < last; i++ )
-    {
-        BVHSAHEvent new_event;
-        BBox tri_box;
-        currGroup->get(object_ids[i])->computeBounds(context, tri_box);
-        new_event.position = tri_box.center()[axis];
-        new_event.obj_id   = object_ids[i];
-        events.push_back(new_event);
-
-        overall_box.extendByBox(tri_box);
-    }
-
-    std::sort(events.begin(),events.end(),CompareBVHSAHEvent());
-
-    int num_events = int(events.size());
-    BBox left_box;
-
-    int num_left = 0;
-    int num_right = num_events;
+  BBox overall_box;
+  std::vector<BVHSAHEvent> events;
+  for ( int i = first; i < last; i++ ) {
+    BVHSAHEvent new_event;
+    BBox tri_box;
+    currGroup->get(object_ids[i])->computeBounds(context, tri_box);
+    new_event.position = tri_box.center()[axis];
+    new_event.obj_id   = object_ids[i];
+    events.push_back(new_event);
 
-    for ( size_t i = 0; i < events.size(); i++ )
-    {
-        events[i].num_left = num_left;
-        events[i].num_right = num_right;
-        events[i].left_area = left_box.computeArea();
-
-        BBox tri_box;
-        currGroup->get(events[i].obj_id)->computeBounds(context, tri_box);
-        left_box.extendByBox(tri_box);
+    overall_box.extendByBox(tri_box);
+  }
 
-        num_left++;
-        num_right--;
-    }
+  std::sort(events.begin(),events.end(),CompareBVHSAHEvent());
 
-    BBox right_box;
+  int num_events = int(events.size());
+  BBox left_box;
 
-    best_eval.cost = FLT_MAX;
-    best_eval.event = -1;
+  int num_left = 0;
+  int num_right = num_events;
 
-    for ( int i = num_events - 1; i >= 0; i-- )
-    {
-        BBox tri_box;
-        currGroup->get(events[i].obj_id)->computeBounds(context, tri_box);
+  for ( size_t i = 0; i < events.size(); i++ ) {
+    events[i].num_left = num_left;
+    events[i].num_right = num_right;
+    events[i].left_area = left_box.computeArea();
 
-        right_box.extendByBox(tri_box);
+    BBox tri_box;
+    currGroup->get(events[i].obj_id)->computeBounds(context, tri_box);
+    left_box.extendByBox(tri_box);
 
-        if ( events[i].num_left > 0 && events[i].num_right > 0 )
-        {
-            events[i].right_area = right_box.computeArea();
+    num_left++;
+    num_right--;
+  }
 
-            float this_cost = (events[i].num_left * events[i].left_area +
-                               events[i].num_right * events[i].right_area);
-            this_cost /= overall_box.computeArea();
-            this_cost *= BVH_C_isec;
-            this_cost += BVH_C_trav;
+  BBox right_box;
 
-            events[i].cost = this_cost;
-            if ( this_cost < best_eval.cost )
-            {
-                best_eval.cost       = this_cost;
-                best_eval.position   = events[i].position;
-                best_eval.axis       = axis;
-                best_eval.event      = i;
-                best_eval.num_left   = events[i].num_left;
-                best_eval.num_right  = events[i].num_right;
+  best_eval.cost = FLT_MAX;
+  best_eval.event = -1;
 
-            }
-        }
+  for ( int i = num_events - 1; i >= 0; i-- ) {
+    BBox tri_box;
+    currGroup->get(events[i].obj_id)->computeBounds(context, tri_box);
+
+    right_box.extendByBox(tri_box);
+
+    if ( events[i].num_left > 0 && events[i].num_right > 0 ) {
+      events[i].right_area = right_box.computeArea();
+
+      float this_cost = (events[i].num_left * events[i].left_area +
+                         events[i].num_right * events[i].right_area);
+      this_cost /= overall_box.computeArea();
+      this_cost *= BVH_C_isec;
+      this_cost += BVH_C_trav;
+
+      events[i].cost = this_cost;
+      if ( this_cost < best_eval.cost ) {
+        best_eval.cost       = this_cost;
+        best_eval.position   = events[i].position;
+        best_eval.axis       = axis;
+        best_eval.event      = i;
+        best_eval.num_left   = events[i].num_left;
+        best_eval.num_right  = events[i].num_right;
+      }
     }
-    return best_eval.event != -1;
+  }
+  return best_eval.event != -1;
 }
 
 
@@ -1362,11 +1356,11 @@
     }
 
     const __m128 tBoxFarX = 
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[0][i]),
-                                        far_minus_org_x);
+                                       far_minus_org_x);
     const __m128 tBoxFarY = 
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[1][i]),
-                                        far_minus_org_y);
+                                       far_minus_org_y);
     const __m128 tBoxFarZ = 
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[2][i]),
-                                        far_minus_org_z);
+                                       far_minus_org_z);
 
     t1 = _mm_min_ps(t1, tBoxFarX);
     t1 = _mm_min_ps(t1, tBoxFarY);
@@ -1430,11 +1424,11 @@
     }
 
     const __m128 tBoxFarX = 
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[0][i]),
-                                        far_minus_org_x);
+                                       far_minus_org_x);
     const __m128 tBoxFarY = 
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[1][i]),
-                                        far_minus_org_y);
+                                       far_minus_org_y);
     const __m128 tBoxFarZ = 
_mm_mul_ps(_mm_load_ps(&data->inverseDirection[2][i]),
-                                        far_minus_org_z);
+                                       far_minus_org_z);
 
     t1 = _mm_min_ps(t1, tBoxFarX);
     t1 = _mm_min_ps(t1, tBoxFarY);

Modified: trunk/Model/Groups/DynBVH.h
==============================================================================
--- trunk/Model/Groups/DynBVH.h (original)
+++ trunk/Model/Groups/DynBVH.h Mon Aug 20 17:26:40 2007
@@ -10,170 +10,173 @@
 
 namespace Manta
 {
-    class DynBVH : public AccelerationStructure
+  class DynBVH : public AccelerationStructure
+  {
+  protected:
+    struct IAData
     {
-    protected:
-        struct IAData
-        {
-            Real min_rcp[3];
-            Real max_rcp[3];
-            Real min_org[3];
-            Real max_org[3];
-            Real min_org_rcp[3];
-            Real max_org_rcp[3];
-        };
-
-        struct BVHNode
-        {
-            BBox bounds;
-            int child; // my child
-            unsigned char axis; // 0 = x, 1 = y, 2 = z,
-            unsigned char axis_sign; // 0 means left-right, 1 means 
right-left
-            short children; // num children
-
-            // 24 bytes + 4 bytes + 1 + 1 + 2 = 32 bytes
-
-            inline void makeLeaf(int first_child, short num_children)
-            {
-                child = first_child;
-                children = num_children;
-                axis = 0;
-                axis_sign = 0;
-            }
-
-            inline void makeInternal(int first_child, unsigned char _axis)
-            {
-                child = first_child;
-                children = 0;
-                axis = _axis;
-                axis_sign = 0; // for now
-            }
-
-            inline bool isLeaf() const
-            {
-                return children != 0;
-            }
-
-        };
-
-        vector<BVHNode> nodes;
-        vector<unsigned int> object_ids;
-        unsigned int num_nodes;
-        Group* currGroup;
-        SCIRun::Barrier barrier;
-
-      vector<BBox> obj_bounds;
-      vector<Vector> obj_centroids;
-
-
-    public:
-      DynBVH() : currGroup(NULL), barrier("DynBVH barrier")
-        {}
-
-        void preprocess(const PreprocessContext&);
-        void intersect(const RenderContext& context, RayPacket& rays) const;
-    protected:
-        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 
IAData& ia_data, float* out_tmin) const;
-        // return the last index which hits the box
-        int lastIntersects(const BBox& box, const RayPacket& rays) const;
-
-    public:
-        void computeBounds(const PreprocessContext&,
-                           BBox& bbox) const
-        {
-          if (num_nodes)
-            bbox.extendByBox(nodes[0].bounds);
-        }
-
-      //Is this used by anyone?
-//         static Group* create(const vector<string>&)
-//         {
-//             return new DynBVH();
-//         }
-        void update(int proc=0, int numProcs=1);
-        void rebuild(Group *group, int proc=0, int numProcs=1);
-
-        void build(const PreprocessContext& context,
-                   int nodeID, int objectBegin, int objectEnd,
-                   int &nextFree, int depth = 0);
-
-        void parallelUpdateBounds(const PreprocessContext& context,
-                                  int proc, int numProcs);
-        void updateBounds(const PreprocessContext& context, int ID = 0);
-
-
-    protected:
-      int partitionSAH(const PreprocessContext& context,
-                       int objBegin, int objEnd, int& output_axis);
-      int partitionApproxSAH(const PreprocessContext& context,
-                             int objBegin,
-                             int objEnd,
-                             int& output_axis);
-
-        struct BVHCostEval
-        {
-            float position;
-            float cost;
-            int num_left;
-            int num_right;
-            int event;
-            int axis;
-        };
-
-        struct BVHSAHEvent
-        {
-            float position;
-            int obj_id;
-            float left_area;
-            float right_area;
-            int num_left;
-            int num_right;
-            float cost;
-        };
-
-        struct CompareBVHSAHEvent
-        {
-            bool operator()(const BVHSAHEvent& x, const BVHSAHEvent& y)
-            {
-                // add obj_id sorting in here automatically?
-                return x.position < y.position;
-            }
-        };
-
-        bool buildEvents(const PreprocessContext& context,
-                         int first,
-                         int last,
-                         int axis,
-                         BVHCostEval& eval);
+      Real min_rcp[3];
+      Real max_rcp[3];
+      Real min_org[3];
+      Real max_org[3];
+      Real min_org_rcp[3];
+      Real max_org_rcp[3];
+    };
+
+    struct BVHNode
+    {
+      BBox bounds;
+      int child; // my child
+      unsigned char axis; // 0 = x, 1 = y, 2 = z,
+      unsigned char axis_sign; // 0 means left-right, 1 means right-left
+      short children; // num children
+
+      // 24 bytes + 4 bytes + 1 + 1 + 2 = 32 bytes
+
+      inline void makeLeaf(int first_child, short num_children)
+      {
+        child = first_child;
+        children = num_children;
+        axis = 0;
+        axis_sign = 0;
+      }
+
+      inline void makeInternal(int first_child, unsigned char _axis)
+      {
+        child = first_child;
+        children = 0;
+        axis = _axis;
+        axis_sign = 0; // for now
+      }
+
+      inline bool isLeaf() const
+      {
+        return children != 0;
+      }
+
+    };
+
+    vector<BVHNode> nodes;
+    vector<unsigned int> object_ids;
+    unsigned int num_nodes;
+    Group* currGroup;
+    bool group_changed;
+    SCIRun::Barrier barrier;
+
+    vector<BBox> obj_bounds;
+    vector<Vector> obj_centroids;
+
+
+  public:
+    DynBVH() : currGroup(NULL), group_changed(false), barrier("DynBVH 
barrier")
+    {}
+
+    void setGroup(Group* new_group);
+
+    void preprocess(const PreprocessContext&);
+    void intersect(const RenderContext& context, RayPacket& rays) const;
+  protected:
+    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 
IAData& ia_data, float* out_tmin) const;
+    // return the last index which hits the box
+    int lastIntersects(const BBox& box, const RayPacket& rays) const;
+
+  public:
+    void computeBounds(const PreprocessContext&,
+                       BBox& bbox) const
+    {
+      if (num_nodes)
+        bbox.extendByBox(nodes[0].bounds);
+    }
+
+    //Is this used by anyone?
+    //         static Group* create(const vector<string>&)
+    //         {
+    //             return new DynBVH();
+    //         }
+    void update(int proc=0, int numProcs=1);
+    void rebuild(int proc=0, int numProcs=1);
+
+    void build(const PreprocessContext& context,
+               int nodeID, int objectBegin, int objectEnd,
+               int &nextFree, int depth = 0);
+
+    void parallelUpdateBounds(const PreprocessContext& context,
+                              int proc, int numProcs);
+    void updateBounds(const PreprocessContext& context, int ID = 0);
+
+
+  protected:
+    int partitionSAH(const PreprocessContext& context,
+                     int objBegin, int objEnd, int& output_axis);
+    int partitionApproxSAH(const PreprocessContext& context,
+                           int objBegin,
+                           int objEnd,
+                           int& output_axis);
+
+    struct BVHCostEval
+    {
+      float position;
+      float cost;
+      int num_left;
+      int num_right;
+      int event;
+      int axis;
+    };
+
+    struct BVHSAHEvent
+    {
+      float position;
+      int obj_id;
+      float left_area;
+      float right_area;
+      int num_left;
+      int num_right;
+      float cost;
+    };
+
+    struct CompareBVHSAHEvent
+    {
+      bool operator()(const BVHSAHEvent& x, const BVHSAHEvent& y)
+      {
+        // add obj_id sorting in here automatically?
+        return x.position < y.position;
+      }
+    };
+
+    bool buildEvents(const PreprocessContext& context,
+                     int first,
+                     int last,
+                     int axis,
+                     BVHCostEval& eval);
 
 #ifdef MANTA_SSE
-      // DynBVH ports
-      void templatedTraverse(const RenderContext& context, RayPacket& 
packet) const;
+    // DynBVH ports
+    void templatedTraverse(const RenderContext& context, RayPacket& packet) 
const;
 
-      int firstActivePort(RayPacket& packet, int firstActive, const BBox& 
box) const;
-      int lastActivePort(RayPacket& packet, int firstActive, const BBox& 
box) const;
+    int firstActivePort(RayPacket& packet, int firstActive, const BBox& box) 
const;
+    int lastActivePort(RayPacket& packet, int firstActive, const BBox& box) 
const;
 
-      int firstActiveSameSignFrustumPort(RayPacket& packet,
-                                         const int firstActive,
-                                         const BBox& bounds,
-                                         const int signs[3],
-                                         const __m128 sc_min_org[3],
-                                         const __m128 sc_max_org[3],
-                                         const __m128 sc_min_rcp[3],
-                                         const __m128 sc_max_rcp[3],
-                                         const __m128& max_t) const;
-
-      int lastThatIntersectsSameSignPort(RayPacket& packet,
-                                         const int firstActive,
-                                         const BBox& box,
-                                         const int signs[3]) const;
+    int firstActiveSameSignFrustumPort(RayPacket& packet,
+                                       const int firstActive,
+                                       const BBox& bounds,
+                                       const int signs[3],
+                                       const __m128 sc_min_org[3],
+                                       const __m128 sc_max_org[3],
+                                       const __m128 sc_min_rcp[3],
+                                       const __m128 sc_max_rcp[3],
+                                       const __m128& max_t) const;
+
+    int lastThatIntersectsSameSignPort(RayPacket& packet,
+                                       const int firstActive,
+                                       const BBox& box,
+                                       const int signs[3]) const;
 #endif
 
-    };
+  };
 };
 
 #endif

Modified: trunk/Model/Groups/GriddedGroup.cc
==============================================================================
--- trunk/Model/Groups/GriddedGroup.cc  (original)
+++ trunk/Model/Groups/GriddedGroup.cc  Mon Aug 20 17:26:40 2007
@@ -1,5 +1,6 @@
 
 #include <Model/Groups/GriddedGroup.h>
+#include <Interface/Context.h>
 #include <Interface/RayPacket.h>
 #include <Core/Exceptions/IllegalArgument.h>
 #include <Core/Exceptions/InternalError.h>
@@ -65,6 +66,9 @@
 
   BBox bbox;
   Group::computeBounds(context,bbox);
+  // NOTE(boulos): I think the computebounds could easily end up being
+  // parallel, so I'll let the threads get to here?
+  if (context.proc != 0) { context.done(); return; }
 
   min = bbox.getMin();
   max = bbox.getMax();
@@ -157,6 +161,7 @@
   double dt = Time::currentSeconds()-start;
   cerr << "GriddedGroup: " << numObjects << " objects, targeted cells: " << 
target_numcells << ", actual cells: " << totalcells << ", " << nx << "x" << 
ny << "x" << nz << ", built in " << dt << " seconds\n";
 
+  context.done();
 }
 
 void GriddedGroup::intersect( const RenderContext &context, RayPacket &rays 
) const

Modified: trunk/Model/Groups/Group.cc
==============================================================================
--- trunk/Model/Groups/Group.cc (original)
+++ trunk/Model/Groups/Group.cc Mon Aug 20 17:26:40 2007
@@ -1,8 +1,12 @@
 
+#include <Core/Util/Preprocessor.h>
 #include <Interface/Context.h>
 #include <Model/Groups/Group.h>
 #include <SCIRun/Core/Util/Assert.h>
 #include <algorithm>
+#include <iostream>
+using std::cerr;
+using std::endl;
 
 using namespace Manta;
 
@@ -153,11 +157,17 @@
 void Group::preprocess(const PreprocessContext& context)
 {
   //partition so that objs are serial and then parallel
-  parallelSplit = partition(objs.begin(), objs.end(), isSerial);
+  if (context.proc == 0)
+    parallelSplit = partition(objs.begin(), objs.end(), isSerial);
+  // NOTE(boulos): This is actually a barrier wait, and it's important
+  // to use that here since we don't want the objs changing underneath
+  // us for other threads
+  context.done();
 
   for(vector<Object*>::iterator iter = objs.begin(); iter != objs.end(); 
++iter)
     (*iter)->preprocess(context);
   dirtybbox = true;
+  context.done();
 }
 
 void Group::computeBounds(const PreprocessContext& context, BBox& bbox) const

Modified: trunk/Model/Groups/Mesh.cc
==============================================================================
--- trunk/Model/Groups/Mesh.cc  (original)
+++ trunk/Model/Groups/Mesh.cc  Mon Aug 20 17:26:40 2007
@@ -1,5 +1,6 @@
 #include <Model/Groups/Mesh.h>
 #include <Model/Primitives/WaldTriangle.h>
+#include <Core/Util/Preprocessor.h>
 #include <SCIRun/Core/Exceptions/InternalError.h>
 
 using namespace Manta;
@@ -202,7 +203,7 @@
 {
   for (unsigned int i=0; i < materials.size(); ++i)
     materials[i]->preprocess(context);
-  Group::preprocess(context);
+   Group::preprocess(context);
 }
 
 void Mesh::interpolateNormals()
@@ -255,10 +256,10 @@
     const Vector& a = vertices[index0];
     const Vector& b = vertices[index1];
     const Vector& c = vertices[index2];
-    
+
     //degenerate if triangle is collapsed onto a line or point.
     if ( Cross(a-b, c-b) == Vector::zero() ) {
-      
+
       //this triangle is degenerate. Let's remove it.
       vertex_indices[i+0] = vertex_indices[vertex_indices.size()-3];
       vertex_indices[i+1] = vertex_indices[vertex_indices.size()-2];

Modified: trunk/Model/Groups/RealisticBvh.cc
==============================================================================
--- trunk/Model/Groups/RealisticBvh.cc  (original)
+++ trunk/Model/Groups/RealisticBvh.cc  Mon Aug 20 17:26:40 2007
@@ -2,12 +2,12 @@
 
 /*
  For more information, please see: http://software.sci.utah.edu

+
  The MIT License

+
  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"),
@@ -15,10 +15,10 @@
  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
@@ -42,18 +42,18 @@
 
 using namespace Manta;
 
-RealisticBvh::RealisticBvh( Object *child0, Object *child1 ) { 
+RealisticBvh::RealisticBvh( Object *child0, Object *child1 ) {
+
+        child[0] = child0;
+        child[1] = child1;
 
-       child[0] = child0;
-       child[1] = child1;
-       
-       PreprocessContext context;
-       
-       // Update the bounding box of this node.
-       child0->computeBounds( context, bounds );
-       child1->computeBounds( context, bounds );
-       
-       split_axis = 0;
+        PreprocessContext context;
+
+        // Update the bounding box of this node.
+        child0->computeBounds( context, bounds );
+        child1->computeBounds( context, bounds );
+
+        split_axis = 0;
 }
 
 
@@ -66,138 +66,139 @@
 void
 RealisticBvh::start_build( Object **array, int size ) {
 
-       PreprocessContext context;
-       
-       // Compute the bounds of the array.
-       for (int i=0;i<size;++i) {
-               array[i]->computeBounds( context, bounds );
-       }
-
-       // Check to see if there is only one node.
-       if (size == 1) {
-               child[0] = child[1] = array[0];
-               return;
-       }
-       if (size == 2) {
-               child[0] = array[0];
-               child[1] = array[1];
-               return;
-       }
-
-       // Find a pivot point.
-       Vector pivot((Vector(bounds[0]) + Vector(bounds[1])) * 0.5);
-       
-       // Split along the axis.
-       int mid_point = qsplit( array, size, pivot[0], 0 );
-       
-       // Create new left and right children.
-       child[0] = build_branch( array, mid_point, 1 );
-       child[1] = build_branch( array+mid_point, size-mid_point, 1 );
-               
+        PreprocessContext context;
+
+        // Compute the bounds of the array.
+        for (int i=0;i<size;++i) {
+                array[i]->computeBounds( context, bounds );
+        }
+
+        // Check to see if there is only one node.
+        if (size == 1) {
+                child[0] = child[1] = array[0];
+                return;
+        }
+        if (size == 2) {
+                child[0] = array[0];
+                child[1] = array[1];
+                return;
+        }
+
+        // Find a pivot point.
+        Vector pivot((Vector(bounds[0]) + Vector(bounds[1])) * 0.5);
+
+        // Split along the axis.
+        int mid_point = qsplit( array, size, pivot[0], 0 );
+
+        // Create new left and right children.
+        child[0] = build_branch( array, mid_point, 1 );
+        child[1] = build_branch( array+mid_point, size-mid_point, 1 );
+
 }
 
 // Rearrange the pointers in the input array around a pivot point.
 int RealisticBvh::qsplit( Object **array, int size, Real pivot, int axis ) {
 
-       PreprocessContext context;
+        PreprocessContext context;
+
+        int ret_val = 0;
+        for (int i=0; i<size;++i) {
+
+                // Get the bounds of the object.
+                BBox bounds;
+                array[i]->computeBounds( context, bounds );
+
+                // Find the centroid of those bounds.
+                Real centroid = (bounds[0][axis] + bounds[1][axis]) * 
(Real)0.5;
+
+                if (centroid < pivot) {
+                        Object *tmp = array[i];
+                        array[i]    = array[ret_val];
+                        array[ret_val] = tmp;
+                        ++ret_val;
+                }
+        }
 
-       int ret_val = 0;
-       for (int i=0; i<size;++i) {
-       
-               // Get the bounds of the object.
-               BBox bounds;
-               array[i]->computeBounds( context, bounds );
-               
-               // Find the centroid of those bounds.
-               Real centroid = (bounds[0][axis] + bounds[1][axis]) * 
(Real)0.5;
-               
-               if (centroid < pivot) {
-                       Object *tmp = array[i];
-                       array[i]    = array[ret_val];
-                       array[ret_val] = tmp;
-                       ++ret_val;
-               }
-       }
-       
-       if ((ret_val == 0) || (ret_val == size)) 
-               ret_val = size / 2;
-               
-       return ret_val;
+        if ((ret_val == 0) || (ret_val == size))
+                ret_val = size / 2;
+
+        return ret_val;
 }
 
 Object *RealisticBvh::build_branch( Object **array, int size, int axis ) {
-       
-       // Check two exit conditions.
-       if (size == 1)
-               return array[0];
-       if (size == 2)
-               return new RealisticBvh( array[0], array[1] );
-       
-       // Create a new node.
-       RealisticBvh *new_node = new RealisticBvh();
-       
-       PreprocessContext context;
-       
-       // Compute the bounds of the array.
-       for (int i=0;i<size;++i) {
-               array[i]->computeBounds( context, new_node->bounds );
-       }
-       
-       // Find a pivot point.
-       Vector pivot((new_node->bounds[0] + new_node->bounds[1]) * (Real)0.5);
-       
-       // Split along the axis.
-       int mid_point = qsplit( array, size, pivot[axis], axis );
-
-       // save the split axis.
-       new_node->split_axis = axis;
-       
-       // Create new left and right children.
-       new_node->child[0] = build_branch( array, mid_point, (axis+1)%3 );
-       new_node->child[1] = build_branch( array+mid_point, size-mid_point, 
(axis+1)%3 );
-       
-       return new_node;
+
+        // Check two exit conditions.
+        if (size == 1)
+                return array[0];
+        if (size == 2)
+                return new RealisticBvh( array[0], array[1] );
+
+        // Create a new node.
+        RealisticBvh *new_node = new RealisticBvh();
+
+        PreprocessContext context;
+
+        // Compute the bounds of the array.
+        for (int i=0;i<size;++i) {
+                array[i]->computeBounds( context, new_node->bounds );
+        }
+
+        // Find a pivot point.
+        Vector pivot((new_node->bounds[0] + new_node->bounds[1]) * 
(Real)0.5);
+
+        // Split along the axis.
+        int mid_point = qsplit( array, size, pivot[axis], axis );
+
+        // save the split axis.
+        new_node->split_axis = axis;
+
+        // Create new left and right children.
+        new_node->child[0] = build_branch( array, mid_point, (axis+1)%3 );
+        new_node->child[1] = build_branch( array+mid_point, size-mid_point, 
(axis+1)%3 );
+
+        return new_node;
 }
 
 void RealisticBvh::preprocess(const PreprocessContext& context) {
+  // Build occurs in the constructor.
+  if (child[0])
+    child[0]->preprocess( context );
+
+  if (child[1])
+    child[1]->preprocess( context );
 
-       // Build occurs in the constructor.
-       if (child[0])
-               child[0]->preprocess( context );
-               
-       if (child[1])
-               child[1]->preprocess( context );
+  context.done();
 }
 
 void RealisticBvh::computeBounds(const PreprocessContext& /*context*/,
                                  BBox& bbox) const {
 
-       // Bound the bvh.
-       bbox.extendByBox( bounds );
+        // Bound the bvh.
+        bbox.extendByBox( bounds );
 }
 
 void RealisticBvh::intersect(const RenderContext& context, RayPacket& rays) 
const {
-       
-       rays.computeInverseDirections();
+
+        rays.computeInverseDirections();
   rays.computeSigns();
 
-       // Intersect the ray packet with the bounds of this node.
-       bool bbox_intersect[RayPacket::MaxSize];
+        // Intersect the ray packet with the bounds of this node.
+        bool bbox_intersect[RayPacket::MaxSize];
 
-       for(int i=rays.begin();i<rays.end();i++) {
-               // Check to see if the ray hits this node's bounding box.
-               Real min_t, max_t;
-               bbox_intersect[i]
-      = Intersection::intersectAaBox( bounds, min_t, max_t, rays.getRay(i), 
+        for(int i=rays.begin();i<rays.end();i++) {
+                // Check to see if the ray hits this node's bounding box.
+                Real min_t, max_t;
+                bbox_intersect[i]
+      = Intersection::intersectAaBox( bounds, min_t, max_t, rays.getRay(i),
                                       rays.getSigns(i),
                                       rays.getInverseDirection(i),
                                       (Real)0, rays.getMinT(i) );
-       }
+        }
 
   for(int begin=rays.begin(); begin < rays.end(); ){
-               // Find the beginning of a run.
-               while ((begin < rays.end()) && (!bbox_intersect[begin]))
-                       ++begin;
+                // Find the beginning of a run.
+                while ((begin < rays.end()) && (!bbox_intersect[begin]))
+                        ++begin;
 
     if (begin >= rays.end())
       // No box intersections left

Modified: trunk/Model/Groups/private/CGT.cc
==============================================================================
--- trunk/Model/Groups/private/CGT.cc   (original)
+++ trunk/Model/Groups/private/CGT.cc   Mon Aug 20 17:26:40 2007
@@ -13,6 +13,10 @@
 {
 }
 
+void Grid::setGroup(Group* new_group) {
+  currGroup = new_group;
+}
+
 void Grid::preprocess(const PreprocessContext& context)
 {
   context.manta_interface->registerSerialPreRenderCallback(
@@ -33,7 +37,7 @@
 #ifdef MAILBOXING
   //need to adjust mailboxes if number of threads or number of
   //primitives changes
-  
+
   if (!currGroup) return;
 
   //this could be called from rebuild and the serialPreRenderCallback
@@ -59,7 +63,7 @@
   mutex.unlock();
 #endif
 
-} 
+}
 
 void Grid::computeBounds(const PreprocessContext& context, BBox& bbox) const
 {
@@ -70,10 +74,8 @@
     currGroup->computeBounds(context, bbox);
 }
 
-void Grid::rebuild(Group *group, int proc, int numProcs)
+void Grid::rebuild(int proc, int numProcs)
 {
-  currGroup = group;
-
   if (proc == 0) {
     startGlobalBuildTime = SCIRun::Time::currentSeconds();
     preFrameSetup(proc, numProcs); //currGroup size might have changed
@@ -155,11 +157,11 @@
     sse_N = set44(0,N[2],N[1],N[0]);
     sse_M = set44(0,M[2],M[1],M[0]);
     sse_one_over_N = accurateReciprocal(sse_N);
-  
+
     scale = accurateReciprocal(diam);
     scaleN = mul4(sse_N,accurateReciprocal(diam));
     scaleM = mul4(sse_M,accurateReciprocal(diam));
-  
+
     //If we have a packet wider than X cells we will probably want to split 
it.
     //lets assume that the values in scaleN are essentially all the same -- 
so use one.
 #define MAX_CELLS_WIDTH 3.0f
@@ -173,7 +175,7 @@
       cout << "building grid for " << currGroup->size() << " objects, res = 
" << N[0] << "x" << N[1] << "x" << N[2] << endl << "bounds = " << bounds << 
endl;
 
     if (firstTime || DISPLAY_BUILD_TIMES)
-      cout << "first stage of grid build : " 
+      cout << "first stage of grid build : "
            << (SCIRun::Time::currentSeconds() - startThreadBuildTime)*1e3 << 
"ms" << endl;
   }
 
@@ -196,9 +198,9 @@
   //that had objects and just clear those.
 #if 1
   const int oldlength = oldN_mc[1]*oldN_mc[2] - 1;
-  const int start_z = oldlength*proc / 
+  const int start_z = oldlength*proc /
     (oldN_mc[1]*numProcs);
-  const int end_z = oldlength*(proc+1) / 
+  const int end_z = oldlength*(proc+1) /
     (oldN_mc[1]*numProcs);
   const int start_y = oldlength*proc / numProcs -
     start_z*oldN_mc[1];
@@ -218,8 +220,8 @@
       for (int x=0; x < oldN_mc[0]; x++) {
         int ofs = x+oldN_mc[0]*(y+oldN_mc[1]*(z));
         if (cellVector_mc[ofs] > 0) {
-          int id = (x*MACRO_CELLS) + 
-                   oldN[0]*( y*MACRO_CELLS + 
+          int id = (x*MACRO_CELLS) +
+                   oldN[0]*( y*MACRO_CELLS +
                              oldN[1]*z*MACRO_CELLS);
           for (int mz=0;mz<MACRO_CELLS;mz++) {
             for (int my=0;my<MACRO_CELLS;my++) {
@@ -227,7 +229,7 @@
                 myCell[id].ObjectIDs.resize(0);
                 id++;
               }
-              id += oldN[0] - MACRO_CELLS; 
+              id += oldN[0] - MACRO_CELLS;
             }
             id += oldN[0] * (oldN[1] - MACRO_CELLS);
           }
@@ -240,12 +242,12 @@
   if (firstTime || DISPLAY_BUILD_TIMES)
   {
     char buf[128];
-    sprintf(buf, "%d: time to clear old grid: %fms\n", 
+    sprintf(buf, "%d: time to clear old grid: %fms\n",
             proc, (SCIRun::Time::currentSeconds() - startClearTime)*1e3);
     cout<<buf;
   }
 
-  buildQueue_resize_mutex.lock();  
+  buildQueue_resize_mutex.lock();
   if (buildQueues.size() < static_cast<size_t>(numProcs*numProcs)) {
     buildQueues.resize(numProcs*numProcs);
   }
@@ -265,7 +267,7 @@
   //even though we don't really need a barrier here, this
   //ends up, I think, not slowing down the code and it produces
   //nicer more uniform and easier to understand timings.
-  //Make sure to double check when getting overall best timings 
+  //Make sure to double check when getting overall best timings
   //whether this is slowing down the code...
   barrier.wait(numProcs);
 
@@ -316,7 +318,7 @@
 
   if (DISPLAY_BUILD_TIMES) {
     char buf[128];
-    sprintf(buf, "%d engriddingTimer time: %fms\n", 
+    sprintf(buf, "%d engriddingTimer time: %fms\n",
             proc, (SCIRun::Time::currentSeconds()-startSortTime)*1e3f);
     cout<<buf;
   }
@@ -327,7 +329,7 @@
 
   for (int i=0; i < numProcs; i++) {
     for (size_t k=0; k < buildQueues[i*numProcs + 
proc].loc_primitives.size(); ++k) {
-      const location_primitive &prim_lp = 
+      const location_primitive &prim_lp =
         buildQueues[i*numProcs + proc].loc_primitives[k];
 
       
myCell[prim_lp.gridLocation].ObjectIDs.push_back(prim_lp.which_primitive);
@@ -336,7 +338,7 @@
 
   if (DISPLAY_BUILD_TIMES) {
     char buf[128];
-    sprintf(buf, "%d merge time: %fms\n", 
+    sprintf(buf, "%d merge time: %fms\n",
             proc, (SCIRun::Time::currentSeconds() - startMergeTime)*1e3);
     cout<<buf;
   }
@@ -352,9 +354,9 @@
   double startMacroBuildTime = SCIRun::Time::currentSeconds();
 
   const int length = N_mc[1]*N_mc[2] - 1;
-  const int start_iz = length*proc / 
+  const int start_iz = length*proc /
     (N_mc[1]*numProcs);
-  const int end_iz = length*(proc+1) / 
+  const int end_iz = length*(proc+1) /
     (N_mc[1]*numProcs);
   const int start_iy = length*proc / numProcs -
     start_iz*N_mc[1];
@@ -363,11 +365,11 @@
 
   for (int iz = start_iz; iz<=end_iz; iz++)
     for (int iy = ((iz==start_iz)? start_iy: 0);
-         iy < ((iz==end_iz)? end_iy:N_mc[1]); iy++) 
+         iy < ((iz==end_iz)? end_iy:N_mc[1]); iy++)
       for (int ix = 0;ix<N_mc[0];ix++) {
         int count = 0;
-        int id = (ix*MACRO_CELLS) + 
-                  N[0]*( iy*MACRO_CELLS + 
+        int id = (ix*MACRO_CELLS) +
+                  N[0]*( iy*MACRO_CELLS +
                          N[1]*iz*MACRO_CELLS);
         for (int mz=0;mz<MACRO_CELLS;mz++) {
           for (int my=0;my<MACRO_CELLS;my++) {
@@ -390,7 +392,7 @@
 
   if (DISPLAY_BUILD_TIMES) {
     char buf[128];
-    sprintf(buf, "%d macro cell build time: %fms\n", 
+    sprintf(buf, "%d macro cell build time: %fms\n",
             proc, (SCIRun::Time::currentSeconds() - 
startMacroBuildTime)*1e3);
     cout<<buf;
   }
@@ -410,7 +412,7 @@
   }
 
   if (firstTime|| DISPLAY_BUILD_TIMES)
-    cout << "grid built in " 
+    cout << "grid built in "
          << (SCIRun::Time::currentSeconds() - startGlobalBuildTime)*1e3 << 
"ms\n\n";
   firstTime = false;
 }
@@ -429,7 +431,7 @@
   //grid, but later on maybe try checking more often (every macro cell
   //or every grid cell?).
 

+
   const float f_NK = N[K];
   const float f_NU = N[U];
   const float f_NV = N[V];
@@ -445,7 +447,7 @@
   float maxUd;
   float minVd;
   float maxVd;
-  
+
   if (ray.getFlag(RayPacket::HaveCornerRays))
   {
     sse_t dir4[3];
@@ -456,7 +458,7 @@
 
     // all rays in u space are u(k) = f_orgU + d_u/d_k * (k - f_orgK)
     // i.e., u(k) = (f_orgU - d_u/d_k*f_orgK) + k * d_u/d_k
-    
+
     //------------------------------------------------------------------
     // stretch all rays to have dir[k] == 1
     //
@@ -473,16 +475,16 @@
     minDv = min4f(dv);
     maxDu = max4f(du);
     maxDv = max4f(dv);
-    
+
   }
   else {
     //TODO: convert to SSE!
-   
+
     ray.computeInverseDirections();
 
     bool setDir = false;
     for (int i=ray.begin();i<ray.end();i++) {
-      
+
 //XXXX set it so that disabled rays do not contribute!
 //         if (ray.wasHit(i))
 //           continue;
@@ -501,20 +503,20 @@
       minDv = min(minDv, dv);
       maxDv = max(maxDv, dv);
     }
-    
+
     const sse_t inv_scaleN = accurateReciprocal(scaleN);
-      
+
     minDu *= DK;
     minDv *= DK;
     maxDu *= DK;
     maxDv *= DK;
-    
+
     //some intersecters, like WaldTriangle use corner rays, so get corners.
     ray.data->corner_dir[K] = set4(DK);
     ray.data->corner_dir[U] = set44(maxDu, maxDu, minDu, minDu);
     ray.data->corner_dir[V] = set44(maxDv, minDv, maxDv, minDv);
     ray.setFlag(RayPacket::HaveCornerRays);
-      
+
     float u_scale = ((float4&)scaleN)[U] * ((float4&)inv_scaleN)[K]*DK;
     float v_scale = ((float4&)scaleN)[V] * ((float4&)inv_scaleN)[K]*DK;
     minDu *= u_scale;
@@ -526,7 +528,7 @@
   sse_t minMax_dudv = set44(maxDv,maxDu,minDv,minDu);
   //printf("%f %f %f %f\n", maxDv,maxDu,minDv,minDu);
   if (COMMON_ORIGIN) {
-    sse_t org4 = set44(0.0f, ray.getOrigin(ray.begin(),2), 
+    sse_t org4 = set44(0.0f, ray.getOrigin(ray.begin(),2),
                        ray.getOrigin(ray.begin(),1), 
ray.getOrigin(ray.begin(),0));
     sse_t s_org = mul4(scaleN,sub4(org4,bounds.min));
 
@@ -567,10 +569,10 @@
   if (DK == +1) {
     int b = (ray.begin() + 3) & (~3);
     int e = ray.end() & (~3);
-    if (b == e) {
+    if (b >= e) {
       float curr_k = ((float4&)s_furthest_k)[0];
       for(int i=ray.begin();i<ray.end();i++) {
-        curr_k = max(curr_k, ray.getOrigin(i,K) + 
+        curr_k = max(curr_k, ray.getOrigin(i,K) +
                      ray.getMinT(i)*ray.getDirection(i,K));
       }
       s_furthest_k = set4(curr_k);
@@ -580,7 +582,7 @@
       // Do the non aligned in front
       if (i < b) {
         s_furthest_k = add4(load44(&ray.getOrigin(b-4,K)),
-                            mul4(load44(&ray.getMinT(b-4)), 
+                            mul4(load44(&ray.getMinT(b-4)),
                                  load44(&ray.getDirection(b-4,K))));
         for(int j=0; j<i&4; ++j)
           ((float4&)s_furthest_k)[j] = ((float4&)s_furthest_k)[3];
@@ -589,13 +591,13 @@
       for(i=b; i<e; i+=4)
         s_furthest_k = max4(s_furthest_k,
                             add4(load44(&ray.getOrigin(b,K)),
-                                 mul4(load44(&ray.getMinT(i)), 
+                                 mul4(load44(&ray.getMinT(i)),
                                       load44(&ray.getDirection(i,K)))));
       // Do the non aligned in end
       if (i < ray.end()) {
         float curr_k = ((float4&)s_furthest_k)[0];
         for(; i<ray.end(); ++i) {
-          curr_k = max(curr_k, ray.getOrigin(b,K) + 
+          curr_k = max(curr_k, ray.getOrigin(b,K) +
                        ray.getMinT(i)*ray.getDirection(i,K));
         }
         ((float4&)s_furthest_k)[0] = curr_k;
@@ -606,10 +608,10 @@
   else {
     int b = (ray.begin() + 3) & (~3);
     int e = ray.end() & (~3);
-    if (b == e) {
+    if (b >= e) {
       float curr_k = ((float4&)s_furthest_k)[0];
       for(int i=ray.begin();i<ray.end();i++) {
-        curr_k = min(curr_k, ray.getOrigin(i,K) + 
+        curr_k = min(curr_k, ray.getOrigin(i,K) +
                      ray.getMinT(i)*ray.getDirection(i,K));
       }
       s_furthest_k = set4(curr_k);
@@ -619,7 +621,7 @@
       // Do the non aligned in front
       if (i < b) {
         s_furthest_k = add4(load44(&ray.getOrigin(b-4,K)),
-                            mul4(load44(&ray.getMinT(b-4)), 
+                            mul4(load44(&ray.getMinT(b-4)),
                                  load44(&ray.getDirection(b-4,K))));
         for(int j=0; j<i&4; ++j)
           ((float4&)s_furthest_k)[j] = ((float4&)s_furthest_k)[3];
@@ -628,13 +630,13 @@
       for(i=b; i<e; i+=4)
         s_furthest_k = min4(s_furthest_k,
                             add4(load44(&ray.getOrigin(b,K)),
-                                 mul4(load44(&ray.getMinT(i)), 
+                                 mul4(load44(&ray.getMinT(i)),
                                       load44(&ray.getDirection(i,K)))));
       // Do the non aligned in end
       if (i < ray.end()) {
         float curr_k = ((float4&)s_furthest_k)[0];
         for(; i<ray.end(); ++i) {
-          curr_k = min(curr_k, ray.getOrigin(b,K) + 
+          curr_k = min(curr_k, ray.getOrigin(b,K) +
                        ray.getMinT(i)*ray.getDirection(i,K));
         }
         ((float4&)s_furthest_k)[0] = curr_k;
@@ -647,7 +649,7 @@
     for(int i=0; i<ray.end(); i+=4)
       s_furthest_k = max4(s_furthest_k,
                           add4(load44(&ray.getOrigin(0,K)),
-                               mul4(load44(&ray.getMinT(i)), 
+                               mul4(load44(&ray.getMinT(i)),
                                     load44(&ray.getDirection(i,K)))));
 //     for (int i=0;i<ray.end;i+=4)
 //         s_furthest_k = 
max4(s_furthest_k,add4(ray.org0[K],mul4(ray.t[i],ray.dir[K][i])));
@@ -655,7 +657,7 @@
     for(int i=0; i<ray.end(); i+=4)
       s_furthest_k = min4(s_furthest_k,
                           add4(load44(&ray.getOrigin(0,K)),
-                               mul4(load44(&ray.getMinT(i)), 
+                               mul4(load44(&ray.getMinT(i)),
                                     load44(&ray.getDirection(i,K)))));
 //     for (int i=0;i<ray.curr_packet_simds;i++)
 //         s_furthest_k = 
min4(s_furthest_k,add4(ray.org0[K],mul4(ray.t[i],ray.dir[K][i])));
@@ -667,7 +669,7 @@
   else
     k1 = (min4f(s_furthest_k) - ((float4&)bounds.min)[K]) * 
((float4&)scaleN)[K];
   // transform to local:
-  
+
   // --------------------------------------------
   // now, [k0,k1] is the k interval overlapped by the rays. (note: for 
DK==-1, k1<k0!)
   // next, clip to [0..N[K]] interval
@@ -683,9 +685,9 @@
   // --------------------------------------------
   // now, [k0,k1] is the k interval overlapped by the rays. (note: for 
DK==-1, k1<k0!)
   // both k0 and k1 are positive (must be in [0..Nk] range ...
-  // 
+  //
   // now, clip in u dimension
-  // know 'min' and 'max' planes: 
+  // know 'min' and 'max' planes:
   //   u(k) = minUd + k * minDu
   //   u(k) = maxUd + k * maxDu
   //
@@ -700,55 +702,55 @@
   if (DK == +1) {
     // min is lower plane, max is upper plane
     if (minDu < 0.0f) {
-         // lower plane goes downwards, defines entry point at Nu
-         const float k = (f_NU - minUd) / minDu;
-         k0 = max(k0,k);
-         uMinOfs = 1.f;
-       }
+          // lower plane goes downwards, defines entry point at Nu
+          const float k = (f_NU - minUd) / minDu;
+          k0 = max(k0,k);
+          uMinOfs = 1.f;
+        }
     else {
-         // lower plane goes up, defines exit point at Nu
-         const float k = (f_NU - minUd) / minDu;
-         k1 = min(k1,k);
-         uMinOfs = 0.f;
-       }
+          // lower plane goes up, defines exit point at Nu
+          const float k = (f_NU - minUd) / minDu;
+          k1 = min(k1,k);
+          uMinOfs = 0.f;
+        }
     if (maxDu < 0.0f) {
-         // upper plane goes downwards, defines exit point at 0
-         const float k = (0.f - maxUd) / maxDu;
-         k1 = min(k1,k);
-         uMaxOfs = 0.f;
-       }
+          // upper plane goes downwards, defines exit point at 0
+          const float k = (0.f - maxUd) / maxDu;
+          k1 = min(k1,k);
+          uMaxOfs = 0.f;
+        }
     else {
-         // upper plane goes up, defines exit point at 0
-         const float k = (0.f - maxUd) / maxDu;
-         k0 = max(k0,k);
-         uMaxOfs = 1.f;
-       }
+          // upper plane goes up, defines exit point at 0
+          const float k = (0.f - maxUd) / maxDu;
+          k0 = max(k0,k);
+          uMaxOfs = 1.f;
+        }
     if (k0 > k1) return;
   }
   else {
     // min is upper plane, max is lower plane
     if (minDu < 0.0f) {
-         // upper plane goes neg. downwards, defines entry point at 0
-         const float k = (0.f - minUd) / minDu;
-         k0 = min(k0,k);
-         uMaxOfs = 0.f;
-       }
+          // upper plane goes neg. downwards, defines entry point at 0
+          const float k = (0.f - minUd) / minDu;
+          k0 = min(k0,k);
+          uMaxOfs = 0.f;
+        }
     else {
-         // upper plane neg. goes up, defines exit point at Nu
-         const float k = (0.f - minUd) / minDu;
-         k1 = max(k1,k);
-         uMaxOfs = 1.f;
-       }
+          // upper plane neg. goes up, defines exit point at Nu
+          const float k = (0.f - minUd) / minDu;
+          k1 = max(k1,k);
+          uMaxOfs = 1.f;
+        }
     if (maxDu < 0.0f) {
-         const float k = (f_NU - maxUd) / maxDu;
-         k1 = max(k1,k);
-         uMinOfs = 1.f;
-       }
+          const float k = (f_NU - maxUd) / maxDu;
+          k1 = max(k1,k);
+          uMinOfs = 1.f;
+        }
     else {
-         const float k = (f_NU - maxUd) / maxDu;
-         k0 = min(k0,k);
-         uMinOfs = 0.f;
-       }
+          const float k = (f_NU - maxUd) / maxDu;
+          k0 = min(k0,k);
+          uMinOfs = 0.f;
+        }
     if (k0 < k1) return;
   }
 
@@ -756,55 +758,55 @@
   if (DK == +1) {
     // min is lower plane, max is vpper plane
     if (minDv < 0.0f) {
-         // lower plane goes downwards, defines entry point at Nv
-         const float k = (f_NV - minVd) / minDv;
-         k0 = max(k0,k);
-         vMinOfs = 1.f;
-       }
+          // lower plane goes downwards, defines entry point at Nv
+          const float k = (f_NV - minVd) / minDv;
+          k0 = max(k0,k);
+          vMinOfs = 1.f;
+        }
     else {
-         // lower plane goes vp, defines exit point at Nv
-         const float k = (f_NV - minVd) / minDv;
-         k1 = min(k1,k);
-         vMinOfs = 0.f;
-       }
+          // lower plane goes vp, defines exit point at Nv
+          const float k = (f_NV - minVd) / minDv;
+          k1 = min(k1,k);
+          vMinOfs = 0.f;
+        }
     if (maxDv < 0.0f) {
-         // vpper plane goes downwards, defines exit point at 0
-         const float k = (0.f - maxVd) / maxDv;
-         k1 = min(k1,k);
-         vMaxOfs = 0.f;
-       }
+          // vpper plane goes downwards, defines exit point at 0
+          const float k = (0.f - maxVd) / maxDv;
+          k1 = min(k1,k);
+          vMaxOfs = 0.f;
+        }
     else {
-         // vpper plane goes vp, defines exit point at 0
-         const float k = (0.f - maxVd) / maxDv;
-         k0 = max(k0,k);
-         vMaxOfs = 1.f;
-       }
+          // vpper plane goes vp, defines exit point at 0
+          const float k = (0.f - maxVd) / maxDv;
+          k0 = max(k0,k);
+          vMaxOfs = 1.f;
+        }
     if (k0 > k1) return;
   }
   else {
     // min is vpper plane, max is lower plane
     if (minDv < 0.0f) {
-         // vpper plane goes neg. downwards, defines entry point at 0
-         const float k = (0.f - minVd) / minDv;
-         k0 = min(k0,k);
-         vMaxOfs = 0.f;
-       }
+          // vpper plane goes neg. downwards, defines entry point at 0
+          const float k = (0.f - minVd) / minDv;
+          k0 = min(k0,k);
+          vMaxOfs = 0.f;
+        }
     else {
-         // vpper plane neg. goes vp, defines exit point at Nv
-         const float k = (0.f - minVd) / minDv;
-         k1 = max(k1,k);
-         vMaxOfs = 1.f;
-       }
+          // vpper plane neg. goes vp, defines exit point at Nv
+          const float k = (0.f - minVd) / minDv;
+          k1 = max(k1,k);
+          vMaxOfs = 1.f;
+        }
     if (maxDv < 0.0f) {
-         const float k = (f_NV - maxVd) / maxDv;
-         k1 = max(k1,k);
-         vMinOfs = 1.f;
-       }
+          const float k = (f_NV - maxVd) / maxDv;
+          k1 = max(k1,k);
+          vMinOfs = 1.f;
+        }
     else {
-         const float k = (f_NV - maxVd) / maxDv;
-         k0 = min(k0,k);
-         vMinOfs = 0.f;
-       }
+          const float k = (f_NV - maxVd) / maxDv;
+          k0 = min(k0,k);
+          vMinOfs = 0.f;
+        }
     if (k0 < k1) return;
   }
 
@@ -816,7 +818,7 @@
   int startSlice;
   if (DK == +1)
     startSlice = int(k0);
-  else 
+  else
     startSlice = int(k0);
   const float f_startSlice = startSlice;
 
@@ -831,12 +833,12 @@
     uv01k0 = set44(minVd, minUd, maxVd, maxUd);
   }
   const sse_t minMax_Ofs = set44(vMaxOfs, uMaxOfs, vMinOfs, uMinOfs);
-  sse_t minMax_uv = add4( mul4(uv01duv, 
+  sse_t minMax_uv = add4( mul4(uv01duv,
                                add4(set4(f_startSlice), minMax_Ofs)),
                           uv01k0);
 
-  // ------------------------------------------------------- 
-  // now, for the macrocells: 
+  // -------------------------------------------------------
+  // now, for the macrocells:
   //
   // since the macrocells have exactly the same planes, we can just
   // compute the new values for the new start slice
@@ -847,7 +849,7 @@
   const float f_startSlice_mc = startSlice_mc;
 
   sse_t minMax_uv_mc;
-  minMax_uv_mc = add4( mul4(uv01duv, 
+  minMax_uv_mc = add4( mul4(uv01duv,
                             add4(set4(f_startSlice_mc), minMax_Ofs)),
                        mul4(uv01k0, set4(1./MACRO_CELLS)));
 #endif
@@ -863,12 +865,12 @@
   else
     next_mc_slice = slice_mc*MACRO_CELLS - 1;
 #endif
-    
+
   int cellID[3];
   int ik1 = int(k1);
   assert(slice >= 0);
   assert(slice < N[K]);
-  
+
 #ifdef MACRO_CELLS
   const sse_t sse_N_mc = set44(N_mc[V]-1,N_mc[U]-1,N_mc[V]-1,N_mc[U]-1);
 #endif
@@ -939,7 +941,7 @@
       } range;
       range.clampedAsInt = convert4_f2i(clamped);
 
-         cellID[K] = slice;
+          cellID[K] = slice;
       cellID[U] = range.uv01[0];
       cellID[V] = range.uv01[1];
 
@@ -952,11 +954,11 @@
           const int items = object.size();
           for (int i=0;i<items;i++) {
 #ifdef MAILBOXING
-            if (mailboxes[context.proc].mailbox[object[i]] == 
+            if (mailboxes[context.proc].mailbox[object[i]] ==
                 mailboxes[context.proc].rayID) {
               continue;
             }
-            mailboxes[context.proc].mailbox[object[i]] = 
+            mailboxes[context.proc].mailbox[object[i]] =
               mailboxes[context.proc].rayID;
 #endif
             //it appears that always setting anyHit to true only causes a 
couple
@@ -978,8 +980,8 @@
         else //K == 2 and U is X and V is Y
           id += N[0] - (range.uv01[2]-range.uv01[0]+1);
       }
-      
-         if (anyHit) {
+
+          if (anyHit) {
         if (DK == +1)
           s_furthest_k = _mm_minus_infty;
         else
@@ -988,10 +990,10 @@
         if (DK == +1) {
           int b = (ray.begin() + 3) & (~3);
           int e = ray.end() & (~3);
-          if (b == e) {
+          if (b >= e) {
             float curr_k = ((float4&)s_furthest_k)[0];
             for(int i=ray.begin();i<ray.end();i++) {
-              curr_k = max(curr_k, ray.getOrigin(i,K) + 
+              curr_k = max(curr_k, ray.getOrigin(i,K) +
                            ray.getMinT(i)*ray.getDirection(i,K));
             }
             s_furthest_k = set4(curr_k);
@@ -1001,7 +1003,7 @@
             // Do the non aligned in front
             if (i < b) {
               s_furthest_k = add4(load44(&ray.getOrigin(b-4,K)),
-                                  mul4(load44(&ray.getMinT(b-4)), 
+                                  mul4(load44(&ray.getMinT(b-4)),
                                        load44(&ray.getDirection(b-4,K))));
               for(int j=0; j<i&4; ++j)
                 ((float4&)s_furthest_k)[j] = ((float4&)s_furthest_k)[3];
@@ -1010,13 +1012,13 @@
             for(i=b; i<e; i+=4)
               s_furthest_k = max4(s_furthest_k,
                                   add4(load44(&ray.getOrigin(b,K)),
-                                       mul4(load44(&ray.getMinT(i)), 
+                                       mul4(load44(&ray.getMinT(i)),
                                             
load44(&ray.getDirection(i,K)))));
             // Do the non aligned in end
             if (i < ray.end()) {
               float curr_k = ((float4&)s_furthest_k)[0];
               for(; i<ray.end(); ++i) {
-                curr_k = max(curr_k, ray.getOrigin(b,K) + 
+                curr_k = max(curr_k, ray.getOrigin(b,K) +
                              ray.getMinT(i)*ray.getDirection(i,K));
               }
               ((float4&)s_furthest_k)[0] = curr_k;
@@ -1026,10 +1028,10 @@
         else {
           int b = (ray.begin() + 3) & (~3);
           int e = ray.end() & (~3);
-          if (b == e) {
+          if (b >= e) {
             float curr_k = ((float4&)s_furthest_k)[0];
             for(int i=ray.begin();i<ray.end();i++) {
-              curr_k = min(curr_k, ray.getOrigin(i,K) + 
+              curr_k = min(curr_k, ray.getOrigin(i,K) +
                            ray.getMinT(i)*ray.getDirection(i,K));
             }
             s_furthest_k = set4(curr_k);
@@ -1039,7 +1041,7 @@
             // Do the non aligned in front
             if (i < b) {
               s_furthest_k = add4(load44(&ray.getOrigin(b-4,K)),
-                                  mul4(load44(&ray.getMinT(b-4)), 
+                                  mul4(load44(&ray.getMinT(b-4)),
                                        load44(&ray.getDirection(b-4,K))));
               for(int j=0; j<i&4; ++j)
                 ((float4&)s_furthest_k)[j] = ((float4&)s_furthest_k)[3];
@@ -1048,13 +1050,13 @@
             for(i=b; i<e; i+=4)
               s_furthest_k = min4(s_furthest_k,
                                   add4(load44(&ray.getOrigin(b,K)),
-                                       mul4(load44(&ray.getMinT(i)), 
+                                       mul4(load44(&ray.getMinT(i)),
                                             
load44(&ray.getDirection(i,K)))));
             // Do the non aligned in end
             if (i < ray.end()) {
               float curr_k = ((float4&)s_furthest_k)[0];
               for(; i<ray.end(); ++i) {
-                curr_k = min(curr_k, ray.getOrigin(b,K) + 
+                curr_k = min(curr_k, ray.getOrigin(b,K) +
                              ray.getMinT(i)*ray.getDirection(i,K));
               }
               ((float4&)s_furthest_k)[0] = curr_k;
@@ -1066,13 +1068,13 @@
           for(int i=0; i<ray.end(); i+=4)
             s_furthest_k = max4(s_furthest_k,
                                 add4(load44(&ray.getOrigin(0,K)),
-                                     mul4(load44(&ray.getMinT(i)), 
+                                     mul4(load44(&ray.getMinT(i)),
                                           load44(&ray.getDirection(i,K)))));
         else
           for(int i=0; i<ray.end(); i+=4)
             s_furthest_k = min4(s_furthest_k,
                                 add4(load44(&ray.getOrigin(0,K)),
-                                     mul4(load44(&ray.getMinT(i)), 
+                                     mul4(load44(&ray.getMinT(i)),
                                           load44(&ray.getDirection(i,K)))));
 #endif
 
@@ -1080,24 +1082,24 @@
           k1 = min(k1,(max4f(s_furthest_k) - ((float4&)bounds.min)[K]) * 
((float4&)scaleN)[K]);
         else
           k1 = max(k1,(min4f(s_furthest_k) - ((float4&)bounds.min)[K]) * 
((float4&)scaleN)[K]);
-        
+
         ik1 = int(k1);
         if (DK == +1)
           { if (slice > ik1) return; }
         else
           { if (slice < ik1) return; }
       }
-         
-         if (DK == +1) {
+
+          if (DK == +1) {
         minMax_uv = add4(minMax_uv, uv01duv);
         slice ++;
       }
-         else {
+          else {
         minMax_uv = sub4(minMax_uv, uv01duv);
         slice --;
       }
 #ifdef MACRO_CELLS
-       }
+        }
     while (slice != next_mc_slice);
 
     // done doing the micro-slices, finish the macrocell stepping
@@ -1112,7 +1114,7 @@
 
 template<bool SHADOWS_ONLY, bool COMMON_ORIGIN, bool SQUARE_PACKETS>
 void Grid::traverse(RayPacket &packet, const RenderContext& context) const
-{ 
+{
   // apparently, this is faster than via the sse_t ops below...
   const float dirX = packet.getDirection(packet.begin(),0);
   const float dirY = packet.getDirection(packet.begin(),1);

Modified: trunk/Model/Groups/private/CGT.h
==============================================================================
--- trunk/Model/Groups/private/CGT.h    (original)
+++ trunk/Model/Groups/private/CGT.h    Mon Aug 20 17:26:40 2007
@@ -68,13 +68,13 @@
   struct location_primitive {
     int gridLocation;
     int which_primitive;
-    location_primitive(int g, int w) : 
+    location_primitive(int g, int w) :
       gridLocation(g), which_primitive(w){ }
     location_primitive() { }
   };
   struct vector_of_location_primitive {
     vector<location_primitive> loc_primitives;
-    char false_sharing_buffer[128-sizeof(vector<location_primitive>)];    
+    char false_sharing_buffer[128-sizeof(vector<location_primitive>)];
   };
   vector< vector_of_location_primitive > buildQueues;
 
@@ -88,7 +88,7 @@
 };
   mutable vector <mailbox_struct> mailboxes;
 #endif //MAILBOXING
-  
+
   static void newFrame();
 #ifdef MACRO_CELLS
   vector<int> cellVector_mc;
@@ -152,7 +152,7 @@
     return cell;
   }
 
-  Grid() : resolutionFactor(5), 
+  Grid() : resolutionFactor(5),
            firstTime(true), mutex("generic build mutex"),
            barrier("CGT build barrier"),
            buildQueue_resize_mutex("build queue resize mutex"),
@@ -167,18 +167,19 @@
 
   void computeBounds(const PreprocessContext& context, BBox& bbox) const;
 
+  void setGroup(Group* new_group);
   void preprocess(const PreprocessContext&);
   void build(int proc, int numProcs, bool &);
   void preFrameSetup(int proc, int numProcs);
 
-  void rebuild(Group *group, int proc=0, int numProcs=1);
+  void rebuild(int proc=0, int numProcs=1);
 
   template<bool SHADOWS_ONLY, bool COMMON_ORIGIN, bool SQUARE_PACKETS>
   void traverse(RayPacket &packet, const RenderContext& context) const;
 
   template<bool SHADOWS_ONLY, bool COMMON_ORIGIN, bool SQUARE_PACKETS, int 
K, int U, int V, int DK>
   void TrvMajor(RayPacket &ray, const RenderContext& context) const;
-  
+
   void intersect(const RenderContext& context, RayPacket& rays) const;
 
 protected:

Modified: trunk/Model/Instances/Instance.cc
==============================================================================
--- trunk/Model/Instances/Instance.cc   (original)
+++ trunk/Model/Instances/Instance.cc   Mon Aug 20 17:26:40 2007
@@ -28,10 +28,12 @@
 
 #include <Model/Instances/Instance.h>
 #include <Model/Instances/MPT.h>
+#include <Interface/Context.h>
 #include <Interface/RayPacket.h>
 #include <Core/Exceptions/BadPrimitive.h>
 #include <Core/Geometry/BBox.h>
 #include <Core/Math/MiscMath.h>
+#include <Core/Util/Preprocessor.h>
 
 #include <sgi_stl_warnings_off.h>
 #include <sstream>
@@ -59,7 +61,10 @@
 
 void Instance::preprocess(const PreprocessContext& context)
 {
+  //cerr << MANTA_FUNC << endl;
+  //cerr << " Before instance->preprocess (thread " << context.proc << " of 
" << context.numProcs << ")\n";
   instance->preprocess(context);
+  //cerr << " After instance->preprocess (thread " << context.proc << " of " 
<< context.numProcs << ")\n";
 }
 
 void Instance::computeBounds(const PreprocessContext& context, BBox& bbox) 
const
@@ -74,18 +79,33 @@
 
 void Instance::intersect(const RenderContext& context, RayPacket& rays) const
 {
+  bool debugFlag = rays.getFlag(RayPacket::DebugPacket);
+  if (debugFlag) {
+    cerr << MANTA_FUNC << " called\n";
+  }
   RayPacketData raydata;
   RayPacket instance_rays(raydata, RayPacket::UnknownShape, rays.begin(), 
rays.end(),
                           rays.getDepth(), rays.getAllFlags());
+  // TODO(boulos): Make this a lot cleaner and try to easily maintain
+  // ray packet properties (probably best to just do so in specialized
+  // instance classes though)
+
+  // We don't know if we have a constant scale
+  instance_rays.resetFlag(RayPacket::NormalizedDirections |
+                          RayPacket::HaveInverseDirections |
+                          RayPacket::HaveSigns |
+                          RayPacket::ConstantSigns |
+                          RayPacket::HaveCornerRays);
+
   Real scales[RayPacket::MaxSize];
   Real inv_scales[RayPacket::MaxSize];
 
   if(rays.getFlag(RayPacket::ConstantOrigin)){
     Vector o = transform_inv.multiply_point(rays.getOrigin(rays.begin()));
-        
+
     for(int i = rays.begin();i<rays.end();i++){
       Vector dir = transform_inv.multiply_vector(rays.getDirection(i));
-               
+
       Real length = dir.length();
       inv_scales[i] = length;
       Real ilength = 1/length;
@@ -106,6 +126,14 @@
       instance_rays.resetHit(i, rays.getMinT(i)*length);
     }
   }
+
+  if (debugFlag) {
+    cerr << "After transforming the incoming rays:" << endl;
+    cerr << rays << endl;
+    cerr << "We get this: " << endl;
+    cerr << instance_rays << endl << endl;
+  }
+
   instance->intersect(context, instance_rays);
   for(int i=rays.begin();i<rays.end();i++){
     if(instance_rays.wasHit(i)){
@@ -170,7 +198,7 @@
 }
 
 void Instance::computeTexCoords2(const RenderContext& context,
-                              RayPacket& rays) const
+                               RayPacket& rays) const
 {
   Real old_minT[RayPacket::MaxSize];
   Ray old_rays[RayPacket::MaxSize];
@@ -209,7 +237,7 @@
 }
 
 void Instance::computeTexCoords3(const RenderContext& context,
-                              RayPacket& rays) const
+                               RayPacket& rays) const
 {
   Real old_minT[RayPacket::MaxSize];
   Ray old_rays[RayPacket::MaxSize];

Modified: trunk/Model/Materials/LitMaterial.cc
==============================================================================
--- trunk/Model/Materials/LitMaterial.cc        (original)
+++ trunk/Model/Materials/LitMaterial.cc        Mon Aug 20 17:26:40 2007
@@ -16,6 +16,11 @@
 
 void LitMaterial::preprocess(const PreprocessContext& context)
 {
+  if (context.proc != 0) {
+    context.done();
+    return;
+  }
+
   if(localLights){
     localLights->preprocess(context);
     if(localLightsOverrideGlobal){
@@ -26,4 +31,5 @@
   } else {
     activeLights = context.globalLights;
   }
+  context.done();
 }

Modified: trunk/Model/MiscObjects/CuttingPlane.cc
==============================================================================
--- trunk/Model/MiscObjects/CuttingPlane.cc     (original)
+++ trunk/Model/MiscObjects/CuttingPlane.cc     Mon Aug 20 17:26:40 2007
@@ -1,4 +1,5 @@
 
+#include <Interface/Context.h>
 #include <Model/MiscObjects/CuttingPlane.h>
 #include <Model/Intersections/AxisAlignedBox.h>
 #include <Model/Intersections/Plane.h>
@@ -7,6 +8,7 @@
 #include <iostream>
 #include <sgi_stl_warnings_on.h>
 
+
 using namespace Manta;
 
 CuttingPlane::CuttingPlane( const Vector &point_, const Vector &normal_,
@@ -29,13 +31,16 @@
 {
   // Call preprocess on the object.
   internal_object->preprocess( context );
-       
+
   // Compute its bounds.
   internal_object->computeBounds( context, bounds );
 
-  // Determine how far away the edges of the bounding box are from the 
+  // Determine how far away the edges of the bounding box are from the
   // initial point.
-  movement_scale = bounds.diagonal().length() * (Real)0.5;
+  if (context.proc == 0)
+    movement_scale = bounds.diagonal().length() * (Real)0.5;
+
+  context.done();
 }
 
 void CuttingPlane::intersect(const RenderContext& context, RayPacket& rays) 
const {
@@ -44,20 +49,20 @@
   RayPacketData new_data;
   RayPacket     new_rays( new_data, RayPacket::UnknownShape, rays.begin(), 
rays.end(),
                           rays.getDepth(), rays.getAllFlags());
-  
+
   rays.normalizeDirections();
   rays.computeInverseDirections();
   rays.computeSigns();
-       
+
   // Map between rays in original packet and new packet in case some rays 
are skipped.
   int packet_map[RayPacket::MaxSize];
-       
+
   // Keep track of which new rays intersect the front face of the plane.
   bool front_facing[RayPacket::MaxSize];
-       
+
   // Keep track of the plane_t offset for each ray.
   Real plane_t[RayPacket::MaxSize];
-        
+
   
/////////////////////////////////////////////////////////////////////////////
   // Create the new rays.
   int new_i = 0;
@@ -69,75 +74,75 @@
     if (Intersection::intersectAaBox( bounds, box_min, box_max,
                                       ray, rays.getSigns(i),
                                       rays.getInverseDirection(i) )) {
-      
+
       // Intersect the ray with the plane.
       Intersection::intersectPlane( plane_point, plane_normal, 
plane_t[new_i],
                                     ray );
-      
+
       // Record which original ray this new ray maps to.
       packet_map[new_i] = i;
-      
+
       // Check to see if the ray origin is on the front or back facing side 
of
       // the cutting plane (the front facing side is cut away).
       front_facing[new_i] = Dot(plane_normal, (ray.origin()-plane_point)) > 
0;
       if (front_facing[new_i]) {
-       
+
         // If plane_t is negative, the ray can't possibly hit the cut model.
         // because the ray is pointing away from the plane.
         if (plane_t[new_i] > 0) {
-          
+
           // If front facing, move the new ray to the cutting plane.
           new_rays.setRay(new_i, 
ray.origin()+(ray.direction()*plane_t[new_i]),
                           ray.direction());
           new_rays.resetFlag(RayPacket::ConstantOrigin);
-          
-          
+
+
           // Subtract the distance from the hit t.
           new_rays.resetHit( new_i, rays.getMinT(i) - plane_t[new_i] );
-          
+
           ++new_i;
         }
       }
       else {
-       
+
         // Otherwise if back facing, move the hit t in the hit record
         // to the plane (it will need to be moved back afterwards)
         new_rays.setRay(new_i, ray);
         new_rays.resetHit( new_i, rays.getMinT(i) );
-       
-        ++new_i;       
+
+        ++new_i;
       }
-      
-      
+
+
     }
   }
-  
+
   // Check to see if all of the rays miss the bounds.
   if (new_i == 0) {
     return;
   }
-  
+
   // Specify the number of new rays.
   new_rays.resize( new_i );
-  
+
   
/////////////////////////////////////////////////////////////////////////////
   // Intersect the new ray packet with the internal object.
   internal_object->intersect( context, new_rays );
-  
+
   
/////////////////////////////////////////////////////////////////////////////
   // Map the results back to the old rays.
   for (new_i=new_rays.begin(); new_i<new_rays.end(); ++new_i) {
-    
+
     // Check to see if the new ray hit something.
     if (new_rays.wasHit(new_i)) {
-      
+
       // Determine which old ray this maps to.
       int old_i = packet_map[new_i];
-      
+
       // Check to see if the old ray is front or back facing.
       if (front_facing[new_i]) {
         // If so, then translate the hit t back into the old hit record.
-        if (rays.hit( old_i, new_rays.getMinT(new_i)+plane_t[new_i], 
+        if (rays.hit( old_i, new_rays.getMinT(new_i)+plane_t[new_i],
                       new_rays.getHitMaterial(new_i),
                       new_rays.getHitPrimitive(new_i),
                       new_rays.getHitTexCoordMapper(new_i) ))

Modified: trunk/Model/MiscObjects/KeyFrameAnimation.cc
==============================================================================
--- trunk/Model/MiscObjects/KeyFrameAnimation.cc        (original)
+++ trunk/Model/MiscObjects/KeyFrameAnimation.cc        Mon Aug 20 17:26:40 
2007
@@ -9,9 +9,9 @@
 using namespace Manta;
 using namespace std;
 
-KeyFrameAnimation::KeyFrameAnimation(InterpolationMode interpolation) : 
-  as(NULL), interpolation(interpolation), spareGroup(NULL), 
-  currGroup(NULL), currTime(-1), updateToCurrTime(false), 
+KeyFrameAnimation::KeyFrameAnimation(InterpolationMode interpolation) :
+  as(NULL), interpolation(interpolation), spareGroup(NULL),
+  currGroup(NULL), currTime(-1), updateToCurrTime(false),
   paused(false), barrier("keyframe animation barrier"), duration(1)
 {
 }
@@ -110,16 +110,30 @@
       keyframes[1].keyframe = frames[end];
       keyframes[1].t = t;
 
-      InterpErr errCode = currGroup->parallelInterpolate(keyframes, 
+      // NOTE(boulos): This doesn't actually change the group pointer,
+      // so we don't need to inform the AccelStruct to do a setGroup
+      InterpErr errCode = currGroup->parallelInterpolate(keyframes,
                                                          context.proc, 
context.numProcs);
       if (errCode != success)
         printf("KeyFrameAnimation had trouble interpolating!\n");
     }
     else if (interpolation == truncate) {
+      // NOTE(boulos): Only proc 0 should change the currGroup pointer
+      if (context.proc == 0) {
         currGroup = frames[(int) frame];
+        // TODO(boulos): Who should check for identical pointers?
+        if (as) as->setGroup(currGroup);
+      }
     }
+
+    // NOTE(boulos): We have to wait until the group is properly
+    // interpolated before proceeding to the acceleration structure
+    // update (there's no way to ensure that all the geometry will be
+    // ready before someone starts touching it in update otherwise).
+    barrier.wait(context.numProcs);
+
     if (as)
-      as->rebuild(currGroup, context.proc, context.numProcs);
+      as->update(context.proc, context.numProcs);
   }
 }
 
@@ -200,9 +214,12 @@
   if (as)
     as->preprocess(context);
 
-  context.manta_interface->registerParallelAnimationCallback(
-    Callback::create(this, &KeyFrameAnimation::temporaryUpdate));
+  if (context.proc == 0) {
+    context.manta_interface->registerParallelAnimationCallback
+      (Callback::create(this, &KeyFrameAnimation::temporaryUpdate));
+  }
 
+  context.done();
 }
 
 void KeyFrameAnimation::computeBounds(const PreprocessContext& context, 
BBox& bbox) const

Modified: trunk/Model/Primitives/GridSpheres.cc
==============================================================================
--- trunk/Model/Primitives/GridSpheres.cc       (original)
+++ trunk/Model/Primitives/GridSpheres.cc       Mon Aug 20 17:26:40 2007
@@ -94,6 +94,10 @@
   // Preprocess material
   LitMaterial::preprocess(context);
 
+  if (context.proc != 0) {
+    context.done();
+    return;
+  }
   // Build grid
   cerr<<"Building GridSpheres\n";
 
@@ -328,6 +332,7 @@
   }
 
   cerr<<"Done building GridSpheres\n";
+  context.done();
 }
 
 void GridSpheres::computeBounds(const PreprocessContext& context,

Modified: trunk/Model/Primitives/ParticleBVH.cc
==============================================================================
--- trunk/Model/Primitives/ParticleBVH.cc       (original)
+++ trunk/Model/Primitives/ParticleBVH.cc       Mon Aug 20 17:26:40 2007
@@ -1,5 +1,6 @@
 
 #include <Model/Primitives/ParticleBVH.h>
+#include <Interface/Context.h>
 #include <Interface/RayPacket.h>
 #include <SCIRun/Core/Math/MiscMath.h>
 
@@ -96,7 +97,10 @@
   PreprocessContext const &context )
 {
   PrimitiveCommon::preprocess( context );
-  build( 0, 0, number_of_particles, 1 );
+  if (context.proc == 0) {
+    build( 0, 0, number_of_particles, 1 );
+  }
+  context.done();
 }
 
 void ParticleBVH::computeBounds(

Modified: trunk/Model/Primitives/WaldTriangle.cc
==============================================================================
--- trunk/Model/Primitives/WaldTriangle.cc      (original)
+++ trunk/Model/Primitives/WaldTriangle.cc      Mon Aug 20 17:26:40 2007
@@ -1,6 +1,8 @@
 #include <Model/Primitives/WaldTriangle.h>
+#include <Interface/Context.h>
 #include <Interface/RayPacket.h>
 #include <Core/Geometry/BBox.h>
+#include <Core/Util/Preprocessor.h>
 #include <SCIRun/Core/Util/Assert.h>
 #include <sgi_stl_warnings_off.h>
 #include <iostream>
@@ -81,6 +83,7 @@
 
 void WaldTriangle::preprocess(const PreprocessContext& context)
 {
+  if (context.proc != 0) { context.done(); return; }
   //TODO: this materials->preprocess might end up getting called lots
   //of times (imagine all the triangles share the same
   //material). Would be nice to have the preprocess for this in the
@@ -88,6 +91,7 @@
   //that, so we will do extra work for now.
   mesh->materials[mesh->face_material[myID]]->preprocess(context);
   update();
+  context.done();
 }
 
 void WaldTriangle::setPoints(const Vector& _p1, const Vector& _p2, const 
Vector& _p3)
@@ -206,6 +210,12 @@
 
 
 void WaldTriangle::intersect(const RenderContext& context, RayPacket& rays) 
const {
+  bool debugFlag = rays.getFlag(RayPacket::DebugPacket);
+  if (debugFlag) {
+    cerr << MANTA_FUNC << " called\n";
+    cerr << "Rays are: \n" << rays << endl;
+  }
+
     const int axis = k;
     const int ku = (k==2)?0:k+1;
     const int kv = (k==0)?2:k-1;

Modified: trunk/scenes/primtest.cc
==============================================================================
--- trunk/scenes/primtest.cc    (original)
+++ trunk/scenes/primtest.cc    Mon Aug 20 17:26:40 2007
@@ -439,7 +439,7 @@
     mesh->face_material.push_back(0);
 
     mesh->addTriangle(prim);
-    prim->update();
+    //prim->update();
     if ( mapr )
       prim->setTexCoordMapper( mapr );
     spinprim = prim;




  • [Manta] r1668 - in trunk: Core/Util Engine/Control Engine/Renderers Interface Maya Model/Cameras Model/Groups Model/Groups/private Model/Instances Model/Materials Model/MiscObjects Model/Primitives scenes, boulos, 08/20/2007

Archive powered by MHonArc 2.6.16.

Top of page