Index: GTP/trunk/Lib/Vis/Preprocessing/src/run_test2
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/run_test2	(revision 1829)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/run_test2	(revision 1867)
@@ -41,5 +41,5 @@
 
 $COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
- -rss_use_importance+ -rss_update_subdivision+ -rss_split=hybrid -hybrid_depth=10 \
+ -rss_use_importance+ -rss_use_rss_tree+ -rss_update_subdivision+ -rss_split=hybrid -hybrid_depth=10 \
  -view_cells_filter_max_size=1 -preprocessor_stats=$PREFIX-i-combined-update-ccb12-nn.log \
 -preprocessor_histogram_file=$PREFIX-i-combined-update-ccb12-nn.hlog
@@ -60,8 +60,8 @@
 
 
-# $COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
-#  -rss_use_importance+ -rss_use_rss_tree- -view_cells_filter_max_size=1 \
-#  -preprocessor_stats=$PREFIX-i-mixed-b1.log \
-#  -preprocessor_histogram_file=$PREFIX-i-mixed-b1.hlog
+$COMMAND -scene_filename=$SCENE -view_cells_filename=$VIEWCELLS \
+ -rss_use_importance+ -rss_use_rss_tree- -view_cells_filter_max_size=1 \
+ -preprocessor_stats=$PREFIX-i-mixed-b1-n.log \
+ -preprocessor_histogram_file=$PREFIX-i-mixed-b1-n.hlog
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/QtPreprocessorThread.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/QtPreprocessorThread.cpp	(revision 1770)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/QtPreprocessorThread.cpp	(revision 1867)
@@ -29,5 +29,16 @@
 }
 
+int
+QtPreprocessorThread::GetCurrentThreadId() const
+{
+  QThread *thread = currentThread();
+  for (int i=0; i < sThreads.size(); i++)
+	if (sThreads[i] == (QtPreprocessorThread *)thread)
+	  return i+1;
+  return 0;
 }
+
+}
+
 
 #endif
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Vector3.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Vector3.h	(revision 1579)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Vector3.h	(revision 1867)
@@ -233,7 +233,16 @@
   friend inline int EpsilonEqualV3(const Vector3 &v1, const Vector3 &v2);
 
+  friend Vector3 CosineRandomVector(const Vector3 &normal);
   friend Vector3 UniformRandomVector(const Vector3 &normal);
   friend Vector3 UniformRandomVector();
