Manta Interactive Ray Tracer Development Mailing List

Text archives Help


[MANTA] r913 - in trunk/fox/afr_demo: . Engine/Control Engine/ImageTraversers StandAlone


Chronological Thread 
  • From: abhinav@sci.utah.edu
  • To: manta@sci.utah.edu
  • Subject: [MANTA] r913 - in trunk/fox/afr_demo: . Engine/Control Engine/ImageTraversers StandAlone
  • Date: Thu, 9 Feb 2006 13:14:47 -0700 (MST)

Author: abhinav
Date: Thu Feb  9 13:14:44 2006
New Revision: 913

Added:
   trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.cc
   trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.h
Modified:
   trunk/fox/afr_demo/CMakeLists.txt
   trunk/fox/afr_demo/Engine/Control/AFRPipeline.h
   trunk/fox/afr_demo/Engine/ImageTraversers/AFImageTraverser.cc
   trunk/fox/afr_demo/Engine/ImageTraversers/AFRImageTraverser.cc
   trunk/fox/afr_demo/Engine/ImageTraversers/EGSRImageTraverser.cc
   trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverser.cc
   trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserNew.cc
   trunk/fox/afr_demo/Engine/ImageTraversers/STAFRImageTraverser.cc
   trunk/fox/afr_demo/StandAlone/afr.cc
Log:
Added stplanes imagetraverser (still not correctly working though)

Added AFRCamera as generic camera for AFR Image traversers. It maintains a 
history.



Modified: trunk/fox/afr_demo/CMakeLists.txt
==============================================================================
--- trunk/fox/afr_demo/CMakeLists.txt   (original)
+++ trunk/fox/afr_demo/CMakeLists.txt   Thu Feb  9 13:14:44 2006
@@ -27,6 +27,8 @@
     Engine/ImageTraversers/GSTAFRImageTraverserNew.cc
     Engine/ImageTraversers/GSTAFRImageTraverserNew.h
     Engine/ImageTraversers/GSTAFRImageTraverser.h
+    Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.cc
+    Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.h
     Engine/ImageTraversers/AFRImageTraverser.h
     Engine/ImageTraversers/STAFRImageTraverser.cc
     Engine/ImageTraversers/STAFRImageTraverser.h
@@ -35,8 +37,10 @@
     Engine/ImageTraversers/EGSRImageTraverser.cc
     Engine/ImageTraversers/EGSRImageTraverser.h
     # Model
-    Model/Cameras/AfrPinholeCamera.cc
-    Model/Cameras/AfrPinholeCamera.h
+    Model/Cameras/AFRPinholeCamera.cc
+    Model/Cameras/AFRPinholeCamera.h
+    Model/Cameras/AFRCamera.cc
+    Model/Cameras/AFRCamera.h
 
     )
 

Modified: trunk/fox/afr_demo/Engine/Control/AFRPipeline.h
==============================================================================
--- trunk/fox/afr_demo/Engine/Control/AFRPipeline.h     (original)
+++ trunk/fox/afr_demo/Engine/Control/AFRPipeline.h     Thu Feb  9 13:14:44 
2006
@@ -173,7 +173,7 @@
 
       // Query functions
       virtual int getCurrentFrame() const { return 
animFrameState.frameNumber; };
-      virtual double getCurrentTime();
+      virtual Real getCurrentTime();
       virtual int getWorkersRendering() const { return workersRendering; };
       virtual int getAFRContextArraySize() const { return 
afr_context_array_size; };
 

Modified: trunk/fox/afr_demo/Engine/ImageTraversers/AFImageTraverser.cc
==============================================================================
--- trunk/fox/afr_demo/Engine/ImageTraversers/AFImageTraverser.cc       
(original)
+++ trunk/fox/afr_demo/Engine/ImageTraversers/AFImageTraverser.cc       Thu 
Feb  9 13:14:44 2006
@@ -4,7 +4,7 @@
 #include <Interface/Renderer.h>
 #include <Interface/Context.h>
 #include <Interface/Fragment.h>
-#include <Model/Cameras/AfrPinholeCamera.h>
+#include <Model/Cameras/AFRCamera.h>
 #include <Interface/Image.h>
 #include <Interface/LoadBalancer.h>
 #include <Interface/PixelSampler.h>
@@ -165,7 +165,7 @@
   // have flag for camera and dump the camera
   fprintf(textstreamfile[myID],"\n\nbegin_camera\n");
   // print camera to file
