Text archives Help
- 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.