-  
+
+  friend Vector3
+  UniformRandomVector(const float r1, const float r2);
+
+  friend Vector3 UniformRandomVector(const Vector3 &normal,
+									 const float r1,
+									 const float r2
+									 );
+
 
 };
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Halton.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Halton.h	(revision 860)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Halton.h	(revision 1867)
@@ -7,12 +7,8 @@
 namespace GtpVisibilityPreprocessor {
 
-class Halton2 {
-  static float _invBases[2];
-  float _prev[2];
-  
-  float halton(float baseRec, float prev) const {
-	float r = 1 - prev - 1e-10f;
-	if (baseRec < r)
-	  return prev + baseRec;
+inline float halton(float baseRec, float prev) {
+  float r = 1 - prev - 1e-10f;
+  if (baseRec < r)
+	return prev + baseRec;
 	float h = baseRec;
 	float hh;
@@ -22,5 +18,41 @@
 	} while (h >= r);
 	return prev + hh + h - 1;
+}
+
+template<int T>
+class Halton {
+  float _invBases[T];
+  float _prev[T];
+  
+public:
+  
+  void Reset() {
+	for (int i=0; i < T; i++) 
+	  _prev[i] = 0;
   }
+  
+  Halton() {
+	for (int i=0; i < T; i++) {
+	  int base = FindPrime(i+1);
+	  if (base == 1)
+		base++;
+	  _invBases[i] = 1.0f/base;
+	}
+	Reset();
+  }
+  
+  void
+  GetNext(float *a) {
+	for (int i=0; i < T; i++) {
+	  a[i] = halton(_invBases[i], _prev[i]);
+	  _prev[i] = a[i];
+	}
+  }
+  
+};
+
+class Halton2 {
+  static float _invBases[2];
+  float _prev[2];
   
 public:
@@ -69,8 +101,13 @@
  */
 inline int FindPrime(const int index) {
-  if(index < 1) {
-	cerr<<"FindPrime: The argument must be non-negative."<<endl;
-	return -1;
-  }
+  //  if (index < 1) {
+  //	cerr<<"FindPrime: The argument must be non-negative."<<endl;
+  //	return -1;
+  //  }
+
+  const int primes[] = {-1, 1, 3, 5, 7, 11, 13};
+  if (index <= 6)
+	return primes[index];
+
   int prime = 1;
   int found = 1;
@@ -115,6 +152,4 @@
 	int copyOfIndex = index;
 	if((base >= 2) && (index >= 1)) {
-	// changed by matt
-	//if(base >= 2 & index >= 1) {
 	  while(copyOfIndex > 0) {
 		N1 = (copyOfIndex / base);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1845)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1867)
@@ -307,4 +307,6 @@
 	*/
 	virtual bool GetViewPoint(Vector3 &viewPoint) const;
+  
+  virtual bool GetViewPoint(Vector3 &viewPoint, const Vector3 &params) const;
 
 	/** Returns true if this view point is in the valid view space.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1832)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/QtGlRenderer.cpp	(revision 1867)
@@ -327,5 +327,5 @@
 QtGlRendererWidget::RenderPvs()
 {
-  
+	
   Intersectable::NewMail();
 
@@ -345,5 +345,5 @@
 	// copy the pvs so that it can be filtered...
 	
-	ObjectPvs &pvs = mPvsCache.mPvs;
+	//	mPvsCache.mPvs;
 	
 	if (mPvsCache.mViewCell != viewcell) {
@@ -352,22 +352,22 @@
 	  
 	  if (mUseSpatialFilter) {
-			// 9.11. 2006 -> experiment with new spatial filter
+		// 9.11. 2006 -> experiment with new spatial filter
 #if 0
-			mViewCellsManager->ApplySpatialFilter(mKdTree,
-																						mSpatialFilterSize*
-																						Magnitude(mViewCellsManager->GetViewSpaceBox().Size()),
-																						pvs);
+		mViewCellsManager->ApplySpatialFilter(mKdTree,
+											  mSpatialFilterSize*
+											  Magnitude(mViewCellsManager->GetViewSpaceBox().Size()),
+											  mPvsCache.mPvs);
 #else
-			// mSpatialFilter size is in range 0.001 - 0.1
-			mViewCellsManager->ApplyFilter2(viewcell,
-																			mUseFilter,
-																			100*mSpatialFilterSize,
-																			pvs,
-																			&mPvsCache.filteredBoxes
-																			);
+		// mSpatialFilter size is in range 0.001 - 0.1
+		mViewCellsManager->ApplyFilter2(viewcell,
+										mUseFilter,
+										100*mSpatialFilterSize,
+										mPvsCache.mPvs,
+										&mPvsCache.filteredBoxes
+										);
 #endif
 	  } else
-		pvs = viewcell->GetPvs();
-
+		mPvsCache.mPvs = viewcell->GetPvs();
+	  
 	  emit PvsUpdated();
 	}
@@ -378,7 +378,7 @@
 			RenderBox(mPvsCache.filteredBoxes[i]);
 	} else {
-		ObjectPvsIterator it = pvs.GetIterator();
+		ObjectPvsIterator it = mPvsCache.mPvs.GetIterator();
 		
-		mPvsSize = pvs.GetSize();
+		mPvsSize = mPvsCache.mPvs.GetSize();
 		for (; it.HasMoreEntries(); ) {
 			ObjectPvsEntry entry = it.Next();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Ray.h	(revision 1867)
@@ -316,12 +316,19 @@
 struct SimpleRay
 {
+  int mId;
   Vector3 mOrigin;
   Vector3 mDirection;
   float mPdf;
-	int mType;
-	
-  SimpleRay(): mType(Ray::LOCAL_RAY) {}
+  int mType;
+
+  static int sSimpleRayId;
+  SimpleRay(): mType(Ray::LOCAL_RAY) {
+	mId = sSimpleRayId++;
+  }
+  
   SimpleRay(const Vector3 &o, const Vector3 &d, const float p=1.0f):
-		mOrigin(o), mDirection(d), mPdf(p), mType(Ray::LOCAL_RAY) {}
+	mOrigin(o), mDirection(d), mPdf(p), mType(Ray::LOCAL_RAY) {	
+	mId = sSimpleRayId++;
+  }
 	
   Vector3 Extrap(const float t) const {
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1843)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1867)
@@ -1576,5 +1576,5 @@
 		"bsp_construction_input=",
 		"fromViewCells");
-
+	
 	RegisterOption("BspTree.subdivisionStats",
 					optString,
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 1764)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 1867)
@@ -136,5 +136,5 @@
   void SetWireframe() { mWireframe = true; }
   void SetFilled() { mWireframe = false; }
-
+  
   void SetForcedMaterial(const Material &m) {
     mForcedMaterial = m;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1827)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1867)
@@ -30,7 +30,8 @@
 namespace GtpVisibilityPreprocessor {
 
-const static bool ADDITIONAL_GEOMETRY_HACK = false;
-
-
+  const static bool ADDITIONAL_GEOMETRY_HACK = false;
+
+  Preprocessor *preprocessor = NULL;
+  
 // HACK: Artificially modify scene to watch rendercost changes
 static void AddGeometry(SceneGraph *scene)
@@ -443,11 +444,11 @@
 	Environment::GetSingleton()->GetIntValue("Preprocessor.rayCastMethod", rayCastMethod);
 	vector<FaceParentInfo> *fi = 
-		((rayCastMethod == RayCaster::INTEL_RAYCASTER) && mLoadMeshes) ?
-		&mFaceParents : NULL;
-
+	  ((rayCastMethod == RayCaster::INTEL_RAYCASTER) && mLoadMeshes) ?
+	  &mFaceParents : NULL;
+	
 	if (files == 1) 
-	{
+	  {
 		if (strstr(filename.c_str(), ".x3d"))
-		{
+		  {
 			parser = new X3dParser;
 			
@@ -984,8 +985,8 @@
 int
 Preprocessor::GenerateRays(const int number,
-													 const SamplingStrategy &strategy,
-													 SimpleRayContainer &rays)
-{
-	return strategy.GenerateSamples(number, rays);
+						   SamplingStrategy &strategy,
+						   SimpleRayContainer &rays)
+{
+  return strategy.GenerateSamples(number, rays);
 }
 
@@ -1096,15 +1097,15 @@
 	if (rayCastMethod == 0)
 	{
+		cout << "ray cast method: internal" << endl;
 		mRayCaster = new InternalRayCaster(*this, mKdTree);
-		cout << "ray cast method: internal" << endl;
 	}
 	else
 	{
 #ifdef GTP_INTERNAL
-		mRayCaster = new IntelRayCaster(*this, externKdTree);
-		cout << "ray cast method: intel" << endl;
+	  cout << "ray cast method: intel" << endl;
+	  mRayCaster = new IntelRayCaster(*this, externKdTree);
 #endif
 	}
-
+	
 	return true;
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Ray.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Ray.cpp	(revision 1584)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Ray.cpp	(revision 1867)
@@ -14,9 +14,11 @@
 // that are converted to canonical space and thus the mailbox
 // rayID identification does not work for them!
-int
-Ray::genID = 1;
-
-// Precompute some Ray parameters. Most of them is used for
-// ropes traversal.
+  int
+  Ray::genID = 1;
+  
+  
+  int
+  SimpleRay::sSimpleRayId = 1;
+  
 
 void
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1867)
@@ -13,5 +13,5 @@
 #include "GlRenderer.h"
 #include "SamplingStrategy.h"
-
+#include "PreprocessorThread.h"
 
 
@@ -19,10 +19,7 @@
 
 
-static bool useViewSpaceBox = false;
-static bool use2dSampling = false;
-
-
-// not supported anymore!
-static bool fromBoxVisibility = false;
+  const bool pruneRays = false;
+  
+
 
 #define ADD_RAYS_IN_PLACE 1
@@ -62,7 +59,6 @@
 RssPreprocessor::GenerateRays(
 							  const int number,
-							  const int sampleType,
-							  SimpleRayContainer &rays
-							  )
+							  SamplingStrategy &strategy,
+							  SimpleRayContainer &rays)
 {
   int result = 0;
@@ -70,16 +66,16 @@
   Debug<<"Generate rays...\n"<<flush;
 
-  switch (sampleType) {
+  switch (strategy.mType) {
   case SamplingStrategy::RSS_BASED_DISTRIBUTION:
   case SamplingStrategy::RSS_SILHOUETTE_BASED_DISTRIBUTION:
 		if (mRssTree) {
-			result = GenerateImportanceRays(mRssTree, number, rays);
+		  result = GenerateImportanceRays(mRssTree, number, rays);
 		}
 		break;
 		
   default:
-		result = Preprocessor::GenerateRays(number, sampleType, rays);
-  }
-
+	result = Preprocessor::GenerateRays(number, strategy, rays);
+  }
+  
   //  rays.NormalizePdf();
   Debug<<"done.\n"<<flush;
@@ -413,5 +409,5 @@
 {
   // now evaluate the ratios for the next pass
-#define TIME_WEIGHT 0.5f
+#define TIME_WEIGHT 0.0f
   for (int i=0; i < distributions.size(); i++) {
 	distributions[i]->mRatio = distributions[i]->mContribution/
@@ -437,7 +433,40 @@
 
   Randomize(0);
+
+  if (1) {
+	Exporter *exporter = Exporter::GetExporter("samples.wrl");
+    exporter->SetFilled();
+	Halton<4> halton;
+
+// 	for (int i=1; i < 7; i++) 
+// 	  cout<<i<<" prime= "<<FindPrime(i)<<endl;
+	
+	Material mA, mB;
+	mA.mDiffuseColor = RgbColor(1, 0, 0);
+	mB.mDiffuseColor = RgbColor(0, 1, 0);
+	
+	for (int i=0; i < 10000; i++) {
+	  float r[4];
+	  halton.GetNext(r);
+	  Vector3 v1 = UniformRandomVector(r[0], r[1]);
+	  Vector3 v2 = UniformRandomVector(r[2], r[3]);
+
+	  const float size =0.002f;
+	  AxisAlignedBox3 box(v1-Vector3(size), v1+Vector3(size));
+	  exporter->SetForcedMaterial(mA);
+	  exporter->ExportBox(box);
+	  AxisAlignedBox3 box2(v2-Vector3(size), v2+Vector3(size));
+
+	  exporter->SetForcedMaterial(mB);
+	  exporter->ExportBox(box2);
+	}
+	delete exporter;
+  }
+  
+  
+  cout<<"COMPUTATION THREAD="<<GetThread()->GetCurrentThreadId()<<endl<<flush;
   
   // use ray buffer to export ray animation
-  const bool useRayBuffer = false;
+  const bool useRayBuffer = true;
   
   vector<VssRayContainer> rayBuffer(50);
@@ -467,15 +496,16 @@
 		mDistributions.push_back(new RssBasedDistribution(*this));
 
-
-	if (1) {
-		//  mDistributions.push_back(new SpatialBoxBasedDistribution(*this));
-		//  mDistributions.push_back(new DirectionBasedDistribution(*this));
-		mDistributions.push_back(new ObjectDirectionBasedDistribution(*this));
-		//  mDistributions.push_back(new ReverseObjectBasedDistribution(*this));
-		mDistributions.push_back(new ObjectBasedDistribution(*this));
-		mDistributions.push_back(new ReverseViewSpaceBorderBasedDistribution(*this));
-	} else {
-		mDistributions.push_back(new GlobalLinesDistribution(*this));
-	}
+  
+  if (1) {
+	mDistributions.push_back(new SpatialBoxBasedDistribution(*this));
+// 	//  mDistributions.push_back(new DirectionBasedDistribution(*this));
+// 	mDistributions.push_back(new ObjectDirectionBasedDistribution(*this));
+// 	//  mDistributions.push_back(new ReverseObjectBasedDistribution(*this));
+// 	mDistributions.push_back(new ObjectBasedDistribution(*this));
+// 	mDistributions.push_back(new ReverseViewSpaceBorderBasedDistribution(*this));
+  } else {
+	mDistributions.push_back(new GlobalLinesDistribution(*this));
+	mDistributions.push_back(new SpatialBoxBasedDistribution(*this));
+  }
   
   if (mLoadInitialSamples) {
@@ -500,7 +530,7 @@
 		if (mDistributions[i]->mType != SamplingStrategy::RSS_BASED_DISTRIBUTION)
 		  GenerateRays(mInitialSamples/count,
-									 mDistributions[i]->mType,
-									 rays);
-
+					   *mDistributions[i],
+					   rays);
+	  
 	} else {
 	  int rayType = SamplingStrategy::SPATIAL_BOX_BASED_DISTRIBUTION;
@@ -511,10 +541,11 @@
 		  rayType = SamplingStrategy::DIRECTION_BASED_DISTRIBUTION;
 	  cout<<"Generating rays..."<<endl;
-	  GenerateRays(mRssSamplesPerPass, rayType, rays);
+
+	  Preprocessor::GenerateRays(mRssSamplesPerPass, rayType, rays);
 	}
 	
 	
 	cout<<"Casting initial rays..."<<endl<<flush;
-	CastRays(rays, mVssRays, true);
+	CastRays(rays, mVssRays, true, pruneRays);
 
 	ExportObjectRays(mVssRays, 1546);
@@ -578,5 +609,5 @@
 	// cull viewcells with PVS > median (0.5f)
 	//mViewCellsManager->SetValidityPercentage(0, 0.5f); 
-	mViewCellsManager->SetValidityPercentage(0, 1.0f); 
+	//	mViewCellsManager->SetValidityPercentage(0, 1.0f); 
 	Debug<<"Valid viewcells after set validity: "<<mViewCellsManager->CountValidViewcells()<<endl;
 
@@ -584,6 +615,26 @@
 	mViewCellsManager->PrintPvsStatistics(mStats);
 
+
+	if (0) {
+	  char str[64];
+	  sprintf(str, "tmp/v-");
+	  
+	  // visualization
+	  const bool exportRays = true;
+	  const bool exportPvs = true;
+	  ObjectContainer objects;
+	  mViewCellsManager->ExportSingleViewCells(objects,
+											   1000,
+											   false,
+											   exportPvs,
+											   exportRays,
+											   10000,
+											   str);
+	}
+	  
 	ComputeRenderError();
   }
+
+  //  return 1;
   
   rssPass++;
@@ -618,6 +669,7 @@
 	}
   }
-  
-  
+
+  // keep only rss
+  mDistributions.resize(1);
 
   while (1) {
@@ -646,12 +698,14 @@
 		if (mDistributions[i]->mRatio != 0) {
 		  GenerateRays(int(mRssSamplesPerPass*mDistributions[i]->mRatio),
-					   mDistributions[i]->mType,
+					   *mDistributions[i],
 					   rays);
 		  
 		  rays.NormalizePdf((float)rays.size());
 		  
-		  CastRays(rays, tmpVssRays, true);
+		  CastRays(rays, tmpVssRays, true, pruneRays);
 		  castRays += (int)rays.size();
-		  
+
+		  cout<<"Computing sample contributions..."<<endl<<flush;
+
 #if ADD_RAYS_IN_PLACE 
 		  mDistributions[i]->mContribution =
@@ -661,8 +715,10 @@
 			mViewCellsManager->ComputeSampleContributions(tmpVssRays, false, true);
 #endif
+		  cout<<"done."<<endl;
 		}
 
 		mDistributions[i]->mTime = TimeDiff(t1, GetTime());
-		mDistributions[i]->mRays = (int)rays.size();
+		//		mDistributions[i]->mRays = (int)rays.size();
+		mDistributions[i]->mRays = (int)tmpVssRays.size() + 1;
 		//		mStats<<"#RssRelContrib"<<endl<<contributions[0]/nrays[0]<<endl;
 		vssRays.insert(vssRays.end(), tmpVssRays.begin(), tmpVssRays.end() );
@@ -686,5 +742,5 @@
 	  cout<<"Generating rays..."<<endl;
 
-	  GenerateRays(mRssSamplesPerPass, rayType, rays);
+	  Preprocessor::GenerateRays(mRssSamplesPerPass, rayType, rays);
 	  cout<<"done."<<endl;
 
@@ -843,5 +899,5 @@
 
 
-  if (useRayBuffer&& mExportRays && mUseImportanceSampling) {
+  if (useRayBuffer && mExportRays && mUseImportanceSampling) {
 	char filename[64];
 	sprintf(filename, "rss-rays-i.x3d");
Index: GTP/trunk/Lib/Vis/Preprocessing/src/default.env
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/default.env	(revision 1867)
@@ -25,5 +25,5 @@
 #filename ../data/soda/soda.dat
 #filename ../data/test1/test2.x3d
-#filename ../data/soda/soda5.dat
+# filename ../data/soda/soda5.dat
 #filename ../data/PowerPlant/ppsection1/part_a/g0.ply
 #filename ../data/PowerPlant/ppsection1/part_b/g0.ply
@@ -53,5 +53,5 @@
 	pvsRenderErrorSamples 0
 #	pvsRenderErrorSamples 1000
-	quitOnFinish true
+	quitOnFinish false
 	computeVisibility true
 
@@ -90,7 +90,7 @@
 RssPreprocessor {
 	samplesPerPass 1000
-	initialSamples 3000000
-	vssSamples 100000000
-	vssSamplesPerPass 5000000
+	initialSamples 1000000
+	vssSamples 20000000
+	vssSamplesPerPass 1000000
 	useImportanceSampling true
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1786)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1867)
@@ -9,7 +9,7 @@
 
 
-
 namespace GtpVisibilityPreprocessor {
-
+  class PreprocessorThread;
+  
 class RenderSimulator;
 class SceneGraph;
@@ -122,11 +122,11 @@
 
 	virtual int
-		GenerateRays(const int number,
-		const SamplingStrategy &strategy,
-		SimpleRayContainer &rays);
-
-	virtual int GenerateRays(const int number,
-		const int raysType,
-		SimpleRayContainer &rays);
+	GenerateRays(const int number,
+				 SamplingStrategy &strategy,
+				 SimpleRayContainer &rays);
+
+  virtual int GenerateRays(const int number,
+						   const int raysType,
+						   SimpleRayContainer &rays);
 
 	bool GenerateRayBundle(SimpleRayContainer &rayBundle,
@@ -136,7 +136,7 @@
 
 	virtual void CastRays(SimpleRayContainer &rays,
-		VssRayContainer &vssRays,
-		const bool castDoubleRays,
-		const bool pruneInvalidRays = true);
+						  VssRayContainer &vssRays,
+						  const bool castDoubleRays,
+						  const bool pruneInvalidRays = true);
 
 	/** Returns a view cells manager of the given name.
@@ -207,4 +207,12 @@
 
   GlRendererBuffer *renderer;
+
+  void SetThread(PreprocessorThread *t) {
+	mThread = t;
+  }
+
+  PreprocessorThread *GetThread() const {
+	return mThread;
+  }
 
 protected:
@@ -237,6 +245,9 @@
 	/// if box around view space should be used
 	bool mUseViewSpaceBox;
+
+  PreprocessorThread *mThread;
 };
 
+  extern Preprocessor *preprocessor;
 
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.h	(revision 1867)
@@ -2,4 +2,5 @@
 #define _SamplingStategy_H__
 
+#include "Halton.h"
 
 namespace GtpVisibilityPreprocessor {
@@ -46,9 +47,9 @@
 	*/
 
-	virtual int GenerateSamples(const int number, SimpleRayContainer &rays) const;
-
-private:
-
-	virtual bool GenerateSample(SimpleRay &ray) const = 0;
+	virtual int GenerateSamples(const int number, SimpleRayContainer &rays);
+
+private:
+
+	virtual bool GenerateSample(SimpleRay &ray) = 0;
 
 public:
@@ -77,5 +78,5 @@
 
 private:
-  virtual bool GenerateSample(SimpleRay &ray) const;
+  virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -91,5 +92,5 @@
 
 private:
-  virtual bool GenerateSample(SimpleRay &ray) const;
+  virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -103,5 +104,5 @@
 	 }
 private:
-	virtual bool GenerateSample(SimpleRay &ray) const;
+	virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -115,5 +116,5 @@
   }
 private:
-  virtual bool GenerateSample(SimpleRay &ray) const;
+  virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -128,5 +129,5 @@
 	   
 private:
-	   virtual bool GenerateSample(SimpleRay &ray) const;
+	   virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -135,11 +136,12 @@
 {
  public:
-	 SpatialBoxBasedDistribution(const Preprocessor &preprocessor):
-	   SamplingStrategy(preprocessor){
-	   mType = DIRECTION_BOX_BASED_DISTRIBUTION;
-	 }
-	   
-private:
-	   virtual bool GenerateSample(SimpleRay &ray) const;
+  Halton<6> halton;
+  SpatialBoxBasedDistribution(const Preprocessor &preprocessor):
+	SamplingStrategy(preprocessor){
+	mType = DIRECTION_BOX_BASED_DISTRIBUTION;
+  }
+  
+private:
+	   virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -154,5 +156,5 @@
 	 
 private:
-	 virtual bool GenerateSample(SimpleRay &ray) const;
+	 virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -167,5 +169,5 @@
 	 
 private:
-	 virtual bool GenerateSample(SimpleRay &ray) const;
+	 virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -180,5 +182,5 @@
 
 
-  virtual int GenerateSamples(const int number, SimpleRayContainer &ray) const {
+  virtual int GenerateSamples(const int number, SimpleRayContainer &ray) {
 	// TBD!!!
 	return 0;
@@ -186,5 +188,5 @@
 
 private:
-  virtual bool GenerateSample(SimpleRay &ray) const;
+  virtual bool GenerateSample(SimpleRay &ray);
   
 };
@@ -197,5 +199,5 @@
 	SamplingStrategy(preprocessor) {}
   
-  virtual bool GenerateSample(SimpleRay &ray) const;
+  virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -203,10 +205,13 @@
 {
 public:
+  Halton<4> halton;
+  //HaltonSequence mHalton;
+
   GlobalLinesDistribution(const Preprocessor &preprocessor):
-		SamplingStrategy(preprocessor) {
-		mType = GLOBAL_LINES_DISTRIBUTION;
-	}
-  
-  virtual bool GenerateSample(SimpleRay &ray) const;
+	SamplingStrategy(preprocessor) {
+	mType = GLOBAL_LINES_DISTRIBUTION;
+  }
+  
+  virtual bool GenerateSample(SimpleRay &ray);
 };
 
@@ -221,5 +226,5 @@
 	 SamplingStrategy(preprocessor) {}
 	 
-	 virtual bool GenerateSample(SimpleRay &ray) const;
+	 virtual bool GenerateSample(SimpleRay &ray);
 };
 */
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1844)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1867)
@@ -27,6 +27,6 @@
 #define USE_VOLUMES_FOR_HEURISTICS 1
 
-//int BvhNode::sMailId = 10000; //2147483647;
-//int BvhNode::sReservedMailboxes = 1;
+  //int BvhNode::sMailId = 10000; //2147483647;
+  //int BvhNode::sReservedMailboxes = 1;
 
 BvHierarchy *BvHierarchy::BvhSubdivisionCandidate::sBvHierarchy = NULL;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorThread.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorThread.cpp	(revision 1583)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorThread.cpp	(revision 1867)
@@ -8,4 +8,6 @@
 namespace GtpVisibilityPreprocessor {
 
+
+vector<PreprocessorThread *> PreprocessorThread::sThreads;
 
 PreprocessorThread::PreprocessorThread(Preprocessor *p):
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.h	(revision 1785)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.h	(revision 1867)
@@ -125,10 +125,8 @@
   /** Redefininition of the get sample rays method from the preprocessor */
   int
-  GenerateRays(
-			   const int number,
-			   const int sampleType,
-			   SimpleRayContainer &rays
-			   );
-
+  GenerateRays(const int number,
+			   SamplingStrategy &strategy,
+			   SimpleRayContainer &rays);
+  
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BoostPreprocessorThread.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BoostPreprocessorThread.cpp	(revision 1457)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BoostPreprocessorThread.cpp	(revision 1867)
@@ -33,4 +33,13 @@
 {
   mThread = new boost::thread(*this);
+  
+  PreprocessorThread::InitThread();
+}
+
+int
+BoostPreprocessorThread::GetCurrentThreadId() const
+{
+  // $$ temporary implementation
+  return 0;
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1846)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1867)
@@ -1500,6 +1500,12 @@
 bool ViewCellsManager::GetViewPoint(Vector3 &viewPoint) const
 {
-	viewPoint = mViewSpaceBox.GetRandomPoint();
-	return true;
+  viewPoint = mViewSpaceBox.GetRandomPoint();
+  return true;
+}
+
+bool ViewCellsManager::GetViewPoint(Vector3 &viewPoint, const Vector3 &params) const
+{
+  viewPoint = mViewSpaceBox.GetRandomPoint(params);
+  return true;
 }
 
@@ -1532,21 +1538,22 @@
 
 
-float ViewCellsManager::ComputeSampleContributions(const VssRayContainer &rays,
-												   const bool addRays,									
-												   const bool storeViewCells)
-{
-	// view cells not yet constructed
-	if (!ViewCellsConstructed())
-		return 0.0f;
-	
-	float sum = 0.0f;
-	VssRayContainer::const_iterator it, it_end = rays.end();
-	
-	for (it = rays.begin(); it != it_end; ++ it) 
-	{
-		sum += ComputeSampleContribution(*(*it), addRays, storeViewCells);
-	}
-
-	return sum;
+float
+ViewCellsManager::ComputeSampleContributions(const VssRayContainer &rays,
+											 const bool addRays,
+   											 const bool storeViewCells)
+{
+  // view cells not yet constructed
+  if (!ViewCellsConstructed())
+	return 0.0f;
+  
+  float sum = 0.0f;
+  VssRayContainer::const_iterator it, it_end = rays.end();
+  
+  for (it = rays.begin(); it != it_end; ++ it) 
+	{
+	  sum += ComputeSampleContribution(*(*it), addRays, storeViewCells);
+	}
+  
+  return sum;
 }
 
@@ -2006,70 +2013,75 @@
 
 float ViewCellsManager::ComputeSampleContribution(VssRay &ray,
-																									const bool addRays,
-																									const bool storeViewCells)
-{
-	ViewCellContainer viewcells;
-
-	ray.mPvsContribution = 0;
-	ray.mRelativePvsContribution = 0.0f;
-
-	static Ray hray;
-	hray.Init(ray);
-	//hray.mFlags |= Ray::CULL_BACKFACES;
-	//Ray hray(ray);
-
-	float tmin = 0, tmax = 1.0;
-
-	if (!GetViewSpaceBox().GetRaySegment(hray, tmin, tmax) || (tmin > tmax))
-		return 0;
-
-	Vector3 origin = hray.Extrap(tmin);
-	Vector3 termination = hray.Extrap(tmax);
-
-	ViewCell::NewMail();
-
-	//	if (ray.mPdf!=1.0f)
-	//	  cout<<ray.mPdf<<" ";
-	
-	
-	// traverse the view space subdivision
-	CastLineSegment(origin, termination, viewcells);
-
-	if (storeViewCells)
+												  const bool addRays,
+												  const bool storeViewCells)
+{
+  ray.mPvsContribution = 0;
+  ray.mRelativePvsContribution = 0.0f;
+
+  if (ray.mTerminationObject==NULL)
+	return 0.0f;
+  
+  ViewCellContainer viewcells;
+  
+
+
+  
+  static Ray hray;
+  hray.Init(ray);
+  //hray.mFlags |= Ray::CULL_BACKFACES;
+  //Ray hray(ray);
+  
+  float tmin = 0, tmax = 1.0;
+  
+  if (!GetViewSpaceBox().GetRaySegment(hray, tmin, tmax) || (tmin > tmax))
+	return 0;
+  
+  Vector3 origin = hray.Extrap(tmin);
+  Vector3 termination = hray.Extrap(tmax);
+  
+  ViewCell::NewMail();
+  
+  //	if (ray.mPdf!=1.0f)
+  //	  cout<<ray.mPdf<<" ";
+  
+  
+  // traverse the view space subdivision
+  CastLineSegment(origin, termination, viewcells);
+  
+  if (storeViewCells)
 	{	// copy viewcells memory efficiently
-		ray.mViewCells.reserve(viewcells.size());
-		ray.mViewCells = viewcells;
-	}
-	
-	Intersectable *obj = GetIntersectable(ray, true);
-		
-	ViewCellContainer::const_iterator it = viewcells.begin();
-	
-	for (; it != viewcells.end(); ++ it) 
-	{
-		ViewCell *viewcell = *it;
-		// tests if view cell is in valid view space
-		if (viewcell->GetValid())
-		{
-			float contribution;
-
-			if (ray.mTerminationObject) 
-			{			
-				if (viewcell->GetPvs().GetSampleContribution(obj,
-					ray.mPdf,
-					contribution))
-				{
-					++ ray.mPvsContribution;
-					ray.mRelativePvsContribution += contribution;
-					// $$ test of different contribution measure
-					//					ray.mRelativePvsContribution += 1.0f/(viewcell->GetPvs().GetSize() + 10.0f);
-
-				}
+	  ray.mViewCells.reserve(viewcells.size());
+	  ray.mViewCells = viewcells;
+	}
+  
+  Intersectable *obj = GetIntersectable(ray, true);
+  
+  ViewCellContainer::const_iterator it = viewcells.begin();
+  
+  for (; it != viewcells.end(); ++ it) 
+	{
+	  ViewCell *viewcell = *it;
+	  // tests if view cell is in valid view space
+	  if (viewcell->GetValid())
+		{
+		  float contribution;
+		  
+		  if (ray.mTerminationObject)  {			
+			if (viewcell->GetPvs().GetSampleContribution(obj,
+														 ray.mPdf,
+														 contribution)) {
+			  ++ ray.mPvsContribution;
 			}
 			
+			ray.mRelativePvsContribution += contribution;
+			// $$ test of different contribution measure
+			//					ray.mRelativePvsContribution += 1.0f/(viewcell->GetPvs().GetSize() + 10.0f);
+			
+		  }
+		  
 #if SAMPLE_ORIGIN_OBJECTS
-
-			// for directional sampling it is important to count only contributions
-			// made in one direction!!!
+		  
+		  // for directional sampling it is important to count only contributions
+		  // made in one direction!!!
 			// the other contributions of this sample will be counted for the oposite ray!
 
@@ -2096,7 +2108,7 @@
 			{
 				// if view point is valid, add new object to the pvs
-				if (ray.mTerminationObject)
+			  if (ray.mTerminationObject)
 				{ 
-					viewcell->GetPvs().AddSample(obj, ray.mPdf);
+				  viewcell->GetPvs().AddSample(obj, ray.mPdf);
 				}				
 #if SAMPLE_ORIGIN_OBJECTS
@@ -6035,12 +6047,17 @@
 
 #define PVS_ADD_DIRTY 1
-float VspOspViewCellsManager::ComputeSampleContribution(VssRay &ray,
-														const bool addRays,
-														const bool storeViewCells)
-{
-	ViewCellContainer viewcells;
-
-	ray.mPvsContribution = 0;
-	ray.mRelativePvsContribution = 0.0f;
+float
+VspOspViewCellsManager::ComputeSampleContribution(VssRay &ray,
+												  const bool addRays,
+												  const bool storeViewCells)
+{
+  ray.mPvsContribution = 0;
+  ray.mRelativePvsContribution = 0.0f;
+  
+  if (ray.mTerminationObject==NULL)
+	return 0.0f;
+  
+  ViewCellContainer viewcells;
+  
 
 	static Ray hray;
@@ -6075,5 +6092,8 @@
 
 	Intersectable *terminationObj = GetIntersectable(ray, true);
+
+#if SAMPLE_ORIGIN_OBJECTS
 	Intersectable *originObj = GetIntersectable(ray, false);
+#endif
 
 	for (; it != viewcells.end(); ++ it) 
@@ -6087,12 +6107,12 @@
 			if (terminationObj) 
 			{
-				// todo: maybe not correct for kd node pvs
-				if (viewcell->GetPvs().GetSampleContribution(
-							terminationObj, ray.mPdf, contribution))
+			  // todo: maybe not correct for kd node pvs
+			  if (viewcell->GetPvs().GetSampleContribution(
+														   terminationObj, ray.mPdf, contribution))
 				{
-					++ ray.mPvsContribution;
+				  ++ ray.mPvsContribution;
 				}
-
-				ray.mRelativePvsContribution += contribution;
+			  
+			  ray.mRelativePvsContribution += contribution;
 			}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1843)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.cpp	(revision 1867)
@@ -34,6 +34,6 @@
 					   myless<vector<ViewCell *>::value_type> > TraversalQueue;
 
-int ViewCell::sMailId = 10000;//2147483647;
-int ViewCell::sReservedMailboxes = 1;
+  int ViewCell::sMailId = 10000;//2147483647;
+  int ViewCell::sReservedMailboxes = 1;
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 1845)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Pvs.h	(revision 1867)
@@ -592,5 +592,6 @@
 
 	// only check clean part
-	//mLastSorted = 0;
+	// $$ TMP JB
+	// mLastSorted = 0;
 	vector<PvsEntry<T, S> >::iterator sorted_end = mEntries.begin() + mLastSorted;
 
@@ -606,6 +607,6 @@
 		vector<PvsEntry<T, S> >::const_iterator dit, dit_end = mEntries.end();
 
-		for (dit = sorted_end; (dit != dit_end) && ((*dit).mObject != sample); ++ dit);
-
+		for (dit = sorted_end; (dit != dit_end) && ((*dit).mObject != sample); ++ dit) ;
+		
 		if ((dit != mEntries.end()) && ((*dit).mObject == sample))
 			found = true;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorThread.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorThread.h	(revision 1457)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/PreprocessorThread.h	(revision 1867)
@@ -2,9 +2,11 @@
 #define __PREPROCESSOR_THREAD_H
 
-
+#include <vector>
+using namespace std;
 namespace GtpVisibilityPreprocessor 
 {
 
 class Preprocessor;
+
 
 /** This class represents a preprocessor thread.
@@ -13,12 +15,19 @@
 {
 public:
+  static vector<PreprocessorThread *> sThreads;
+  
   PreprocessorThread(Preprocessor *p);
   virtual ~PreprocessorThread();
   
-  virtual void InitThread() {}
+  virtual void InitThread() {
+	sThreads.push_back(this);
+  }
   virtual void RunThread() {}
   
   virtual void Main();
-  
+
+  // This function has to be defined by the thread library used...
+  virtual int GetCurrentThreadId() const = 0;
+
 protected:
   
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.cpp	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntersectableWrapper.cpp	(revision 1867)
@@ -31,13 +31,13 @@
 		if (ray.GetType() == Ray::LOCAL_RAY && !ray.intersections.empty()) {
 			ray.intersections[0] = Ray::Intersection(nearestT,
-																							 nearestNormal,
-																							 this,
-																							 0);
+													 nearestNormal,
+													 this,
+													 0);
 		}
 		else {
 			ray.intersections.push_back(Ray::Intersection(nearestT,
-																										nearestNormal,
-																										this,
-																										0));
+														  nearestNormal,
+														  this,
+														  0));
 		}
 		
Index: GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp	(revision 1786)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/IntelRayCaster.cpp	(revision 1867)
@@ -93,12 +93,12 @@
 
 	return ProcessRay(
-		simpleRay,
-		hitA,
-		hitB,
-		vssRays,
-		box,
-		castDoubleRay,
-		pruneInvalidRays
-		);
+					  simpleRay,
+					  hitA,
+					  hitB,
+					  vssRays,
+					  box,
+					  castDoubleRay,
+					  pruneInvalidRays
+					  );
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1867)
@@ -181,4 +181,5 @@
 
 
+  Vector3 GetRandomPoint(const Vector3 &r) const;
   Vector3 GetRandomPoint() const;
   Vector3 GetRandomSurfacePoint() const;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Makefile
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1832)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Makefile	(revision 1867)
@@ -1,5 +1,5 @@
 #############################################################################
 # Makefile for building: preprocessor
-# Generated by qmake (2.00a) (Qt 4.1.2) on: ?t 30. XI 15:32:50 2006
+# Generated by qmake (2.00a) (Qt 4.1.2) on: pá 8. XII 16:33:20 2006
 # Project:  preprocessor.pro
 # Template: app
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.h	(revision 1832)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.h	(revision 1867)
@@ -137,4 +137,5 @@
 public:
 
+
   struct RayInfo
   {
@@ -162,4 +163,5 @@
 	}
 
+	
 #define USE_ORIGIN 1
 	
@@ -312,5 +314,7 @@
   AxisAlignedBox3 dirBBox;
 
-  
+  // evaluated importance of this node
+  float mImportance;
+
   inline RssTreeNode(RssTreeInterior *p);
 
@@ -328,5 +332,6 @@
   }
 
-  
+  float GetImportance() const;
+
 	
 };
@@ -339,5 +344,5 @@
 {
 public:
-  // plane in local modelling coordinates
+  // plane in world coordinates
   float position;
 
@@ -359,4 +364,11 @@
   virtual int GetAccessTime() {
     return lastAccessTime;
+  }
+
+  float GetRelativePosition() const {
+	if (axis < 3)
+	  return (position - bbox.Min(axis))/bbox.Size(axis);
+	else
+	  return (position - dirBBox.Min(axis-3))/dirBBox.Size(axis-3);
   }
 
@@ -423,8 +435,5 @@
 	
   bool mValidPvs;
-  float mImportance;
-  
-  HaltonSequence halton;
-
+  
   Beam mBeam;
   
@@ -490,5 +499,4 @@
   }
 
-  float GetImportance() const;
   
   float GetSqrRayContribution() const {
@@ -621,5 +629,7 @@
   
   
-  
+  Halton<5> halton;
+  
+
   /////////////////////////////
   // Basic properties
@@ -1086,5 +1096,19 @@
   PushRoots(stack<RayTraversalData> &st, RssTreeNode::RayInfo &info) const;
 
-
+  void
+  UpdateImportance(
+				   RssTreeNode *node);
+
+  void
+  GenerateRay(float *params, SimpleRayContainer &rays);
+
+  void
+  GenerateLeafRay(
+				  float *params,
+				  SimpleRayContainer &rays,
+				  const AxisAlignedBox3 &box,
+				  const AxisAlignedBox3 &dirBBox
+				  );
+	
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/KdTree.cpp	(revision 1867)
@@ -677,39 +677,39 @@
 	  ObjectContainer::const_iterator mi;
 	  for ( mi = leaf->mObjects.begin();
-					mi != leaf->mObjects.end();
-					mi++) {
-			Intersectable *object = *mi;
-			if (!object->Mailed() ) {
-				object->Mail();
-				if (ray.mFlags & Ray::STORE_TESTED_OBJECTS)
-					ray.testedObjects.push_back(object);
-				
-				static int oi=1;
-				if (MeshDebug) 
-					cout<<"Object "<<oi++;
-				
-				hits += object->CastRay(ray);
-				
-				if (MeshDebug) {
-					if (!ray.intersections.empty()) 
-						cout<<"nearest t="<<ray.intersections[0].mT<<endl;
-					else
-						cout<<"nearest t=-INF"<<endl;
-				}	  
-			}
+			mi != leaf->mObjects.end();
+			mi++) {
+		Intersectable *object = *mi;
+		if (!object->Mailed() ) {
+		  object->Mail();
+		  if (ray.mFlags & Ray::STORE_TESTED_OBJECTS)
+			ray.testedObjects.push_back(object);
+		  
+		  static int oi=1;
+		  if (MeshDebug) 
+			cout<<"Object "<<oi++;
+		  
+		  hits += object->CastRay(ray);
+		  
+		  if (MeshDebug) {
+			if (!ray.intersections.empty()) 
+			  cout<<"nearest t="<<ray.intersections[0].mT<<endl;
+			else
+			  cout<<"nearest t=-INF"<<endl;
+		  }	  
+		}
 	  }
 	  
 	  if (hits && ray.GetType() == Ray::LOCAL_RAY)
-			if (ray.intersections[0].mT <= maxt)
-				break;
+		if (ray.intersections[0].mT <= maxt)
+		  break;
 	  
 	  // get the next node from the stack
 	  if (tStack.empty())
-			break;
+		break;
 	  
 	  entp = extp;
 	  mint = maxt;
 	  if (ray.GetType() == Ray::LINE_SEGMENT && mint > 1.0f)
-			break;
+		break;
 	  
 	  RayTraversalData &s  = tStack.top();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1842)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1867)
@@ -284,23 +284,24 @@
 	//-- mailing stuff
 
-	static void NewMail(const int reserve = 1) 
-	{
-		sMailId += sReservedMailboxes;
-		sReservedMailboxes = reserve;
-	}
-
-	void Mail() { mMailbox = sMailId; }
-	bool Mailed() const { return mMailbox == sMailId; }
-
-	void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
-	bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
-
-	int IncMail() { return ++ mMailbox - sMailId; }
+  //	static void NewMail(const int reserve = 1) 
+  //	{
+  //		sMailId += sReservedMailboxes;
+  //		sReservedMailboxes = reserve;
+  //	}
+
+  //	void Mail() { mMailbox = sMailId; }
+  //	bool Mailed() const { return mMailbox == sMailId; }
+
+  //	void Mail(const int mailbox) { mMailbox = sMailId + mailbox; }
+  //	bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; }
+
+  //	int IncMail() { return ++ mMailbox - sMailId; }
 
 
 	// last mail id -> warning not thread safe!
 	// both mailId and mailbox should be unique for each thread!!!
-	static int sMailId;
-	static int sReservedMailboxes;
+
+  //static int sMailId;
+  //static int sReservedMailboxes;
 	
   int GetFilteredPvsSize() const {
Index: GTP/trunk/Lib/Vis/Preprocessing/src/MutualVisibility.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/MutualVisibility.cpp	(revision 1328)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/MutualVisibility.cpp	(revision 1867)
@@ -160,11 +160,12 @@
   }
 
+  //  int id = Mailable::GetThreadId();
   for (i=0; i < 4; i++) {
     RaySample *sample = &shaft.mSamples[i];
     for (j=0; j < sample->mIntersections.size(); j++) {
       if (sample->mIntersections[j].mObject->IncMail() == 4) {
-	cerr<<"T";
-	shaft.mError = 0.0f;
-	return;
+		cerr<<"T";
+		shaft.mError = 0.0f;
+		return;
       }
     }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Vector3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Vector3.cpp	(revision 1832)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Vector3.cpp	(revision 1867)
@@ -196,4 +196,5 @@
 #define USE_HALTON 0
 
+
 Vector3
 UniformRandomVector()
@@ -209,14 +210,60 @@
    r2 = RandomValue(0.0f, 1.0f);
 #endif
-   
+
+   return UniformRandomVector(r1, r2);
+}
+
+Vector3
+UniformRandomVector(const float r1, const float r2)
+{
    float cosTheta = 1.0f - 2*r1;
-	 float sinTheta = sqrt(1 - sqr(cosTheta));
-	 float fi = 2.0f*M_PI*r2;
-  
-	 Vector3 dir(sinTheta*sin(fi),
-							 cosTheta,
-							 sinTheta*cos(fi));
-  
-  return dir;
+   float sinTheta = sqrt(1 - sqr(cosTheta));
+   float fi = 2.0f*M_PI*r2;
+   
+   Vector3 dir(sinTheta*sin(fi),
+			   cosTheta,
+			   sinTheta*cos(fi));
+   
+   return dir;
+}
+
+
+Vector3
+CosineRandomVector(const Vector3 &normal)
+{
+  //  float r1 = RandomValue(0.0f, 1.0f);
+  //  float r2 = RandomValue(0.0f, 1.0f);
+  float r1, r2;
+  
+#if USE_HALTON 
+  halton2.GetNext(r1, r2);
+#else
+   r1 = RandomValue(0.0f, 1.0f);
+   r2 = RandomValue(0.0f, 1.0f);
+#endif
+
+   float theta = 2.0f*M_PI*r2;
+   float radius = sqrt(r1);
+   float x = radius*sin(theta);
+   float z = radius*cos(theta);
+   float y = sqrt(1.0f - x*x - z*z);
+
+   
+   Vector3 dir(x,
+			   y,
+			   z);
+   
+   
+   //  return Normalize(dir);
+   
+   Matrix4x4 m = RotationVectorsMatrix(
+									   normal,
+									   Vector3(0,1,0));
+   Matrix4x4 mi = Invert(m);
+   m = m*RotationVectorsMatrix(
+							   Vector3(0,1,0),
+							   Normalize(dir))*mi;
+  
+   return TransformNormal(m, normal);
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1841)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssTree.cpp	(revision 1867)
@@ -352,5 +352,5 @@
 	leaf->dirBBox.Initialize();
 	leaf->dirBBox.SetMin(2, 0.0f);
-	leaf->dirBBox.SetMax(2, 1.0f);
+	leaf->dirBBox.SetMax(2, 0.0f);
 	mRoots[0] = leaf;
 	stat.nodes = 1;
@@ -1237,7 +1237,7 @@
   node->axis = axis;
   node->position = info.position;
-  //  node->bbox = box;
-  //  node->dirBBox = GetDirBBox(leaf);
-  
+
+  node->bbox = GetBBox(leaf);
+  node->dirBBox = GetDirBBox(leaf);
   
   RssTreeLeaf *back = new RssTreeLeaf(node, info.raysBack);
@@ -1245,7 +1245,4 @@
 
   
-  // update halton generator
-  back->halton.index = leaf->halton.index;
-  front->halton.index = leaf->halton.index;
   
   // replace a link from node's parent
@@ -1810,12 +1807,16 @@
   int leaves = 0;
 
+  for (int i=0; i < mRoots.size(); i++)
+	UpdateImportance(mRoots[i]);
+  
   while (!tstack.empty()) {
     RssTreeNode *node = tstack.top();
-    tstack.pop();
-		
+	tstack.pop();
+	
     if (node->IsLeaf()) {
 	  leaves++;
 	  RssTreeLeaf *leaf = (RssTreeLeaf *)node;
-	  UpdatePvsSize(leaf);
+	  // updated above already
+	  //	  UpdatePvsSize(leaf);
 	  
 	  sumPvsSize += leaf->GetPvsSize();
@@ -1841,8 +1842,6 @@
 	  sumImportance += imp;
 	  
-
 	} else {
 	  RssTreeInterior *in = (RssTreeInterior *)node;
-	  // both nodes for directional splits
 	  tstack.push(in->front);
 	  tstack.push(in->back);
@@ -1858,7 +1857,56 @@
   stat.avgWeightedRayContribution = sumWeightedRayContribution/(float)sumRays;
   stat.rayRefs = (int)sumRays;
-}
-
-
+  
+}
+
+void
+RssTree::UpdateImportance(
+						  RssTreeNode *node)
+{
+  if (node->IsLeaf()) {
+	UpdatePvsSize((RssTreeLeaf *)node);
+  } else {
+	RssTreeInterior *in = (RssTreeInterior *)node;
+	UpdateImportance(in->front);
+	UpdateImportance(in->back);
+	node->mImportance = in->front->mImportance + in->back->mImportance;
+  }
+}
+
+// generate a single ray described by parameters in a unit cube
+void
+RssTree::GenerateRay(float *params, SimpleRayContainer &rays)
+{
+  RssTreeNode *node;
+  
+  // works only with single root now!
+  node = mRoots[0];
+  
+  while (!node->IsLeaf()) {
+	RssTreeInterior *in = (RssTreeInterior *)node;
+	// decide whether to go left or right
+	int axis = in->axis;
+	float pos = in->GetRelativePosition(); 
+	
+	float r = in->back->GetImportance()/(in->back->GetImportance() + in->front->GetImportance());
+	
+	//	cout<<"axis="<<axis<<" pos="<<pos<<endl;
+	//	cout<<GetBBox(in)<<endl;
+	//	cout<<GetDirBBox(in)<<endl;
+	//	cout<<"********"<<endl;
+	
+	if (params[axis] < r) {
+	  node = in->back;
+	  params[axis] = params[axis] / pos;
+	} else {
+	  node = in->front;
+	  params[axis] = (params[axis] - pos) / ( 1.0f - pos);
+	}
+  }
+
+  //  cout<<params[0]<<" "<<params[1]<<" "<<params[2]<<" "<<params[3]<<" "<<params[4]<<endl;
+  
+  GenerateLeafRay(params, rays, node->bbox, node->dirBBox);
+}
 
 int
@@ -1867,4 +1915,8 @@
 					  SimpleRayContainer &rays)
 {
+
+  
+
+
   stack<RssTreeNode *> tstack;
   PushRoots(tstack);
@@ -2195,69 +2247,13 @@
   for (int i=0; i < numberOfRays; i++) {
 	//	Debug<<i<<flush;
-
-	Vector3 origin, direction;
-	Vector3 dirVector;
-	
-	Vector3 pVector;
-	Vector3 dVector;
-	
-	bool useHalton = false;
-	
-	
-	if (useHalton) {
-	  // generate a random 5D vector
-	  pVector = Vector3(leaf->halton.GetNumber(1),
-						leaf->halton.GetNumber(2),
-						leaf->halton.GetNumber(3));
-	  
-	  dVector = Vector3(leaf->halton.GetNumber(4),
-						leaf->halton.GetNumber(5),
-						0.0f);
-	  
-	  leaf->halton.GenerateNext();
-	} else {
-	  pVector = Vector3(RandomValue(0.0f, 1.0f),
-						RandomValue(0.0f, 1.0f),
-						RandomValue(0.0f, 1.0f));
-	  
-	  dVector = Vector3(RandomValue(0.0f, 1.0f),
-						RandomValue(0.0f, 1.0f),
-						0.0f);
-	}
-	
-	origin = box.GetPoint(pVector);
-	dirVector = dirBox.GetPoint(dVector);
-	
-	direction = VssRay::GetInvDirParam(dirVector.x, dirVector.y);
-	
-	//	float dist = Min(avgLength*0.5f, Magnitude(GetBBox(leaf).Size()));
-	float dist = 0.0f;
-	float minT, maxT;
-
-	// compute interection of the ray with the box
-#if 1
-	if (box.ComputeMinMaxT(origin, direction, &minT, &maxT) && minT < maxT)
-	  dist = (maxT + 1e-2*boxSize);
-#else
-	dist = 0.5f*boxSize;
-#endif
-
-	origin += direction*dist;
-	
-#if 0
-	static int counter = 0;
-	//	Debug<<counter++<<flush;
-
-	if (counter > 10374968) {
-	  Debug<<"size="<<rays.size()<<endl;
-	  Debug<<"capacity="<<rays.capacity()<<endl;
-	  Debug<<"o="<<origin<<endl;
-	  Debug<<"d="<<direction<<endl;
-	}
-#endif  
-	//Debug<<"dir vector.x="<<dirVector.x<<"direction'.x="<<atan2(direction.x, direction.y)<<endl;
-	rays.push_back(SimpleRay(origin, direction));
-	//	Debug<<endl;
-	
+	float r[5];
+	
+	r[0] = RandomValue(0.0f, 1.0f);
+	r[1] = RandomValue(0.0f, 1.0f);
+	r[2] = RandomValue(0.0f, 1.0f);
+	r[3] = RandomValue(0.0f, 1.0f);
+	r[4] = RandomValue(0.0f, 1.0f);
+	
+	GenerateLeafRay(r, rays, box, dirBox);
   }
 
@@ -2269,4 +2265,36 @@
 	rays[i].mPdf = p;
   }
+}
+
+void
+RssTree::GenerateLeafRay(
+						 float *params,
+						 SimpleRayContainer &rays,
+						 const AxisAlignedBox3 &box,
+						 const AxisAlignedBox3 &dirBBox
+						 )
+{
+  Vector3 origin = bbox.GetPoint(Vector3(params[0], params[1], params[2]));
+  Vector3 dirVector = dirBBox.GetPoint(Vector3(params[3], params[4], 0.0f));
+  Vector3 direction = VssRay::GetInvDirParam(dirVector.x, dirVector.y);
+  
+  //	float dist = Min(avgLength*0.5f, Magnitude(GetBBox(leaf).Size()));
+  float dist = 0.0f;
+  float minT, maxT;
+  
+  float boxSize = Magnitude(bbox.Size());
+  // compute interection of the ray with the box
+#if 1
+  if (bbox.ComputeMinMaxT(origin, direction, &minT, &maxT) && minT < maxT)
+	dist = (maxT + 1e-2*boxSize);
+#else
+  dist = 0.5f*boxSize;
+#endif
+  
+  origin += direction*dist;
+  
+  
+  //Debug<<"dir vector.x="<<dirVector.x<<"direction'.x="<<atan2(direction.x, direction.y)<<endl;
+  rays.push_back(SimpleRay(origin, direction));
 }
 
@@ -2378,26 +2406,12 @@
 	  Vector3 dVector;
 
-	  bool useHalton = true;
-	  
-	  if (useHalton) {
-		// generate a random 5D vector
-		pVector = Vector3(leaf->halton.GetNumber(1),
-						  leaf->halton.GetNumber(2),
-						  leaf->halton.GetNumber(3));
-		
-		dVector = Vector3(leaf->halton.GetNumber(4),
-						  leaf->halton.GetNumber(5),
-						  0.0f);
-		
-		leaf->halton.GenerateNext();
-	  } else {
-		pVector = Vector3(RandomValue(0.0f, 1.0f),
-						  RandomValue(0.0f, 1.0f),
-						  RandomValue(0.0f, 1.0f));
-		
-		dVector = Vector3(RandomValue(0.0f, 1.0f),
-						  RandomValue(0.0f, 1.0f),
-						  0.0f);
-	  }
+	  pVector = Vector3(RandomValue(0.0f, 1.0f),
+						RandomValue(0.0f, 1.0f),
+						RandomValue(0.0f, 1.0f));
+	  
+	  dVector = Vector3(RandomValue(0.0f, 1.0f),
+						RandomValue(0.0f, 1.0f),
+						0.0f);
+	  
 	  
 	  origin = box.GetPoint(pVector);
@@ -2625,5 +2639,5 @@
 	  if (node->IsLeaf()) {
 		RssTreeLeaf *leaf = (RssTreeLeaf *)node;
-		//		prunned += PruneRaysRandom(leaf, ratio);
+		// prunned += PruneRaysRandom(leaf, ratio);
 		prunned += PruneRaysContribution(leaf, ratio);
 	  } else {
@@ -2653,5 +2667,13 @@
 {
 
-
+  float param[5];
+
+  for (int i=0; i < numberOfRays; i++) {
+	halton.GetNext(param);
+	GenerateRay(param, rays);
+  }
+
+  return rays.size();
+  
   vector<RssTreeLeaf *> leaves;
 
@@ -2864,5 +2886,5 @@
 	
 	// $$ 
-	sumWeights = (float)leaf->mTotalRays;
+	// sumWeights = leaf->mTotalRays;
 
 	//$$ test 30.11. 2006 
@@ -2890,5 +2912,5 @@
 
 float
-RssTreeLeaf::GetImportance()  const
+RssTreeNode::GetImportance()  const
 {
   //  return sqr(mImportance);
@@ -3129,3 +3151,6 @@
 
 
-}
+
+
+
+}
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Triangle3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Triangle3.cpp	(revision 1715)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Triangle3.cpp	(revision 1867)
@@ -29,5 +29,9 @@
 
 
-int Triangle3::CastRay(const Ray &ray, float &t, const float nearestT, Vector3 &normal) const
+int
+Triangle3::CastRay(const Ray &ray,
+				   float &t,
+				   const float nearestT,
+				   Vector3 &normal) const
 {
 #if 0
@@ -38,8 +42,9 @@
 
 	Polygon3 poly(vertices);
+
+	int dummy = poly.CastRay(ray, t, nearestT);
+	normal = poly.GetNormal();
 	
-	int dummy = poly.CastRay(ray, t, nearestT);
-
-	cout << "polyversion code: " << dummy << " t: " << t << " nearestT: " << nearestT << endl;
+	//	cout << "polyversion code: " << dummy << " t: " << t << " nearestT: " << nearestT << endl;
 	return dummy;
 #endif
@@ -83,7 +88,7 @@
     t = a / b;
 
-    if (t < 0.0) // ray goes away from triangle
+    if (t <= Limits::Small) // ray goes away from triangle
 	{
-		return Ray::NO_INTERSECTION; // => no intersect
+	  return Ray::INTERSECTION_OUT_OF_LIMITS;
 	}
 	// already found nearer intersection
@@ -113,10 +118,12 @@
 	const float wu = DotProd(w, u);
     const float wv = DotProd(w, v);
-    const float D = uv * uv - uu * vv;
+
+
+	const float D = uv * uv - uu * vv;
 
     // get and test parametric coords
     const float s = (uv * wv - vv * wu) / D;
 
-    if ((s < 0.0) || (s > 1.0)) // pt is outside triangle
+    if ((s < -Limits::Small) || (s > 1.0f + Limits::Small)) // pt is outside triangle
 	{	
         return Ray::NO_INTERSECTION;
@@ -125,5 +132,5 @@
 	const float s2 = (uv * wu - uu * wv) / D;
 
-    if ((s2 < 0.0) || ((s + s2) > 1.0)) // pt is outside triangle
+    if ((s2 < -Limits::Small) || ((s + s2) > 1.0f + Limits::Small)) // pt is outside triangle
 	{	
         return Ray::NO_INTERSECTION;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VssRay.h	(revision 1867)
@@ -14,5 +14,5 @@
 class KdNode;
 
-#define ABS_CONTRIBUTION_WEIGHT 0.5f
+#define ABS_CONTRIBUTION_WEIGHT 0.9f
 
 class VssRay {
@@ -30,4 +30,7 @@
   };
 
+  // Id of the generating SimpleRay
+  int mGeneratingRayId;
+  
   static int mailID;
   int mMailbox;
@@ -69,5 +72,4 @@
   // sum of relative ray contributions per object
   float mRelativePvsContribution;
-
 
   // weighted contribution to the pvs (based on the pass the ray was casted at)
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayCaster.cpp	(revision 1867)
@@ -39,49 +39,52 @@
 /** Checks if ray is valid, (e.g., not in empty view space or outside the view space)
 */
-bool RayCaster::ValidateRay(const Vector3 &origin,
-							const Vector3 &direction,
-							const AxisAlignedBox3 &box,
-							Intersection &hit)
+bool
+RayCaster::ValidateRay(const Vector3 &origin,
+					   const Vector3 &direction,
+					   const AxisAlignedBox3 &box,
+					   Intersection &hit)
 {
-	if (!hit.mObject)  {
-	  // compute intersection with the scene bounding box
+  if (!hit.mObject)  {
+	// compute intersection with the scene bounding box
 #if EXACT_BOX_CLIPPING
-	  static Ray ray;
-	  mPreprocessor.SetupRay(ray, origin, direction);
-	  
-	  float tmin, tmax;
-	  if (box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax)) {
-		hit.mPoint = ray.Extrap(tmax);
-	  }
-	  else {
-		// 		cout<<" invalid hp "<<tmin<<" "<<tmax<<endl;
-		// 		cout<<" box "<<box<<endl;
-		// 		cout<<" origin "<<origin<<endl;
-		// 		cout<<" direction "<<direction<<endl;
-		// 		cout<< "inv dir"<<ray.GetInvDir()<<endl;
-		return false;
-	  }
+	static Ray ray;
+	mPreprocessor.SetupRay(ray, origin, direction);
+	
+	float tmin, tmax;
+	if (box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax)) {
+	  hit.mPoint = ray.Extrap(tmax);
+	}
+	else {
+	  // 		cout<<" invalid hp "<<tmin<<" "<<tmax<<endl;
+	  // 		cout<<" box "<<box<<endl;
+	  // 		cout<<" origin "<<origin<<endl;
+	  // 		cout<<" direction "<<direction<<endl;
+	  // 		cout<< "inv dir"<<ray.GetInvDir()<<endl;
+	  return false;
+	}
 #else
-	  hit.mPoint = origin + direction*Magnitude(box.Diagonal());
+	hit.mPoint = origin + direction*Magnitude(box.Diagonal());
 #endif
-	}
-	else if (mPreprocessor.mDetectEmptyViewSpace) {
-	  if (DotProd(hit.mNormal, direction) >= 0) {	
+  }
+  else
+	if (mPreprocessor.mDetectEmptyViewSpace) {
+	  if (DotProd(hit.mNormal, direction) >= -Limits::Small) {	
 		hit.mObject = NULL;
 		return false;
 	  }
 	}
-	
-	return true;
+  
+  return true;
 }
 
 
-int RayCaster::ProcessRay(const SimpleRay &simpleRay,
-						  Intersection &hitA,
-						  Intersection &hitB,
-						  VssRayContainer &vssRays,
-						  const AxisAlignedBox3 &box,
-						  const bool castDoubleRay,
-						  const bool pruneInvalidRays)
+int
+RayCaster::ProcessRay(const SimpleRay &simpleRay,
+					  Intersection &hitA,
+					  Intersection &hitB,
+					  VssRayContainer &vssRays,
+					  const AxisAlignedBox3 &box,
+					  const bool castDoubleRay,
+					  const bool pruneInvalidRays)
 {
 	int hits = 0;
@@ -90,7 +93,10 @@
 	Debug<<"PRA"<<flush;
 #endif
+
+	// regardless of the pruneInvalidRays setting reject rays whic degenerate to a point
+	if (EpsilonEqualV3(hitA.mPoint, hitB.mPoint, Limits::Small))
+	  return 0;
 	
-	if (pruneInvalidRays)
-	{
+	if (pruneInvalidRays) {
 	  if (!hitA.mObject && !hitB.mObject) {
 		return 0;
@@ -100,24 +106,26 @@
 	const bool validA = 
 	  ValidateRay(simpleRay.mOrigin, simpleRay.mDirection, box, hitA);
-
+	
+	const bool validB = castDoubleRay && 
+	  ValidateRay(simpleRay.mOrigin, -simpleRay.mDirection, box, hitB);
+	
 #if DEBUG_RAYCAST
 	Debug<<"PR1"<<flush;
 #endif
 	
-	if (!validA && pruneInvalidRays)
-	  {
+	// reset both contributions
+	if (!validA || !validB) {
+	  if (pruneInvalidRays)
 		return 0;
-	  }
+	  // reset both contributions of this ray
+	  hitA.mObject = NULL;
+	  hitB.mObject = NULL;
+	}
+	  
 	
-	const bool validB = castDoubleRay && 
-	  ValidateRay(simpleRay.mOrigin, -simpleRay.mDirection, box, hitB);
-	
-	if (!validB && pruneInvalidRays)
-	  {
-		return 0;
-	}
-
-	const bool validSample = !pruneInvalidRays || (hitA.mObject != hitB.mObject);
-
+	const bool validSample = true;
+	// 8.11. 2007 JB
+	// degenerate rays checked by geometrical constraint...
+	//	!pruneInvalidRays || (hitA.mObject != hitB.mObject);
 	
 #if DEBUG_RAYCAST
@@ -126,23 +134,24 @@
 
 	if (validSample) {
-	  if (!pruneInvalidRays || hitA.mObject) 
-		{
-		  VssRay *vssRay = new VssRay(
-									  hitB.mPoint,
-									  hitA.mPoint,
-									  hitB.mObject,
-									  hitA.mObject,
-									  mPreprocessor.mPass,
-									  simpleRay.mPdf
-									  );
-		  if (validA)
-			vssRay->mFlags |= VssRay::Valid;
-		  vssRays.push_back(vssRay);
-		  ++ hits;
-		  //cout << "vssray 1: " << *vssRay << " " << vssRay->mTermination - vssRay->mOrigin << endl;
-		}
-
+	  if (!pruneInvalidRays || hitA.mObject) {
+		VssRay *vssRay = new VssRay(
+									hitB.mPoint,
+									hitA.mPoint,
+									hitB.mObject,
+									hitA.mObject,
+									mPreprocessor.mPass,
+									simpleRay.mPdf
+									);
+		
+		if (validA)
+		  vssRay->mFlags |= VssRay::Valid;
+		vssRay->mGeneratingRayId = simpleRay.mId;
+		vssRays.push_back(vssRay);
+		++ hits;
+		//cout << "vssray 1: " << *vssRay << " " << vssRay->mTermination - vssRay->mOrigin << endl;
+	  }
+	  
 #if DEBUG_RAYCAST
-	Debug<<"PR3"<<flush;
+	  Debug<<"PR3"<<flush;
 #endif
 
@@ -150,14 +159,15 @@
 		{
 		  VssRay *vssRay = new VssRay(
-																	hitA.mPoint,
-																	hitB.mPoint,
-																	hitA.mObject,
-																	hitB.mObject,
-																	mPreprocessor.mPass,
-																	simpleRay.mPdf
-																	);
+									  hitA.mPoint,
+									  hitB.mPoint,
+									  hitA.mObject,
+									  hitB.mObject,
+									  mPreprocessor.mPass,
+									  simpleRay.mPdf
+									  );
 		  if (validB)
-				vssRay->mFlags |= VssRay::Valid;
+			vssRay->mFlags |= VssRay::Valid;
 		  
+		  vssRay->mGeneratingRayId = simpleRay.mId;
 		  vssRays.push_back(vssRay);
 		  ++ hits;
@@ -165,5 +175,5 @@
 		}
 	}
-
+	
 #if DEBUG_RAYCAST
 	Debug<<"PR4"<<flush;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1842)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/main.cpp	(revision 1867)
@@ -48,5 +48,4 @@
 using namespace GtpVisibilityPreprocessor;
 
-Preprocessor *preprocessor = NULL;
 GlRendererWidget *rendererWidget = NULL;
 
@@ -266,5 +265,4 @@
 	PreprocessorThread *pt;
 
-
 #if USE_QT
 	// create a qt application first (must be created before any opengl widget ...)
@@ -280,4 +278,6 @@
 #endif
 
+	preprocessor->SetThread(pt);
+	
 	bool guiSupported = false;
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1763)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Intersectable.h	(revision 1867)
@@ -6,4 +6,5 @@
 #include <set>
 #include "VssRay.h"
+#include "Mailable.h"
 
 namespace GtpVisibilityPreprocessor {
@@ -74,5 +75,5 @@
   
   Intersectable(): 
-  mMailbox(0), 
+	mMailbox(0), 
   //mReferences(0), 
   mBvhLeaf(0), 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BoostPreprocessorThread.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BoostPreprocessorThread.h	(revision 1457)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BoostPreprocessorThread.h	(revision 1867)
@@ -25,4 +25,7 @@
 	void operator()();
 
+  int
+  GetCurrentThreadId() const;
+
 protected:
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp	(revision 1829)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/InternalRayCaster.cpp	(revision 1867)
@@ -29,5 +29,5 @@
 {
 	if (simpleRay.mType == Ray::GLOBAL_RAY)
-		return CastGlobalRay(simpleRay, vssRays, box, pruneInvalidRays);
+	  return CastGlobalRay(simpleRay, vssRays, box, pruneInvalidRays);
 	
 	//cout << "internal ray" << endl;
@@ -87,96 +87,101 @@
   static Ray ray;
   int hits = 0;
-	mPreprocessor.SetupRay(ray, simpleRay.mOrigin, simpleRay.mDirection);
-
-	float tmin, tmax;
-	if (!(box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax)))
-		return 0;
-
-	// shift the ray origin to tmin
-	//	Vector3 origin = ray.Extrap(tmin);
-	//	mPreprocessor.SetupRay(ray, origin, simpleRay.mDirection);
-	ray.SetType(Ray::GLOBAL_RAY);
-	ray.mFlags &= ~Ray::CULL_BACKFACES;
-
-
-	VssRay *vssRay;
-	
+  mPreprocessor.SetupRay(ray, simpleRay.mOrigin, simpleRay.mDirection);
+  
+  float tmin, tmax;
+  if (!(box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax)))
+	return 0;
+  
+  // shift the ray origin to tmin
+  //	Vector3 origin = ray.Extrap(tmin);
+  //	mPreprocessor.SetupRay(ray, origin, simpleRay.mDirection);
+  ray.SetType(Ray::GLOBAL_RAY);
+  ray.mFlags &= ~Ray::CULL_BACKFACES;
+  
+
+  VssRay *vssRay;
+  
   if (mKdTree->CastRay(ray)) {
-		// sort intersections
-		ray.SortIntersections();
-		//cout<<"I="<<ray.intersections.size()<<endl;
-
-		
-		Ray::Intersection &hit = ray.intersections[0];
-
-		if (DotProd(hit.mNormal, ray.GetDir()) < 0) {
-			// insert intial segment
-			vssRay = new VssRay(
-													ray.Extrap(tmin),
-													ray.Extrap(hit.mT),
-													NULL,
-													hit.mObject,
-													mPreprocessor.mPass,
-													simpleRay.mPdf
-													);
-			vssRay->mFlags |= VssRay::Valid;
-			vssRays.push_back(vssRay);
-			++hits;
+	// sort intersections
+	ray.SortIntersections();
+	//	cout<<"I="<<ray.intersections.size()<<endl;
+	
+	
+	Ray::Intersection &hit = ray.intersections[0];
+	
+	if (DotProd(hit.mNormal, ray.GetDir()) < 0) {
+	  //	  cout<<"F:"<<tmin<<" "<<hit.mT<<endl;
+	  // insert intial segment
+	  vssRay = new VssRay(
+						  ray.Extrap(tmin),
+						  ray.Extrap(hit.mT),
+						  NULL,
+						  hit.mObject,
+						  mPreprocessor.mPass,
+						  simpleRay.mPdf
+						  );
+
+	  vssRay->mFlags |= VssRay::Valid;
+	  vssRays.push_back(vssRay);
+	  ++hits;
+	}
+				
+	hit = ray.intersections[ray.intersections.size()-1];
+	if (DotProd(hit.mNormal, ray.GetDir()) > 0) {
+	  //	  cout<<"L:"<<tmax<<" "<<hit.mT<<endl;
+	  
+	  // insert termination segment
+	  vssRay = new VssRay(
+						  ray.Extrap(tmax),
+						  ray.Extrap(hit.mT),
+						  NULL,
+						  hit.mObject,
+						  mPreprocessor.mPass,
+						  simpleRay.mPdf
+						  );
+	  vssRay->mFlags |= VssRay::Valid;
+	  vssRays.push_back(vssRay);
+	  ++hits;
+	}
+	
+	// insert the rest of segments
+	for (int i=0; i < ray.intersections.size() - 1; i++) {
+	  Ray::Intersection &hitA = ray.intersections[i];
+	  Ray::Intersection &hitB = ray.intersections[i + 1];
+	  if (hitB.mT - hitA.mT > Limits::Small) {
+		if (DotProd(hitA.mNormal, ray.GetDir()) > 0 &&
+			DotProd(hitB.mNormal, ray.GetDir()) < 0
+			) {
+		  
+		  vssRay = new VssRay(
+							  ray.Extrap(hitA.mT),
+							  ray.Extrap(hitB.mT),
+							  hitA.mObject,
+							hitB.mObject,
+							  mPreprocessor.mPass,
+							  simpleRay.mPdf
+							  );
+		  vssRay->mFlags |= VssRay::Valid;
+		  vssRays.push_back(vssRay);
+		  ++hits;
+		  
+		  vssRay = new VssRay(
+							  ray.Extrap(hitB.mT),
+							  ray.Extrap(hitA.mT),
+							  hitB.mObject,
+							  hitA.mObject,
+							  mPreprocessor.mPass,
+							  simpleRay.mPdf
+							  );
+		  
+		  vssRay->mFlags |= VssRay::Valid;
+		  vssRays.push_back(vssRay);
+		  ++hits;
 		}
-				
-		hit = ray.intersections[ray.intersections.size()-1];
-		if (DotProd(hit.mNormal, ray.GetDir()) > 0) {
-			
-			// insert termination segment
-			vssRay = new VssRay(
-													ray.Extrap(tmax),
-													ray.Extrap(hit.mT),
-													NULL,
-													hit.mObject,
-													mPreprocessor.mPass,
-													simpleRay.mPdf
-													);
-			vssRay->mFlags |= VssRay::Valid;
-			vssRays.push_back(vssRay);
-			++hits;
-		}
-		
-		// insert the rest of segments
-		for (int i=0; i < ray.intersections.size() - 1; i++) {
-			Ray::Intersection &hitA = ray.intersections[i];
-			Ray::Intersection &hitB = ray.intersections[i + 1];
-			if (DotProd(hitA.mNormal, ray.GetDir()) > 0 &&
-					DotProd(hitB.mNormal, ray.GetDir()) < 0
-					) {
-				
-				vssRay = new VssRay(
-														ray.Extrap(hitA.mT),
-														ray.Extrap(hitB.mT),
-														hitA.mObject,
-														hitB.mObject,
-														mPreprocessor.mPass,
-														simpleRay.mPdf
-														);
-				vssRay->mFlags |= VssRay::Valid;
-				vssRays.push_back(vssRay);
-				++hits;
-				
-				vssRay = new VssRay(
-														ray.Extrap(hitB.mT),
-														ray.Extrap(hitA.mT),
-														hitB.mObject,
-														hitA.mObject,
-														mPreprocessor.mPass,
-														simpleRay.mPdf
-														);
-				
-				vssRay->mFlags |= VssRay::Valid;
-				vssRays.push_back(vssRay);
-				++hits;
-			}
-		}
-	}
-	
-	return hits;
+	  }
+	}
+  }
+  
+  return hits;
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro	(revision 1832)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/preprocessor.pro	(revision 1867)
@@ -107,5 +107,5 @@
 InternalRayCaster.cpp IntelRayCaster.cpp \
 RayCaster.cpp PreprocessorFactory.cpp GvsPreprocessor.cpp \
-Trackball.cpp ObjExporter.cpp SubdivisionCandidate.cpp QtGlViewer.cpp
+Trackball.cpp ObjExporter.cpp SubdivisionCandidate.cpp QtGlViewer.cpp Mailable.cpp
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1867)
@@ -2275,15 +2275,20 @@
   halton.GenerateNext();
   
-  return mMin + size*Vector3(halton.GetNumber(1),
-							 halton.GetNumber(2),
-							 halton.GetNumber(3));
-
+  return GetRandomPoint(Vector3(halton.GetNumber(1),
+								halton.GetNumber(2),
+								halton.GetNumber(3)));
+  
 #else
-  return mMin + Vector3(RandomValue(0.0f, size.x),
-						RandomValue(0.0f, size.y),
-						RandomValue(0.0f, size.z));
+  return GetRandomPoint(Vector3(RandomValue(0.0f, 1.0f),
+								RandomValue(0.0f, 1.0f),
+								RandomValue(0.0f, 1.0f)));
 #endif
 }
 
+Vector3
+AxisAlignedBox3::GetRandomPoint(const Vector3 &r) const
+{
+  return mMin + Size()*r;
+}
 
 Vector3 AxisAlignedBox3::GetRandomSurfacePoint() const
Index: GTP/trunk/Lib/Vis/Preprocessing/src/QtPreprocessorThread.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/QtPreprocessorThread.h	(revision 1842)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/QtPreprocessorThread.h	(revision 1867)
@@ -16,9 +16,14 @@
   ~QtPreprocessorThread();
   
-  void InitThread() {}
+  void InitThread() {
+	PreprocessorThread::InitThread();
+  }
   void RunThread() {
 	start(QThread::LowPriority);
   }
-  
+
+  // This function has to be defined by the thread library used...
+  virtual int GetCurrentThreadId() const;
+
   
 protected:
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1867)
@@ -9,6 +9,6 @@
 bool MeshDebug = false;
 
-int Intersectable::sMailId = 1;//2147483647;
-int Intersectable::sReservedMailboxes = 1;
+  //int Intersectable::sMailId = 1;//2147483647;
+  //int Intersectable::sReservedMailboxes = 1;
 
 struct SortableVertex {
@@ -370,5 +370,5 @@
     return Ray::INTERSECTION_OUT_OF_LIMITS;
   
-  if (t >= nearestT) {
+  if ((ray.GetType() == Ray::LOCAL_RAY) && (t >= nearestT)) {
     return Ray::INTERSECTION_OUT_OF_LIMITS; // no intersection was found
   }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1824)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/SamplingStrategy.cpp	(revision 1867)
@@ -22,5 +22,5 @@
 int
 SamplingStrategy::GenerateSamples(const int number,
-								  SimpleRayContainer &rays) const
+								  SimpleRayContainer &rays)
 {
 	SimpleRay ray;
@@ -67,5 +67,5 @@
 
 
-bool ObjectBasedDistribution::GenerateSample(SimpleRay &ray) const
+bool ObjectBasedDistribution::GenerateSample(SimpleRay &ray)
 {
 	Vector3 origin, direction; 
@@ -99,5 +99,5 @@
 
 
-bool ObjectDirectionBasedDistribution::GenerateSample(SimpleRay &ray) const
+bool ObjectDirectionBasedDistribution::GenerateSample(SimpleRay &ray)
 {	
 	Vector3 origin, direction; 
@@ -127,5 +127,5 @@
 
 
-bool DirectionBasedDistribution::GenerateSample(SimpleRay &ray) const
+bool DirectionBasedDistribution::GenerateSample(SimpleRay &ray)
 {	
 	Vector3 origin, direction; 
@@ -147,5 +147,5 @@
 
 
-bool DirectionBoxBasedDistribution::GenerateSample(SimpleRay &ray) const
+bool DirectionBoxBasedDistribution::GenerateSample(SimpleRay &ray)
 {
 	Vector3 origin, direction; 
@@ -171,26 +171,32 @@
 
 
-bool SpatialBoxBasedDistribution::GenerateSample(SimpleRay &ray) const
-{
-	Vector3 origin, direction; 
-
-	mPreprocessor.mViewCellsManager->GetViewPoint(origin);
-	direction = mPreprocessor.mKdTree->GetBox().GetRandomPoint() - origin;
-	//cout << "z";
-	const float c = Magnitude(direction);
-
-	if (c <= Limits::Small) 
-		return false;
-
-	const float pdf = 1.0f;
-
-	direction *= 1.0f / c;
-	ray = SimpleRay(origin, direction, pdf);
-
-	return true;
-}
-
-
-bool ReverseObjectBasedDistribution::GenerateSample(SimpleRay &ray) const
+bool SpatialBoxBasedDistribution::GenerateSample(SimpleRay &ray)
+{
+  Vector3 origin, direction; 
+
+  float r[6];
+  halton.GetNext(r);
+  mPreprocessor.mViewCellsManager->GetViewPoint(origin, Vector3(r[0],r[1],r[2]));
+  
+  direction = mPreprocessor.mKdTree->GetBox().GetRandomPoint(Vector3(r[3],
+																	 r[4],
+																	 r[5])
+																	 ) - origin;
+  //cout << "z";
+  const float c = Magnitude(direction);
+  
+  if (c <= Limits::Small) 
+	return false;
+  
+  const float pdf = 1.0f;
+  
+  direction *= 1.0f / c;
+  ray = SimpleRay(origin, direction, pdf);
+  
+  return true;
+}
+
+
+bool ReverseObjectBasedDistribution::GenerateSample(SimpleRay &ray)
 {
 	Vector3 origin, direction; 
@@ -230,5 +236,5 @@
 
 
-bool ViewCellBorderBasedDistribution::GenerateSample(SimpleRay &ray) const
+bool ViewCellBorderBasedDistribution::GenerateSample(SimpleRay &ray)
 {
 	Vector3 origin, direction; 
@@ -274,5 +280,5 @@
 
 #if 0
-bool ObjectsInteriorDistribution::GenerateSample(SimpleRay &ray) const
+bool ObjectsInteriorDistribution::GenerateSample(SimpleRay &ray)
 {
 	Vector3 origin, direction; 
@@ -306,5 +312,5 @@
 
 
-bool ReverseViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray) const
+bool ReverseViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
 {
 	Vector3 origin, direction; 
@@ -344,5 +350,5 @@
 
 
-bool ViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray) const
+bool ViewSpaceBorderBasedDistribution::GenerateSample(SimpleRay &ray)
 {
 	Vector3 origin, direction; 
@@ -381,5 +387,5 @@
 
 bool
-RssBasedDistribution::GenerateSample(SimpleRay &ray) const
+RssBasedDistribution::GenerateSample(SimpleRay &ray)
 {
   return false;
@@ -388,36 +394,69 @@
 
 bool
-GlobalLinesDistribution::GenerateSample(SimpleRay &ray) const
-{
-	Vector3 origin, termination, direction; 
-	
-	origin = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
-
-	termination = mPreprocessor.mViewCellsManager->GetViewSpaceBox().GetRandomSurfacePoint();
+GlobalLinesDistribution::GenerateSample(SimpleRay &ray) 
+{
+  Vector3 origin, termination, direction; 
+
+  float radius = 0.5f*Magnitude(mPreprocessor.mViewCellsManager->GetViewSpaceBox().Size());
+  Vector3 center = mPreprocessor.mViewCellsManager->GetViewSpaceBox().Center();
+
+  const int tries = 1000;
+  int i;
+  for (i=0; i < tries; i++) {
+	float r[4];
+	halton.GetNext(r);
+	
+#if 0
+#if 0
+	r[0] = RandomValue(0,1);
+	r[1] = RandomValue(0,1);
+	r[2] = RandomValue(0,1);
+	r[3] = RandomValue(0,1);
+#else
+	r[0] = mHalton.GetNumber(1);
+	r[1] = mHalton.GetNumber(2);
+	r[2] = mHalton.GetNumber(3);
+	r[3] = mHalton.GetNumber(4);
+	mHalton.GenerateNext();
+#endif
+#endif
+	origin = center + (radius*UniformRandomVector(r[0], r[1]));
+	termination = center + (radius*UniformRandomVector(r[2], r[3]));
 	
 	direction = termination - origin;
 	//direction = UniformRandomVector();
-
-
-	// $$ jb the pdf is yet not correct for all sampling methods!
-	const float c = Magnitude(direction);
-	if (c <= Limits::Small) 
-		return false;
-	
-	
-	direction *= 1.0f / c;
-	
-	// a little offset
-	//	origin += direction * 0.001f;
-	
-	// $$ jb the pdf is yet not correct for all sampling methods!
-	const float pdf = 1.0f;
-
+	
+	
+	// $$ jb the pdf is yet not correct for all sampling methods!
+	const float c = Magnitude(direction);
+	if (c <= Limits::Small) 
+	  return false;
+	
+	direction *= 1.0f / c;
+
+	// check if the ray intersects the view space box
+	static Ray ray;
+	ray.Init(origin, direction, Ray::LOCAL_RAY);	
+	
+	float tmin, tmax;
+	if (mPreprocessor.mViewCellsManager->
+		GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))
+	  break;
+  }
+  
+  if (i!=tries) {
+	// $$ jb the pdf is yet not correct for all sampling methods!
+	const float pdf = 1.0f;
+	
+	
 	ray = SimpleRay(origin, direction, pdf);
 	ray.mType = Ray::GLOBAL_RAY;
 	return true;
-}
-
-}
-
-
+  }
+  
+  return false;
+}
+
+}
+
+