-  ((AFRPinholeCamera*)context.camera)->writeToFile(textstreamfile[myID]);
+  ((AFRCamera*)context.camera)->writeToFile(textstreamfile[myID]);
 }
 
 void AFImageTraverser::setupDisplayChannel(SetupContext& context) {
@@ -645,7 +645,7 @@
         {
           const Point p(px, py, pz);
           Point rp;
-          rp = ((AFRPinholeCamera*)context.camera)->project(p);
+          rp = ((AFRCamera*)context.camera)->project(p);
           sp->viewCoord[0] = rp.x()*xres;
           sp->viewCoord[1] = rp.y()*yres;
           sp->viewCoord[2] = rp.z();

Modified: trunk/fox/afr_demo/Engine/ImageTraversers/AFRImageTraverser.cc
==============================================================================
--- trunk/fox/afr_demo/Engine/ImageTraversers/AFRImageTraverser.cc      
(original)
+++ trunk/fox/afr_demo/Engine/ImageTraversers/AFRImageTraverser.cc      Thu 
Feb  9 13:14:44 2006
@@ -2,7 +2,7 @@
 
 #include <Engine/ImageTraversers/AFRImageTraverser.h>
 #include <Model/Groups/KDTree.h>
-#include <fox/afr_demo/Model/Cameras/AfrPinholeCamera.h>
+#include <fox/afr_demo/Model/Cameras/AFRCamera.h>
 
 using namespace Manta;
 using namespace Manta::Afr;
@@ -55,15 +55,15 @@
         const Point p2(triangle.v[1].x(), triangle.v[1].y(), 
triangle.v[1].z());
         const Point p3(triangle.v[2].x(), triangle.v[2].y(), 
triangle.v[2].z());
         Point rp;
-        rp = ((AFRPinholeCamera*)context.camera)->project(p1);
+        rp = ((AFRCamera*)context.camera)->project(p1);
         tv[i].v1[0] = rp.x()*xres;
         tv[i].v1[1] = rp.y()*yres;
         tv[i].v1[2] = rp.z();
-        rp = ((AFRPinholeCamera*)context.camera)->project(p2);
+        rp = ((AFRCamera*)context.camera)->project(p2);
         tv[i].v2[0] = rp.x()*xres;
         tv[i].v2[1] = rp.y()*yres;
         tv[i].v2[2] = rp.z();
-        rp = ((AFRPinholeCamera*)context.camera)->project(p3);
+        rp = ((AFRCamera*)context.camera)->project(p3);
         tv[i].v3[0] = rp.x()*xres;
         tv[i].v3[1] = rp.y()*yres;
         tv[i].v3[2] = rp.z();

Modified: trunk/fox/afr_demo/Engine/ImageTraversers/EGSRImageTraverser.cc
==============================================================================
--- trunk/fox/afr_demo/Engine/ImageTraversers/EGSRImageTraverser.cc     
(original)
+++ trunk/fox/afr_demo/Engine/ImageTraversers/EGSRImageTraverser.cc     Thu 
Feb  9 13:14:44 2006
@@ -15,7 +15,7 @@
 #include <Interface/Renderer.h>
 #include <Interface/Context.h>
 #include <Interface/Fragment.h>
-#include <Model/Cameras/AfrPinholeCamera.h>
+#include <Model/Cameras/AFRCamera.h>
 #include <Interface/Image.h>
 #include <Interface/LoadBalancer.h>
 #include <Interface/PixelSampler.h>
@@ -179,7 +179,7 @@
   // have flag for camera and dump the camera
   fprintf(textstreamfile[myID],"\n\nbegin_camera\n");
   // print camera to file
-  ((AFRPinholeCamera*)context.camera)->writeToFile(textstreamfile[myID]);
+  ((AFRCamera*)context.camera)->writeToFile(textstreamfile[myID]);
 }
 
 void EGSRImageTraverser::setupDisplayChannel(SetupContext& context) {
@@ -420,7 +420,7 @@
       {
         const Point p(px, py, pz);
         Point rp;
-        rp = ((AFRPinholeCamera*)context.camera)->project(p);
+        rp = ((AFRCamera*)context.camera)->project(p);
         if(fabsf(rp.x()*xres- sp->sample[j].viewCoord[0])>0.001) 
sameloc=false;
         if(fabsf(rp.y()*yres- sp->sample[j].viewCoord[1])>0.001) 
sameloc=false;
         

Modified: trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverser.cc
==============================================================================
--- trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverser.cc   
(original)
+++ trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverser.cc   Thu 
Feb  9 13:14:44 2006
@@ -4,7 +4,7 @@
 #include <Interface/Renderer.h>
 #include <Interface/Context.h>
 #include <Interface/Fragment.h>
-#include <Model/Cameras/AfrPinholeCamera.h>
+#include <Model/Cameras/AFRCamera.h>
 #include <Interface/Image.h>
 #include <Interface/LoadBalancer.h>
 #include <Interface/PixelSampler.h>
@@ -188,7 +188,7 @@
   // have flag for camera and dump the camera
   fprintf(textstreamfile[myID],"\n\nbegin_camera\n");
   // print camera to file
-  ((AFRPinholeCamera*)context.camera)->writeToFile(textstreamfile[myID]);
+  ((AFRCamera*)context.camera)->writeToFile(textstreamfile[myID]);
 }
 
 void GSTAFRImageTraverser::setupBegin(SetupContext& context, int 
numChannels) {
@@ -689,7 +689,7 @@
           {
             const Point p(px, py, pz);
             Point rp;
-            rp = ((AFRPinholeCamera*)context.camera)->project(p);
+            rp = ((AFRCamera*)context.camera)->project(p);
             sp->viewCoord[0] = rp.x()*xres;
             sp->viewCoord[1] = rp.y()*yres;
             sp->viewCoord[2] = rp.z();

Modified: trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserNew.cc
==============================================================================
--- trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserNew.cc      
  (original)
+++ trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserNew.cc      
  Thu Feb  9 13:14:44 2006
@@ -4,7 +4,7 @@
 #include <Interface/Renderer.h>
 #include <Interface/Context.h>
 #include <Interface/Fragment.h>
-#include <Model/Cameras/AfrPinholeCamera.h>
+#include <Model/Cameras/AFRCamera.h>
 #include <Interface/Image.h>
 #include <Interface/LoadBalancer.h>
 #include <Interface/PixelSampler.h>
@@ -194,7 +194,7 @@
   // have flag for camera and dump the camera
   fprintf(textstreamfile[myID],"\n\nbegin_camera\n");
   // print camera to file
-  ((AFRPinholeCamera*)context.camera)->writeToFile(textstreamfile[myID]);
+  ((AFRCamera*)context.camera)->writeToFile(textstreamfile[myID]);
 }
 
 void GSTAFRImageTraverserNew::setupBegin(SetupContext& context, int 
numChannels) {
@@ -986,7 +986,7 @@
                   {
                     const Point p(px, py, pz);
                     Point rp;
-                    rp = ((AFRPinholeCamera*)context.camera)->project(p);
+                    rp = ((AFRCamera*)context.camera)->project(p);
                     sp->sample[j].viewCoord[0] = rp.x()*xres;
                     sp->sample[j].viewCoord[1] = rp.y()*yres;
                     sp->sample[j].viewCoord[2] = rp.z();

Added: 
trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.cc
==============================================================================
--- (empty file)
+++ trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.cc  
  Thu Feb  9 13:14:44 2006
@@ -0,0 +1,1052 @@
+
+#include <Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.h>
+#include <Interface/RayPacket.h>
+#include <Interface/Renderer.h>
+#include <Interface/Context.h>
+#include <Interface/Fragment.h>
+#include <Model/Cameras/AFRCamera.h>
+#include <Interface/Image.h>
+#include <Interface/LoadBalancer.h>
+#include <Interface/PixelSampler.h>
+#include <Core/Exceptions/IllegalArgument.h>
+#include <Core/Exceptions/IllegalValue.h>
+#include <Core/Exceptions/InternalError.h>
+#include <Core/Util/Args.h>
+#include <Core/Util/NotFinished.h>
+#include <Core/Thread/Mutex.h>
+#include <Core/XUtils/XHelper.h>
+#include <Interface/Fragment.h>
+
+#include <SCIRun/Core/Thread/Time.h>
+#include <cmath>
+
+#ifdef __sgi
+#include <ieeefp.h>
+#endif
+
+#include <GL/glu.h>
+#define XhairPacketSize RayPacket::MaxSize/3
+#define MAX_MIN_RATIO 0.5
+#define MAX_MERGE_SPLIT_LIMIT 256
+
+using namespace std;
+using namespace Manta;
+using namespace Manta::Afr;
+
+using SCIRun::IllegalValue;
+using SCIRun::InternalError;
+
+using namespace std;
+
+// args are the command line options, if the user wants to pas to th
+// eimage traverser look in TiledimageTraverser.cc for usage
+ImageTraverser* GSTAFRImageTraverserSTPlane::create(const vector<string>& 
args)
+{
+  return new GSTAFRImageTraverserSTPlane(args);
+}
+
+GSTAFRImageTraverserSTPlane::GSTAFRImageTraverserSTPlane(const 
vector<string>& args) :
+
+  AFRImageTraverser( args ),
+  
+  myRandomNumber( 0 ),
+  inner_loop_time( 0.016666667 ),
+  chunk_size( 256 ),
+  samplingrate( 400000 ),
+  outputStreams( false ),
+  spatialCoherence( false ),
+  numsamples_pertilevisit( 1 ),
+  num_masters( 1 ),
+  master_thread( 0 ),
+  sourcetgrads( false ),
+  afterupdateonly( false ),
+  masters_exempt( false ),
+  outputstats( false )
+  //streamlock( "streamlock" ),
+
+{
+
+  for (int i=0;i<args.size();++i) {
+    if (args[i] == "-inner") {
+      if (!getArg( i, args, inner_loop_time )) {
+        throw IllegalArgument("-inner <Real>", i, args);
+      }
+    }
+    else if (args[i] == "-chunk") {
+      if (!getArg( i, args, chunk_size )) {
+        throw IllegalArgument("-chunk <Int>", i, args);
+      }
+    }
+    else if (args[i] == "-samplingrate") {
+      if (!getArg( i, args, samplingrate )) {
+        throw IllegalArgument("-samplingrate <Int>", i, args);
+      }
+    }
+    else if (args[i] == "-groups") {
+      if (!getArg( i, args, num_masters )) {
+        throw IllegalArgument("-groups <Int>", i, args);
+      }
+    }
+    else if (args[i] == "-stream") {
+      if (!getArg( i, args, streamfilename )) {
+        throw IllegalArgument("-streamfilename <string>", i, args);
+      }
+      outputStreams = true;
+    }
+    else if (args[i] == "-spatial") {
+      if (!getArg( i, args, numsamples_pertilevisit )) {
+        throw IllegalArgument("-spatial <Int>", i, args);
+      }
+      spatialCoherence = true;
+    }
+    else if (args[i] == "-sourcetgrads") {
+      sourcetgrads = true;
+    }
+    else if (args[i] == "-afterupdateonly") {
+      afterupdateonly = true;
+    }
+    // Specify the offset into a group for the master threads
+    else if (args[i] == "-thread") {
+      if (!getArg( i, args, master_thread )) {
+        throw IllegalArgument("-thread <Int>", i, args);
+      }
+    }
+
+    // Set the master threads to be exempt from doing rendering.
+    else if (args[i] == "-exempt") {
+      masters_exempt = true;
+    }
+    else if (args[i] == "-stats") {
+      outputstats = true;
+    }
+  }
+}
+
+GSTAFRImageTraverserSTPlane::~GSTAFRImageTraverserSTPlane()
+{
+  if(myRandomNumber!=NULL) delete [] myRandomNumber;
+  // free the kdtree and queues. I suppose this will be done automatically
+  // confirm! Am I dreaming?
+}
+
+// This factory method returns a context specific to this AFRImageTraverser 
implementation.
+AFRImageTraverser::AFRContext *GSTAFRImageTraverserSTPlane::contextFactory( 
int proc, int numProc ) {
+
+  return new AFRContext;
+};
+
+
+#define DESIRED_FRAME_RATE 15
+void GSTAFRImageTraverserSTPlane::initStreams(int xres, int yres)
+{   // print the version info
+  char fname[80];
+  time_t t;
+  time(&t);
+  //streamlock.lock();
+  for(int i=0; i<num_clients; i++)
+  {
+    sprintf(fname,"%s%03d",streamfilename.c_str(),i);
+    streamfile[i] = fopen(fname,"wb");
+    sprintf(fname,"%s_text%03d",streamfilename.c_str(),i);
+    textstreamfile[i] = fopen(fname,"w");
+    sprintf(fname,"%s_tiles%03d",streamfilename.c_str(),i);
+    tilestreamfile[i] = fopen(fname,"wb");
+    fprintf(textstreamfile[i], "Version 1.5\n");
+    fprintf(textstreamfile[i],"Created on: %s", ctime(&t));
+      // print the width and height
+    fprintf(textstreamfile[i],"width %d\n", xres);
+    fprintf(textstreamfile[i],"height %d\n", yres);
+      // print the simulated frame rate
+    fprintf(textstreamfile[i],"frame_rate %d\n",DESIRED_FRAME_RATE);
+    fprintf(textstreamfile[i],"END\n");
+      //streamlock.unlock();
+    cout << "initialized stream for client " << i << endl;
+  }
+}
+
+void GSTAFRImageTraverserSTPlane::write_Tile_and_Camera(RenderContext& 
context, double currenttime)
+{
+  //streamlock.lock();
+  
+  if(!outputStreams) return;
+  int myID = context.proc;
+  fprintf(textstreamfile[myID],"\n\nbegin_tiles\n");
+  
+  // call thread's tree, print to file function
+  if(!isMaster(myID))
+  {
+    fprintf(textstreamfile[myID],"num_tiles %d\n",1);
+    fprintf(textstreamfile[myID],"timestamp %f\n",(float)currenttime);
+    TilePrintFormat tpf;
+    tpf.index = 1;
+    tpf.xGrad = tpf.yGrad = tpf.tGrad = 0.0f;
+    // find the current sampling rate for this call
+    tpf.oldest_sample_timestamp = 0.0f;
+//     // <TODO> may be we want to compoute this on a per tile basis too
+    fwrite(&tpf, sizeof(tpf), 1, tilestreamfile[myID]);
+    
+  }
+  else
+  {
+    fprintf(textstreamfile[myID],"num_tiles 
%d\n",kdtree[myID].number_of_tiles());
+    fprintf(textstreamfile[myID],"timestamp %f\n",(float)currenttime);
+    kdtree[myID].writeToFile(tilestreamfile[myID], (float)currenttime, 
samplingrate);
+  }
+  // have flag for camera and dump the camera
+  fprintf(textstreamfile[myID],"\n\nbegin_camera\n");
+  // print camera to file
+  ((AFRCamera*)context.camera)->writeToFile(textstreamfile[myID]);
+}
+
+void GSTAFRImageTraverserSTPlane::setupBegin(SetupContext& context, int 
numChannels) {
+
+  if (context.proc == 0)
+    context.loadBalancer->setupBegin(context, numChannels);
+
+  //if (getDebugWindow()) {
+  //  context.setMultipleGLWindows();
+  //  getDebugWindow()->createStatsWin( context );
+  //}
+}
+
+
+void GSTAFRImageTraverserSTPlane::setupDisplayChannel(SetupContext& context) 
{
+
+  if (context.proc != 0)
+    return;
+  
+  // Specify that the rendering pipeline should use only one image buffer.
+  //if (getDebugWindow())
+  //  context.setMultipleGLWindows();
+  numFrontXhairSamples = 5;
+  context.constrainPipelineDepth(1,1); // single buffer mode is set here
+  
+  bool stereo; // get whether it is stereo, (shoot two rays for left
+  // and right eye)
+  int i;
+  int xres,yres;
+  num_clients = context.numProcs;
+  //chunk_size = (chunk_size/num_clients)>10? chunk_size/num_clients : 10;
+  cout << "number of masters = " << num_masters << endl;
+  groupSize = new int[num_masters];
+  avgGroupSize = num_clients/num_masters;
+  for(i=0; i<num_masters-1; i++)
+    {
+      groupSize[i] = avgGroupSize;
+      cout << " number of clients for master " << i+1 << " = " << 
avgGroupSize << endl;
+    }
+  groupSize[num_masters-1] = num_clients-avgGroupSize*(num_masters-1);
+  cout << " number of clients for master " << num_masters << " = " << 
groupSize[num_masters-1] << endl;
+  
+  cout << "samplingrate = " << samplingrate << endl;
+  // Samples done.
+#ifdef __ia64__
+  samples_done = (SamplesDone *)memalign( 128, 
sizeof(SamplesDone)*num_clients );
+#else
+  samples_done = (SamplesDone *)malloc( sizeof(SamplesDone)*num_clients );
+#endif
+  memset( samples_done, 0x0, sizeof(SamplesDone)*num_clients );
+  
+  // Per master performance timer.
+  tile_refresh = new double[num_masters];
+  last_time    = new double[num_masters];
+
+  for (int i=0;i<num_masters;++i) {
+    tile_refresh[i] = 0.0;
+    last_time[i] = 0.0;
+  }
+  
+  // this will change when we can actually simulate 
+  context.getResolution(stereo, xres, yres);
+  cout << "context resolution is: " << xres << ", " << yres << endl;
+  //---------------------------------------------------------
+  // initialize random number generators for each thread.
+  //---------------------------------------------------------
+  myRandomNumber = new MT_RNG[context.numProcs];
+  for(i=0; i<context.numProcs; i++) {
+    myRandomNumber[i].seed_rng(1234*(i+1)); // just to begin give a simple 
seed
+  }
+  
+  
/////////////////////////////////////////////////////////////////////////////
+  // Create a kdtree for each master.
+  
+  //---------------------------------------------------------
+  // make our kdtree, given the resolution of image/channel
+  //---------------------------------------------------------
+  kdtree = new KDTree[num_masters];
+  updatecount = new int[num_masters];
+  chunkindex = new int[num_masters];
+  initpass   = new bool[num_masters];
+  for(i=0; i<num_masters; i++)
+    {
+      // samples_done[i] = 0;
+      initpass[i] = false;
+      kdtree[i].setAB(samplingrate);
+      kdtree[i].init(xres, yres, samplingrate, i); // initialize the tree
+      updatecount[i] = 0;
+      chunkindex[i] = 0;
+    }
+  // chunk_size = 256; // this is a fixed number as of now
+  maxQSize = qSize = (int)(samplingrate*0.1); // temporal queue size
+#ifdef RANDOM_ACCESS_TEMPORALQ
+  temporalQ        = new CSTACK<SampleSet>[num_clients];
+#else
+  temporalQ        = new CQ<SampleSet>[num_clients];
+#endif
+  outputQ[0]          = new CQ<SampleSet>[num_clients];
+  outputQ[1]          = new CQ<SampleSet>[num_clients];
+  newSampleSet     = new SampleSet* [num_clients];
+  newTempSampleSet = new SampleSet* [num_clients];
+  lastxhairindex   = new int[num_clients];
+  clientdone = new bool[num_clients];
+  if(outputstats)
+  {
+    outputfile = new FILE* [num_clients];
+    timestatslastwritten = new float[num_clients];
+  }
+  // Initialize
+  for(i = 0; i<num_clients; i++)
+    {
+      lastxhairindex[i] = 0;
+      temporalQ[i].init(qSize+1, &myRandomNumber[i]);
+      outputQ[0][i].init(chunk_size*2);
+      outputQ[1][i].init(chunk_size*2);
+      newSampleSet[i] = new SampleSet[chunk_size];
+      newTempSampleSet[i] = new SampleSet[chunk_size];
+      clientdone[i] = false;
+      if(outputstats)
+      {
+        char outname[32];
+        sprintf(outname, "gstnew_stats%03d.txt",i);
+        if((outputfile[i] = fopen(outname, "w"))==NULL)
+        {
+          cout << "cannot open "  << outname << " for stats. Exiting ..." << 
endl;
+          exit(1);
+        }
+        timestatslastwritten[i] = 0.0f;
+        fprintf(outputfile[i],"                Trace Rays             Adjust 
Tiles            Update Stats                Rates\n");
+        fprintf(outputfile[i],"currenttime   time      number         time   
  number        time     number        trace       update      adjust\n");
+        //fprintf(outputfile[i],"                Trace Rays                 
Small                  Large                Rates\n");
+        //fprintf(outputfile[i],"currenttime   time      number         time 
    number        time     number        trace       small      large\n");
+      }
+    }
+  
+    if(outputStreams)
+    {
+      spf = new SamplePrintFormat* [num_clients];
+      for(i=0; i<num_clients; i++)
+      {
+        spf[i] = new SamplePrintFormat[chunk_size*numFrontXhairSamples];
+      }
+      streamfile = (FILE**)malloc(num_clients*sizeof(FILE*));
+      tilestreamfile = (FILE**)malloc(num_clients*sizeof(FILE*));
+      textstreamfile = (FILE**)malloc(num_clients*sizeof(FILE*));
+      initStreams(xres, yres);
+    }
+}
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// RENDER CROSS HAIR  RENDER CROSS HAIR  RENDER CROSS HAIR  RENDER CROSS 
HAIR  
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+int GSTAFRImageTraverserSTPlane::renderCrossHair(const RenderContext& 
context,
+                                          AFRContext *afr_context,
+                                          int myID, 
+                                          Image *image, const int xres, 
const int yres,
+                                          SampleSet *sampleset, int sscount, 
double currenttime, bool endChunk)
+{
+  int start = lastxhairindex[myID];
+  bool validinfo[RayPacket::MaxSize];
+  //cout << "now rendering xhair " << myID << ", " << xres << ", " << yres 
<< ", " << sscount << ", " << endChunk << ", " << XhairPacketSize << endl;
+  if((sscount-start+1)<RayPacket::MaxSize && !endChunk)
+    {
+      newSampleSet[myID][sscount].reset();
+      newSampleSet[myID][sscount] = *sampleset;
+      //newSampleSet[myID][sscount].tileindex = 
kdtree[context.proc].getTileforXY(s->viewCoord[0], s->viewCoord[1]);
+      //cout << "checking ...sscount = " << sscount << ", blockstart = " << 
xhairBlockStart[myID] << endl;
+      return 0;
+    }
+  if(start>=sscount) return 0;
+  
+  Real afr_begin = afr_context->beginTraceRays();
+  
+  int myMasterID = getMasterID( myID );
+  float t = (float)currenttime;
+  int flags = RayPacket::HaveImageCoordinates | RayPacket::ConstantEye;
+  int depth = 0;
+  RayPacketData raydata;
+  Fragment frag;
+  RayPacket rays(raydata, 0, (sscount-start+1), depth, flags);
+  int i, j;
+  j = 0;
+  //cout << "size = " << (sscount-start+1) << endl;
+  for(i=start; i<=sscount; i++) {
+    double px, py;
+    if(xres > yres) // let the smaller dimension be mapped to [-1,1]
+      {
+        px = (double)(-1.0 + 
2.0*(newSampleSet[myID][i].sample[0].viewCoord[0])/(double)yres); 
+        py = (double)(-1.0 + 
2.0*(newSampleSet[myID][i].sample[0].viewCoord[1])/(double)yres);
+      }
+    else
+      {
+        px = (double)(-1.0 + 
2.0*(newSampleSet[myID][i].sample[0].viewCoord[0])/(double)xres); 
+        py = (double)(-1.0 + 
2.0*(newSampleSet[myID][i].sample[0].viewCoord[1])/(double)xres);
+      }
+    // Specify the pixel.
+    rays.setPixel(j, 0, px, py);
+    frag.addElement((int)(newSampleSet[myID][i].sample[0].viewCoord[0]), 
(int)(newSampleSet[myID][i].sample[0].viewCoord[1]), 0);
+    j++;
+  }
+
+  
/////////////////////////////////////////////////////////////////////////////
+  // Trace the rays.  The results will automatically go into the fragment
+
+  traceRays(context, afr_context, rays, xres, yres, validinfo);
+  afr_context->endTraceRays( afr_begin , (sscount-start+1));
+  
/////////////////////////////////////////////////////////////////////////////
+  // okay now copy from fragment to temporalQ
+  j = 0;
+  for(i=start; i<=sscount; i++) {
+     Color clr = rays.getColor(j);
+    RGBColor tempcol = clr.convertRGB();
+    Point p = rays.getHitPosition(j);
+    //cout << "processing sampleset " << i << endl;
+    newSampleSet[myID][i].set( numFrontXhairSamples,
+                               newSampleSet[myID][i].sample[0].viewCoord[0],
+                               newSampleSet[myID][i].sample[0].viewCoord[1], 
t,
+                               p.x(), p.y(), p.z(),
+                               tempcol.r(), tempcol.g(), tempcol.b(), 
validinfo[j] );
+    newSampleSet[myID][i].computeGradients(t);
+    //cout << "grad info <complete>: " << newSampleSet[myID][i].xgrad << ", "
+    //     << newSampleSet[myID][i].ygrad << ", " 
+    //     << newSampleSet[myID][i].tgrad << endl;
+    //samples_done[myID].addOne();
+    frag.setColor(j, clr);
+    j++;
+  }
+  image->set( frag );
+  lastxhairindex[myID] = sscount+1;
+  //cout << "done one xhairBlock" << endl;
+  return (sscount-start+1);
+}
+
+
+void GSTAFRImageTraverserSTPlane::addEdgeXhair(const RenderContext& context, 
float v1[3], float v2[3], SampleSet *edgesampleset, int &edgeXhairIndex, int 
xres, int yres, Timestamp tstamp, float spatial_extent)
+{
+  float ex, ey, ez;
+  float ival;// = myRandomNumber[context.proc].genfrand();
+  //if(ival<0.01) ival = 0.01;
+  //if(ival>0.99) ival = 0.99;
+  ival = 0.5;
+  ex =v1[0]+(v2[0]-v1[0])*ival;
+  ey =v1[1]+(v2[1]-v1[1])*ival;
+  //ez =v1[2]+(v2[2]-v1[2])*ival;
+  // project into screenspace
+  /*const Point p(ex, ey, ez);
+  Point rp;
+  rp = context.camera->project(p);
+  ex = rp.x()*xres;
+  ey = rp.y()*yres;
+  ez = rp.z();*/
+  if(ex<xres && ex>=0 && ey<yres && ey>=0)// && ez<=1.0)
+  {
+    // add to crosshair list
+  //ex = myRandomNumber[context.proc].genfrand()*xres;
+  //ey = myRandomNumber[context.proc].genfrand()*yres;
+  //if(ex>=xres) ex = xres;
+  //if(ex>=yres) ey = yres;
+    edgesampleset[edgeXhairIndex].setTempXhair(ex, ey, xres, yres, 1, 
tstamp, myRandomNumber[context.proc], spatial_extent);
+    edgesampleset[edgeXhairIndex].edgevertex1[0] = v1[0];
+    edgesampleset[edgeXhairIndex].edgevertex1[1] = v1[1];
+    edgesampleset[edgeXhairIndex].edgevertex1[2] = v1[2];
+    edgesampleset[edgeXhairIndex].edgevertex2[0] = v2[0];
+    edgesampleset[edgeXhairIndex].edgevertex2[1] = v2[1];
+    edgesampleset[edgeXhairIndex].edgevertex2[2] = v2[2];
+    edgeXhairIndex++;
+    samples_done[context.proc].addFive();
+  }
+}
+
+void GSTAFRImageTraverserSTPlane::setRayPacket(const RenderContext& context, 
AFRContext *afr_context, Image *image, SampleSet* edgesampleset, int size, 
Timestamp tstamp, int xres, int yres)
+{
+  int i, j;
+  int age = 1;
+  Real oldtstamp = ((const AFRCamera*)context.camera)->getOldCamTime(1);
+  float gradThreshold=0.1;
+  int myMasterID = getMasterID( context.proc );
+  int flags = RayPacket::HaveImageCoordinates | RayPacket::ConstantEye;
+  int depth = 0;
+  RayPacketData raydata;
+  Fragment frag;
+  RayPacket rays(raydata, 0, size*numFrontXhairSamples, depth, flags);
+  bool validinfo[RayPacket::MaxSize];
+  //printf("edgecode = %d, size = %d\n", edgecode, size);
+  for(i=0; i<size; i++)
+  {
+    for(j=0; j<numFrontXhairSamples; j++)
+    {
+            // normalized
+      double px, py;
+      if(xres>yres) // let the smaller dimension be mapped to [-1,1]
+      {
+        px = (double)(-1.0 + 
2.0*((double)edgesampleset[i].sample[j].viewCoord[0])/(double)yres);
+        py = (double)(-1.0 + 
2.0*((double)edgesampleset[i].sample[j].viewCoord[1])/(double)yres);
+      }
+      else
+      {
+        px = (double)(-1.0 + 
2.0*((double)edgesampleset[i].sample[j].viewCoord[0])/(double)xres);
+        py = (double)(-1.0 + 
2.0*((double)edgesampleset[i].sample[j].viewCoord[1])/(double)xres);
+      }
+      rays.setPixel(i*numFrontXhairSamples+j, 0, px, py);
+      frag.addElement((int)(edgesampleset[i].sample[j].viewCoord[0]), 
(int)(edgesampleset[i].sample[j].viewCoord[1]), 0);
+    }
+  }
+  Real afr_begin = afr_context->beginTraceRays();
+  traceRays(context, afr_context, rays, xres, yres, validinfo);
+  afr_context->endTraceRays( afr_begin,numFrontXhairSamples*size);
+  int k=-1;
+  for(i=0;i<size;i++)
+  {
+    for(j=0; j<numFrontXhairSamples; j++)
+    {
+      int rayindex = i*numFrontXhairSamples+j;
+      Color clr = rays.getColor(rayindex);
+      RGBColor tempcol = clr.convertRGB();
+      Point p = rays.getHitPosition(rayindex);
+      edgesampleset[i].set(j,
+                           edgesampleset[i].sample[j].viewCoord[0],
+                           edgesampleset[i].sample[j].viewCoord[1],
+                           tstamp,
+                           p.x(), p.y(), p.z(),
+                           tempcol.r(), tempcol.g(), tempcol.b(),
+                           validinfo[rayindex] );
+      frag.setColor(rayindex, clr);
+    }
+    edgesampleset[i].computeGradients(tstamp);
+    temporalQ[context.proc].qInsert(&edgesampleset[i], 
&myRandomNumber[context.proc]);
+    if(!afterupdateonly)
+    {
+      
outputQ[chunkindex[myMasterID]][context.proc].qInsert(&edgesampleset[i]);
+    }
+    // set the planes
+    if(edgesampleset[i].hiGrad(gradThreshold))
+    {
+      float ex[3], ey[3], ez[3];
+      ex[0] = edgesampleset[i].edgevertex1[0];
+      ey[0] = edgesampleset[i].edgevertex1[1];
+      ez[0] = tstamp;
+      
+      ex[1] = edgesampleset[i].edgevertex2[0];
+      ey[1] = edgesampleset[i].edgevertex2[1];
+      ez[1] = tstamp;
+      if(tstamp-oldtstamp>0.1)
+      {
+        ex[2] = ex[0] + (ex[1]-ex[0])*0.5;
+        ey[2] = ey[0] + (ey[1]-ey[0])*0.5;
+        ez[2] = tstamp-0.1;
+      }
+      else
+      {
+          Point rp2;
+          ex[2] = edgesampleset[i].sample[CENTER_SAMPLE].worldCoord[0];
+          ey[2] = edgesampleset[i].sample[CENTER_SAMPLE].worldCoord[1];
+          ez[2] = edgesampleset[i].sample[CENTER_SAMPLE].worldCoord[2];
+          const Point p2(ex[2], ey[2], ez[2]);
+          const Point p3(ex[2], ey[2], ez[2]);
+          Point rp3 = ((AFRCamera*)context.camera)->project(p3, 0);
+          rp2 = ((AFRCamera*)context.camera)->project(p2, 1);
+          printf("point moved from %f,%f to %f,%f, recentcam says %f, %f\n", 
edgesampleset[i].sample[CENTER_SAMPLE].viewCoord[0], 
edgesampleset[i].sample[CENTER_SAMPLE].viewCoord[1], rp2.x()*xres, 
rp2.y()*yres, rp3.x()*xres, rp3.y()*yres);
+          ex[2] = rp2.x()*xres;
+          ey[2] = rp2.y()*yres;
+          ez[2] = oldtstamp;
+      }
+        // now get the plane from three points
+      edgesampleset[i].setPlane(ex, ey, ez);
+    }
+    else
+    {
+      edgesampleset[i].unsetPlane();
+    }
+  }
+  image->set(frag);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// Render all of samples in a fragment of the chunk.
+///////////////////////////////////////////////////////////////////////////////
+void GSTAFRImageTraverserSTPlane::renderChunk(const RenderContext& context,
+                                       AFRContext *afr_context,
+                                       Image* image,
+                                       int xres, int yres, double 
currenttime)
+{
+  //cout << "inside renderChunk " << endl;
+  
+  // renders the fragment by jittering it and stores result in temporalQ
+  int flags = RayPacket::HaveImageCoordinates | RayPacket::ConstantEye;
+  int i = 0, j, f;
+  int myID = context.proc;
+  int myMasterID = getMasterID( context.proc );
+  int fsize = chunk_size;
+  //float tilearea;
+  //int avgtilesize = 64;//kdtree[myMasterID].getAvgTileSize();
+  //cout << "avgtilesize = " << avgtilesize << endl;
+  float tstamp = (float)currenttime;
+  bool validinfo[RayPacket::MaxSize];
+  triangleVertices tv[RayPacket::MaxSize];
+  SampleSet edgeSampleSet[3][6], mainSampleSet[6];
+  int edgexhairindex[3];
+  if(initpass[myMasterID])
+    {
+      fsize = (chunk_size>(qSize-temporalQ[myID].getN()))? chunk_size : 
qSize-temporalQ[myID].getN();
+      //if((fsize + temporalQ[myID].getN()) > temporalQ[myID].getMaxSize())
+      //  fsize = temporalQ[myID].getMaxSize() - temporalQ[myID].getN() -1;
+      //cout << "fsize = " << fsize << endl;
+    }
+  fsize = chunk_size*(fsize/chunk_size);
+  //Sample newSample[RayPacket::MaxSize];
+  //cout << "fsize = " << fsize << ", myID = " << myID << endl;
+
+  
/////////////////////////////////////////////////////////////////////////////
+  // Create ray packets.
+  int raypacketsize = 
numFrontXhairSamples*(RayPacket::MaxSize/numFrontXhairSamples);
+  //cout << "raypacketsize = " << raypacketsize << endl;
+  int numXhairPerRayPack = raypacketsize/numFrontXhairSamples;
+
+  // Make sure that we don't overflow newTempSampleSet
+  Real afr_begin;
+  int xhairsdonethisloop=0;
+  int ncsize = numXhairPerRayPack*(chunk_size/numXhairPerRayPack);
+  fsize = numXhairPerRayPack*(fsize/numXhairPerRayPack);
+  for(int g=0; g<fsize; g+=ncsize)
+  {
+    int csize = ncsize;
+    if(csize>(fsize-g))
+      csize = fsize-g;
+    xhairsdonethisloop=0;
+    for(f=0;f<csize;f+=xhairsdonethisloop)
+    {
+      bool doedgesampling = (myRandomNumber[myID].genfrand()<0.25);
+      int size = numXhairPerRayPack;
+      edgexhairindex[0] = edgexhairindex[1] = edgexhairindex[2] = 0;
+      if(size>(csize-f))
+        size = csize-f;
+      // Create a ray packet for set of crosshairs
+      int depth = 0;
+      RayPacketData raydata;
+      Fragment frag;
+      RayPacket rays(raydata, 0, numXhairPerRayPack*numFrontXhairSamples, 
depth, flags);
+      int cx, cy, ox, oy;
+      int tindex = kdtree[myMasterID].getRandomTile(myRandomNumber[myID]);
+      kdtree[myMasterID].getRandomSamplefromTile(tindex, cx, cy, 
myRandomNumber[myID]);
+      int spatialcount=0;
+      float spatdist = 1.0;
+      for(i=0; i<size; i++)
+      {
+        double jitterx, jittery;
+        jitterx = myRandomNumber[myID].genfrand()-0.5;
+        jittery = myRandomNumber[myID].genfrand()-0.5;
+        int pssindex = (f+i);
+       
+        mainSampleSet[i].setTempXhair((cx+jitterx), (cy+jittery), xres, 
yres, tindex, tstamp, myRandomNumber[myID], spatdist);
+        for(j=0; j<numFrontXhairSamples; j++)
+        {
+          // normalized
+          double px, py;
+        
+          if(xres>yres) // let the smaller dimension be mapped to [-1,1]
+          {
+            px = (double)(-1.0 + 
2.0*((double)mainSampleSet[i].sample[j].viewCoord[0])/(double)yres);
+            py = (double)(-1.0 + 
2.0*((double)mainSampleSet[i].sample[j].viewCoord[1])/(double)yres);
+          }
+          else
+          {
+            px = (double)(-1.0 + 
2.0*((double)mainSampleSet[i].sample[j].viewCoord[0])/(double)xres);
+            py = (double)(-1.0 + 
2.0*((double)mainSampleSet[i].sample[j].viewCoord[1])/(double)xres);
+          }
+          // samples_done[context.proc] ++;
+          //samples_done[myID].addOne();
+          // Specify the position and color pointer for the packet element.
+          rays.setPixel(i*numFrontXhairSamples+j, 0, px, py);
+          frag.addElement((int)(mainSampleSet[i].sample[j].viewCoord[0]), 
(int)(mainSampleSet[i].sample[j].viewCoord[1]), 0);
+          spatialcount++;
+        }
+        tindex = kdtree[myMasterID].getRandomTile(myRandomNumber[myID]);
+        kdtree[myMasterID].getRandomSamplefromTile(tindex, cx, cy, 
myRandomNumber[myID]);
+        xhairsdonethisloop++;
+      }
+      afr_begin = afr_context->beginTraceRays();
+      
//////////////////////////////////////////////////////////////////////////
+      // Trace the rays.  The results will automatically go into the fragment
+      if(doedgesampling)
+        traceRays(context, afr_context, rays, xres, yres, validinfo, tv);
+      else
+        traceRays(context, afr_context, rays, xres, yres, validinfo);
+      afr_context->endTraceRays( afr_begin , 
numXhairPerRayPack*numFrontXhairSamples);
+      
///////////////////////////////////////////////////////////////////////////
+      // okay now copy from fragment to temporalQ
+      for(i=0;i<size;i++)
+      {
+        for(j=0; j<numFrontXhairSamples; j++)
+        {
+          int rayindex = i*numFrontXhairSamples+j;
+          Color clr = rays.getColor(rayindex);
+          RGBColor tempcol = clr.convertRGB();
+          Point p = rays.getHitPosition(rayindex);
+          mainSampleSet[i].set(j,
+                               mainSampleSet[i].sample[j].viewCoord[0],
+                               mainSampleSet[i].sample[j].viewCoord[1],
+                               tstamp,
+                               p.x(), p.y(), p.z(),
+                               tempcol.r(), tempcol.g(), tempcol.b(), 
validinfo[rayindex] );
+          // Skip reconstruction and set the image pixel.
+          frag.setColor(rayindex, clr);
+        }
+  
/////////////////////////////////////////////////////////////////////////////
+        mainSampleSet[i].computeGradients(tstamp);
+        samples_done[myID].addFive();
+        temporalQ[myID].qInsert(&mainSampleSet[i], &myRandomNumber[myID]);
+        if(!afterupdateonly)
+        {
+          
outputQ[chunkindex[myMasterID]][context.proc].qInsert(&mainSampleSet[i]);
+        }
+        // now we have to retrieve the triangles associated with these 
crosshairs and make 3x more xhairs
+        // get one midpoint
+        if(doedgesampling)
+        {
+          if(validinfo[i*numFrontXhairSamples])
+          {
+            float smallx = ((tv[i*numFrontXhairSamples].v2[0] - 
tv[i*numFrontXhairSamples].v1[0])>
+                (tv[i*numFrontXhairSamples].v3[0] - 
tv[i*numFrontXhairSamples].v1[0]))?
+                (tv[i*numFrontXhairSamples].v3[0] - 
tv[i*numFrontXhairSamples].v1[0]) :
+                (tv[i*numFrontXhairSamples].v2[0] - 
tv[i*numFrontXhairSamples].v1[0]);
+            float smally = ((tv[i*numFrontXhairSamples].v2[1] - 
tv[i*numFrontXhairSamples].v1[1])>
+                (tv[i*numFrontXhairSamples].v3[1] - 
tv[i*numFrontXhairSamples].v1[1]))?
+                (tv[i*numFrontXhairSamples].v3[1] - 
tv[i*numFrontXhairSamples].v1[1]) :
+                (tv[i*numFrontXhairSamples].v2[1] - 
tv[i*numFrontXhairSamples].v1[1]);
+            float smalldim = (smallx>smally)? smally/4.0 : smallx/4.0;
+            addEdgeXhair(context, tv[i*numFrontXhairSamples].v1, 
tv[i*numFrontXhairSamples].v2, edgeSampleSet[0], edgexhairindex[0], xres, 
yres, tstamp, smalldim);
+            addEdgeXhair(context, tv[i*numFrontXhairSamples].v2, 
tv[i*numFrontXhairSamples].v3, edgeSampleSet[1], edgexhairindex[1], xres, 
yres, tstamp, smalldim);
+            addEdgeXhair(context, tv[i*numFrontXhairSamples].v3, 
tv[i*numFrontXhairSamples].v1, edgeSampleSet[2], edgexhairindex[2], xres, 
yres, tstamp, smalldim);
+          }
+        }
+      }
+      image->set(frag);
+      if(doedgesampling)
+      {
+          //cout << "indices = " << edgexhairindex[0] << ", " << 
edgexhairindex[1] << ", " << edgexhairindex[2] << endl;
+        if(edgexhairindex[0]>0) setRayPacket(context, afr_context, image, 
edgeSampleSet[0], edgexhairindex[0], tstamp, xres, yres);
+        if(edgexhairindex[1]>0) setRayPacket(context, afr_context, image, 
edgeSampleSet[1], edgexhairindex[1], tstamp, xres, yres);
+        if(edgexhairindex[2]>0) setRayPacket(context, afr_context, image, 
edgeSampleSet[2], edgexhairindex[2], tstamp, xres, yres);
+    
+        xhairsdonethisloop += edgexhairindex[0] + edgexhairindex[1] + 
edgexhairindex[2];
+      }
+      if(outputStreams)
+      {
+        int k,l, samplescopied=0;
+        for(i=0;i<size;i++)
+        {
+          // write streams here
+          for(int l=0; l<5; l++)
+          {
+            mainSampleSet[i].sample[l].copySPF(&spf[myID][samplescopied]);
+            samplescopied++;
+          }
+          if(doedgesampling)
+          for(k=0; k<3; k++)
+          if(i<edgexhairindex[k])
+          {
+            for(int l=0; l<5; l++)
+            {
+              
edgeSampleSet[k][i].sample[l].copySPF(&spf[myID][samplescopied]);
+              samplescopied++;
+            }
+          }
+        }
+        fwrite(spf[myID], sizeof(SamplePrintFormat), samplescopied, 
streamfile[myID]);
+      }
+    }
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This method implements the master thread functionality.
+///////////////////////////////////////////////////////////////////////////////
+void GSTAFRImageTraverserSTPlane::masterTask(const RenderContext& context, 
AFRContext *afr_context, Image* image, double currenttime) {
+  
+  //image->setValid( true );
+  //return;
+  // Check to see if the master thread called this function.
+ // cout << "thread " << context.proc << " master status is " << isMaster( 
context.proc ) << endl;
+  if (isMaster( context.proc ))
+  {
+    
///////////////////////////////////////////////////////////////////////////
+    // update kdtree based on previous results from the client threads
+    // Get the current image resolution.
+    bool stereo;
+    int i;
+    int xres, yres;
+    Real afr_begin = afr_context->beginUpdateStats();
+    image->getResolution(stereo, xres, yres);
+    // get the masterID
+    int masterID = context.proc/avgGroupSize;
+    
///////////////////////////////////////////////////////////////////////////
+    // Determine the refresh rate.
+    double current_time = SCIRun::Time::currentSeconds();
+    kdtree[masterID].setAB(samplingrate);
+    tile_refresh[masterID] = (current_time - last_time[masterID]);
+    last_time[masterID] = current_time;
+    // for clients context.proc+1 to context.proc+groupSize[masterID]
+    // read output queue of all clients and update the kdtree[masterID]
+
+    int first_client = 
groupSize[masterID]*(context.proc/groupSize[masterID]);
+    int last_client = first_client + groupSize[masterID];
+    
+    int masterchunkindex = chunkindex[masterID];
+    chunkindex[masterID] = (masterchunkindex==0)? 1 : 0;
+    int count = 0;
+    for(i= first_client; i<last_client; i++)
+      clientdone[i] = false;
+    for(int k=0; k<chunk_size*2; k++)
+      for(i= first_client; i<last_client; i++)
+      {
+          if(clientdone[i] || isExempt(i)) continue;
+          if(outputQ[masterchunkindex][i].isEmpty()) 
+          {
+            clientdone[i] = true;
+            continue;
+          }
+          SampleSet *npss = outputQ[masterchunkindex][i].qDelete();
+          if(npss==NULL)
+          {
+            clientdone[i] = true;
+            continue;
+          }
+          if(npss->complete)
+          {
+            count++;
+            updatecount[masterID]++;
+          }
+          else
+          {
+            count += 3;
+            updatecount[masterID]+=3;
+          }
+          kdtree[masterID].updateStatsAddSampleSetReversed(npss, 
(float)currenttime, samplingrate, sourcetgrads);
+      }
+    afr_context->endUpdateStats( afr_begin , count );
+    // adjust tiles based on current status
+    if(initpass[masterID]) {
+      // adjust tiles based on current status
+      Real afr_begin = afr_context->beginAdjustTiles();
+      adjustTiles(afr_context, masterID, (float)currenttime);
+      afr_context->endAdjustTiles( afr_begin );
+      //cout << "updateCount says: " << updatecount[masterID] << endl;
+    }
+    else if (getSamplesDone()>= (xres*yres)) {
+      initpass[masterID] = true;
+      std::cerr << "Master Thread: " << masterID << " initialized" << 
std::endl;    
+    }
+    image->setValid( true );
+  }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// This method implements the master thread functionality.
+///////////////////////////////////////////////////////////////////////////////
+void GSTAFRImageTraverserSTPlane::clientTask(const RenderContext& context, 
AFRContext *afr_context, Image* image, double currenttime) {
+
+  //cout << "inside clientThread for frametype " << frametype[context.proc] 
<< endl;
+  bool stereo;
+  int xres, yres;
+  image->getResolution(stereo, xres, yres);
+  int myID = context.proc;
+  int myMasterID = getMasterID( myID );
+  //cout << "client " << myID << " belongs to master " << myMasterID << endl;
+  Sample s;
+  
+  // render the chunk
+  renderChunk(context, afr_context, image, xres, yres, currenttime);
+  //renderSpecialChunk(context, afr_context, image, xres, yres, currenttime);
+  int xhairRendered = 0;
+  if(initpass[myMasterID])
+    {
+      // initialization is done so we can reproject one chunk worth
+      int i, j;
+      int sscount=0;
+      lastxhairindex[myID] = 0;
+      SampleSet *sp;
+      //cout << "now making xhairs" << endl;
+      int fsize = temporalQ[myID].getN()-qSize;
+      for(i=0; i<fsize; i++)
+        temporalQ[myID].qDelete(&myRandomNumber[myID]);
+      
+      //cout << "fsize = " << fsize << endl;
+      fsize = (chunk_size<temporalQ[myID].getN())? chunk_size : 
temporalQ[myID].getN();
+      for(i=0; i<fsize; i++) {
+    
+        sp = temporalQ[myID].qDelete(&myRandomNumber[myID]);
+        if(sp!=NULL) {
+          Manta::Real px, py, pz;
+          for(j=0; j<numFrontXhairSamples; j++)
+            {
+              px = sp->sample[j].worldCoord[0];
+              py = sp->sample[j].worldCoord[1];
+              pz = sp->sample[j].worldCoord[2];
+        
+              //if the point is INF, no need to reproject as it will remain 
the same
+#ifdef __sgi
+              if(finite(px) && finite(py) && finite(pz))
+#else
+                if(!isinf(px) && !isinf(py) && !isinf(pz))
+#endif
+                  {
+                    const Point p(px, py, pz);
+                    Point rp;
+                    rp = ((AFRCamera*)context.camera)->project(p);
+                    /*printf("in clienttask: reprojected %f,%f to %f,%f\n",
+                           sp->sample[j].viewCoord[0],
+                           sp->sample[j].viewCoord[1],
+                    rp.x()*xres, rp.y()*yres);*/
+                    sp->sample[j].viewCoord[0] = rp.x()*xres;
+                    sp->sample[j].viewCoord[1] = rp.y()*yres;
+                    sp->sample[j].viewCoord[2] = rp.z();
+                  }
+            }
+          sp->viewX = sp->sample[CENTER_SAMPLE].viewCoord[0];
+          sp->viewY = sp->sample[CENTER_SAMPLE].viewCoord[1];
+          sp->viewZ = sp->sample[CENTER_SAMPLE].viewCoord[2];
+          if(sp->sample[0].viewCoord[0]<xres && 
sp->sample[0].viewCoord[0]>=0 
+             && sp->sample[0].viewCoord[1]<yres && 
sp->sample[0].viewCoord[1]>=0
+             && sp->sample[0].viewCoord[2]<=1.0)
+            {
+              xhairRendered += renderCrossHair(context, afr_context, myID, 
image, xres, yres, sp, sscount, currenttime);
+              sscount++;
+            }
+        }
+        else break;
+      }
+      xhairRendered += renderCrossHair(context, afr_context, myID, image, 
xres, yres, sp, sscount-1, currenttime, true);
+      // write to outputQ
+      for(i=0; i<xhairRendered; i++)
+      {
+          samples_done[myID].addOne();
+          outputQ[chunkindex[myMasterID]][myID].qInsert( 
&newSampleSet[myID][i] );
+      }
+      // write to file 
+      if(outputStreams)
+      {
+        for(i=0; i<xhairRendered; i++)
+        {
+          
newSampleSet[myID][i].sample[TEMPORAL_SAMPLE].copySPF(&spf[myID][i]);
+        }
+        
fwrite(spf[myID],sizeof(SamplePrintFormat),xhairRendered,streamfile[myID]);
+      }
+    }
+}
+
+//#define USE_BRUTE_FORCE
+///////////////////////////////////////////////////////////////////////////////
+// This method adjusts the kdtree-cut by either merging nodes along the cut
+// or splitting nodes and adding their children to the cut.
+///////////////////////////////////////////////////////////////////////////////
+void GSTAFRImageTraverserSTPlane::adjustTiles( AFRContext *afr_context, int 
id, Timestamp currenttime)
+{
+  float minError, maxError;
+  int count, minIndex, maxIndex;
+  int required_tiles = kdtree[id].getMaxTiles();
+  //cout << "minError = " << minError << ", maxError = " << maxError << endl;
+  //kdtree[id].ageAllStats(samplingrate, currenttime);
+  if(kdtree[id].number_of_tiles()!=required_tiles)
+  {
+    do
+    {
+      while(kdtree[id].number_of_tiles()>required_tiles)
+      {
+#ifdef USE_BRUTE_FORCE
+        kdtree[id].bruteforceminmax(minIndex, maxIndex, minError,maxError);
+        kdtree[id].merge(minIndex, currenttime, samplingrate);
+#else
+        kdtree[id].merge(kdtree[id].getminErrorParentTile(), currenttime, 
samplingrate);
+#endif
+        //cout << " merge " << endl;
+        //kdtree[id].consistencycheck();
+      }
+      while(kdtree[id].number_of_tiles()<required_tiles)
+      {
+#ifdef USE_BRUTE_FORCE
+        kdtree[id].bruteforceminmax(minIndex, maxIndex, minError,maxError);
+        kdtree[id].split(maxIndex, currenttime, samplingrate);
+#else
+        kdtree[id].split(kdtree[id].getmaxErrorTile(), currenttime, 
samplingrate);
+#endif
+        //cout << " split " << endl;
+        //kdtree[id].consistencycheck();
+      }
+    }
+    while(kdtree[id].number_of_tiles()!=required_tiles);
+  }
+#ifdef USE_BRUTE_FORCE
+  kdtree[id].bruteforceminmax(minIndex, maxIndex, minError,maxError);
+#else
+  minError = kdtree[id].getminError();
+  maxError = kdtree[id].getmaxError();
+#endif
+  //cout << "minError = " << minError << ", maxError = " << maxError << endl;
+  if(maxError>0.01 && minError/maxError<MAX_MIN_RATIO)
+{
+    //cout << "minError = " << minError << ", maxError = " << maxError << 
endl;
+  count = 0;
+  do
+  {
+      //for(int i=0; i<128; i++)
+    {
+#ifdef USE_BRUTE_FORCE
+        kdtree[id].merge(minIndex, currenttime, samplingrate);
+        kdtree[id].bruteforceminmax(minIndex, maxIndex, minError,maxError);
+#else
+        kdtree[id].merge(kdtree[id].getminErrorParentTile(), currenttime, 
samplingrate);
+#endif
+        //cout << " merge " << endl;
+        //kdtree[id].consistencycheck();
+    }
+    count++;
+      //for(int i=0; i<128; i++)
+    {
+#ifdef USE_BRUTE_FORCE
+        kdtree[id].split(maxIndex, currenttime, samplingrate);
+        kdtree[id].bruteforceminmax(minIndex, maxIndex, minError,maxError);
+#else
+        kdtree[id].split(kdtree[id].getmaxErrorTile(), currenttime, 
samplingrate);
+#endif
+        //cout << " split " << endl;
+        //kdtree[id].consistencycheck();
+    }
+    count++;
+#ifndef USE_BRUTE_FORCE
+      minError = kdtree[id].getminError();
+      maxError = kdtree[id].getmaxError();
+#endif
+      //cout << "minError = " << minError << ", maxError = " << maxError << 
endl;
+  }
+  while(minError/maxError<MAX_MIN_RATIO && count<MAX_MERGE_SPLIT_LIMIT);
+}
+  //kdtree[id].showErrors();
+}
+
+void GSTAFRImageTraverserSTPlane::outputStats(int myID, AFRContext 
*afr_context)
+{
+  if(outputstats)
+  {
+    int myMasterID = getMasterID( myID );
+    float t = SCIRun::Time::currentSeconds();
+    if((t-timestatslastwritten[myID])>=5.0f)
+    {
+      timestatslastwritten[myID] = t;
+      afr_context->writetofile(outputfile[myID], t);
+    }
+  }
+}

Added: trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.h
==============================================================================
--- (empty file)
+++ trunk/fox/afr_demo/Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.h   
  Thu Feb  9 13:14:44 2006
@@ -0,0 +1,222 @@
+
+#ifndef Manta_Engine_GSTAFRImageTraverserSTPlane_h
+#define Manta_Engine_GSTAFRImageTraverserSTPlane_h
+
+#include <SCIRun/Core/Thread/Time.h>
+#include <SCIRun/Core/Thread/Thread.h>
+
+#include <Interface/ImageTraverser.h>
+#include <Interface/Fragment.h>
+#include <sgi_stl_warnings_off.h>
+#include <string>
+#include <vector>
+#include <sgi_stl_warnings_on.h>
+#include <Engine/ImageTraversers/AFRImageTraverser.h>
+#include <Engine/ImageTraversers/AFR/kdtree.h>
+#include <Engine/ImageTraversers/AFR/CQ.h>
+#include <Engine/ImageTraversers/AFR/sample.h>
+#include <Interface/XWindow.h>
+#include <Model/Cameras/PinholeCamera.h>
+//#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <GL/glx.h>
+
+#ifdef __ia64__
+#include <malloc.h>
+#include <ia64intrin.h>
+#endif
+
+//#define RANDOM_ACCESS_TEMPORALQ
+namespace Manta {
+
+  using namespace std;
+  
+  namespace Afr {
+
+    class GSTAFRImageTraverserSTPlane : public AFRImageTraverser {
+    
+      friend class AFRPipeline;
+    
+    public:
+    
+      GSTAFRImageTraverserSTPlane(const vector<string>& args);
+    
+      virtual ~GSTAFRImageTraverserSTPlane();
+
+      virtual AFRContext *contextFactory( int proc, int numProc );      
+      
+      virtual void setupBegin(SetupContext&, int numChannels);
+      virtual void setupDisplayChannel(SetupContext&);
+      virtual void setupFrame(const RenderContext& context) { /*Undefined 
for AFRPipeline.*/ };
+      virtual void renderImage(const RenderContext& context, Image* image) { 
/*Undefined for AFRPipeline. */ };
+      
+      void renderChunk(const RenderContext& context,
+                       AFRContext *afr_context,
+                       Image* image,
+                       int xres, int yres, double currenttime);
+
+      int renderCrossHair(const RenderContext& context,
+                          AFRContext *afr_context,
+                          int myID,
+                          Image *image, const int xres, const int yres,
+                          SampleSet *sampleset, const int sscount, double 
currenttime,
+                          bool endChunk=false);
+      
+      // Master thread task.
+      void masterTask(const RenderContext& context, AFRContext *afr_context, 
Image* image, double currenttime);
+      
+      // Sampler/Renderer task.
+      void clientTask(const RenderContext& context, AFRContext *afr_context, 
Image* image, double currenttime);
+      void addEdgeXhair(const RenderContext& context, float v1[3], float 
v2[3], SampleSet *edgeSampleSet, int &edgeXhairIndex, int xres, int yres, 
Timestamp tstamp, float spatial_extent);
+      void setRayPacket(const RenderContext& context, AFRContext 
*afr_context, Image *image, SampleSet* edgesampleset, int size, Timestamp 
tstamp, int xres, int yres);
+      inline bool isMaster          (int id) { return 
((id%avgGroupSize)==master_thread); }
+      inline int  getMasterThreadNum(int id) { return 
(id/avgGroupSize)+master_thread; }
+      inline int  getMasterID       (int id) { return (id/avgGroupSize); }
+      inline bool isWithExempt() { return masters_exempt; };
+      // Accessors used by pipeline.
+      virtual bool isExempt( int client ) { return masters_exempt && 
isMaster( client ); };
+      virtual int  totalExempt() { return (masters_exempt) ? num_masters : 
0; }
+      
+      // Update kdtree-cut.
+      void adjustTiles( AFRContext *afr_context, int id, Timestamp 
currenttime);
+      void createStatsWin();
+      void display_stats();
+      void toggleTileDisplayMode();
+      void initStreams(int xres, int yres);
+      void write_Tile_and_Camera(RenderContext& context, double currenttime);
+      void outputStats(int myID, AFRContext *afr_context);
+      int setSamplingRate(unsigned int srate)
+      {
+        static unsigned int numUpdates=0;
+        //cout << "srate = " << srate << endl;
+        float rate = (float)srate;//(float)num_clients;
+        if(numUpdates==0)
+          samplingrate = (int)rate;
+        else
+          {
+            samplingrate = (int)(((float)samplingrate*numUpdates + 
rate)/(float)(numUpdates+1));
+          }
+        numUpdates++;
+        if(numUpdates%1000==0)
+          {
+            qSize = (int)(samplingrate*0.1);
+            if(qSize>maxQSize) qSize = maxQSize;
+          }  
+      }
+      static ImageTraverser* create(const vector<string>& args);
+
+      // Accessors, used by AFRDebugWindow
+      inline int    getSamplingRate()               { return samplingrate; };
+     
+      inline KDTree *getKdtree( int client )        { return 
&kdtree[client]; };
+      
+    private:
+      GSTAFRImageTraverserSTPlane(const GSTAFRImageTraverserSTPlane&);
+      GSTAFRImageTraverserSTPlane& operator=(const 
GSTAFRImageTraverserSTPlane&);
+      int numFrontXhairSamples;
+      // Image kd-tree. per thread
+      KDTree *kdtree;
+      int qSize, maxQSize;
+      bool sourcetgrads, afterupdateonly;
+      // number of fragments a chunk is divided into. It is divided equally 
amongst all clients
+      int numFragments;
+      bool outputStreams;
+      bool spatialCoherence;
+      int numsamples_pertilevisit;
+      string streamfilename;
+      FILE **streamfile, **tilestreamfile, **textstreamfile;
+      SamplePrintFormat **spf;
+      // the reprojection queue per thread
+#ifdef RANDOM_ACCESS_TEMPORALQ
+      CSTACK<PartialSampleSet> *temporalQ;
+#else
+      CQ<SampleSet> *temporalQ;
+#endif
+      CQ<SampleSet> *outputQ[2];
+      SampleSet **newSampleSet, **newTempSampleSet;
+      // Random number generator array??
+      MT_RNG *myRandomNumber;
+
+      // Master/sampler client
+      bool masters_exempt;  // Are the masters exempt from doing sampling.
+      int num_clients;
+      int num_masters, avgGroupSize;
+      int master_thread;
+      int *chunkindex;
+      bool *clientdone;
+      int *groupSize;
+      int chunk_size;
+      int samplingrate;
+      int *lastxhairindex, *updatecount;
+
+      // Per master performance timers.
+      double *tile_refresh;
+      double *last_time;
+      
+      // stats
+      bool outputstats;
+      FILE **outputfile;
+      float *timestatslastwritten;
+      
/////////////////////////////////////////////////////////////////////////
+      // Samples done.
+      struct SamplesDone {
+        SamplesDone() : value (0) {};
+        unsigned int value;
+        unsigned int padding[31];
+#ifdef __ia64__
+        inline void addOne()  { __fetchadd4_acq( &value, 1 ); };
+        inline void addFive() { addOne(); __fetchadd4_acq( &value, 4 ); };
+        inline void addThree() { __fetchadd4_acq( &value, -1 ); 
__fetchadd4_acq( &value, 4 ); };
+        inline unsigned int load()    { return __ld4_acq( &value ); };
+#else
+        inline void addOne()  { value++; };
+        inline void addFive() { value+=5; };
+        inline void addThree() { value+=3; };
+        inline unsigned int load()    { return value; };
+#endif
+      };
+      SamplesDone *samples_done;
+
+      // Arguments.
+      Real inner_loop_time;
+
+      bool   *initpass;
+
+    public:
+    
+      // Sum up all of the samples done by all of the threads.
+      inline unsigned int getSamplesDone() {
+        unsigned int total = 0;
+        for (int i=0;i<num_clients;++i) {
+          total += samples_done[i].load();
+        }
+        return total;
+      };
+
+      // This method is called by the benchmark helper to determine when to 
start
+      // measuring performance.
+      inline bool allThreadsInitialized() {
+        bool all = true;
+        for (int i=0;(i<num_masters)&&all;++i) {
+          
+          // Don't wait for the master to initialize--this takes forever 
since the master
+          // is doing a lot more work then the distributed tree case.
+          all = (initpass[i]) && all;
+        }
+        return all;
+      }
+      inline int getNumThreads()
+      {
+        return num_masters;
+      }
+      // Accessors.
+      virtual double getInnerLoopTime()              { return 
inner_loop_time; };
+      virtual double getTileRefresh( int master_id ) { return 
tile_refresh[master_id]; };
+      
+    };
+
+    
+  };
+};
+
+#endif

Modified: trunk/fox/afr_demo/Engine/ImageTraversers/STAFRImageTraverser.cc
==============================================================================
--- trunk/fox/afr_demo/Engine/ImageTraversers/STAFRImageTraverser.cc    
(original)
+++ trunk/fox/afr_demo/Engine/ImageTraversers/STAFRImageTraverser.cc    Thu 
Feb  9 13:14:44 2006
@@ -4,7 +4,7 @@
 #include <Interface/Renderer.h>
 #include <Interface/Context.h>
 #include <Interface/Fragment.h>
-#include <Model/Cameras/AfrPinholeCamera.h>
+#include <Model/Cameras/AFRCamera.h>
 #include <Interface/Image.h>
 #include <Interface/LoadBalancer.h>
 #include <Interface/PixelSampler.h>
@@ -190,7 +190,7 @@
   // have flag for camera and dump the camera
   fprintf(textstreamfile[myID],"\n\nbegin_camera\n");
   // print camera to file
-  ((AFRPinholeCamera*)context.camera)->writeToFile(textstreamfile[myID]);
+  ((AFRCamera*)context.camera)->writeToFile(textstreamfile[myID]);
 }
 
 
@@ -677,7 +677,7 @@
                   {
                     const Point p(px, py, pz);
                     Point rp;
-                    rp = ((AFRPinholeCamera*)context.camera)->project(p);
+                    rp = ((AFRCamera*)context.camera)->project(p);
                     sp->sample[j].viewCoord[0] = rp.x()*xres;
                     sp->sample[j].viewCoord[1] = rp.y()*yres;
                     sp->sample[j].viewCoord[2] = rp.z();

Modified: trunk/fox/afr_demo/StandAlone/afr.cc
==============================================================================
--- trunk/fox/afr_demo/StandAlone/afr.cc        (original)
+++ trunk/fox/afr_demo/StandAlone/afr.cc        Thu Feb  9 13:14:44 2006
@@ -43,12 +43,13 @@
 #include <Core/Thread/Time.h>
 
 #include <Engine/ImageTraversers/GSTAFRImageTraverser.h>
+#include <Engine/ImageTraversers/GSTAFRImageTraverserSTPlane.h>
 #include <Engine/ImageTraversers/EGSRImageTraverser.h>
 #include <Engine/ImageTraversers/STAFRImageTraverser.h>
 #include <Engine/ImageTraversers/GSTAFRImageTraverserNew.h>
 #include <Engine/ImageTraversers/AFImageTraverser.h>
 #include <Engine/Control/AFRPipeline.h>
-#include <Model/Cameras/AfrPinholeCamera.h>
+#include <Model/Cameras/AFRCamera.h>
 
 // Default scene includes.
 #include <Core/Color/ColorDB.h>
@@ -202,10 +203,10 @@
       throw InternalError("default shadow algorithm not found", __FILE__, 
__LINE__ );
     
     // Set camera for the default scene.
-    Camera* currentCamera = new AFRPinholeCamera( Point( 3, 3, 2 ),
+    Camera* currentCamera = new AFRCamera( Point( 3, 3, 2 ),
                                                   Point( 0, 0, 0.3 ),
                                                   Vector( 0, 0, 1 ), 60 );
-
+    AFRCamera::afrRoot = (AFRPipeline*)rtrt;
     // Defaults for command line args.
     int xres = 512, yres = 512;
     string stack_file = "";
@@ -469,6 +470,9 @@
       }
       else if (name == "egsr") {
          rtrt->setImageTraverser( EGSRImageTraverser::create( args ) );
+      }
+      else if (name == "stplane") {
+         rtrt->setImageTraverser( GSTAFRImageTraverserSTPlane::create( args 
) );
       }
       // Otherwise attempt to load a default image traverser from manta.
       else {




  • [MANTA] r913 - in trunk/fox/afr_demo: . Engine/Control Engine/ImageTraversers StandAlone, abhinav, 02/09/2006

Archive powered by MHonArc 2.6.16.

Top of page