Index: /trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.h	(revision 473)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.h	(revision 477)
@@ -82,5 +82,5 @@
 	/** Probability for crossing one view cell.
 	*/
-	float GetCrossVcProbability();
+	float GetCrossVcProbability() const;
 
 	/// render time for single object of the PVS
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 475)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.h	(revision 477)
@@ -160,39 +160,39 @@
 	virtual bool ViewCellsConstructed() const = 0;
 
-  /** cast line segment to get a list of unique viewcells which are intersected
-	  by this line segment */
+	/** cast line segment to get a list of unique viewcells which are intersected
+		by this line segment 
+	*/
   
-  virtual int CastLineSegment(const Vector3 &origin,
+	virtual int CastLineSegment(const Vector3 &origin,
 							  const Vector3 &termination,
 							  ViewCellContainer &viewcells
 							  ) = 0;
 
-  virtual void GetPvsStatistics(PvsStatistics &stat);
-
-  virtual void
-  PrintPvsStatistics(ostream &s);
-
-  /** Returns probability that view point lies in one view cell.
+	virtual void GetPvsStatistics(PvsStatistics &stat);
+
+	virtual void PrintPvsStatistics(ostream &s);
+
+	/** Returns probability that view point lies in one view cell.
+	*/
+	virtual float GetProbability(ViewCell *viewCell) = 0;
+
+	/** Returns render cost of a single view cell given the render cost of an object.
+	*/
+	virtual float GetRendercost(ViewCell *viewCell, float objRendercost) const = 0;
+
+	/** Returns vector of loaded / generated view cells.
+	*/
+	ViewCellContainer &GetViewCells();
+
+	/** Helper function used to split ray set into one used for view cell
+		construction and one cast after construction.
+	*/
+	void GetRaySets(const VssRayContainer &sourceRays,
+					VssRayContainer &constructionRays, 
+					VssRayContainer &savedRays) const;
+
+  /** Returns accumulated area of all view cells.
   */
-  virtual float GetProbability(ViewCell *viewCell) = 0;
-
-  /** Returns render cost of a single view cell given the render cost of an object.
-  */
-  virtual float GetRendercost(ViewCell *viewCell, float objRendercost) const = 0;
-
-  /** Returns vector of loaded / generated view cells.
-  */
-  ViewCellContainer &GetViewCells();
-
-  /** Helper function used to split ray set into one used for view cell
-      construction and one cast after construction.
-  */
-  void GetRaySets(const VssRayContainer &sourceRays,
-				  VssRayContainer &constructionRays, 
-				  VssRayContainer &savedRays) const;
-
-  /** Returns total area of view cells.
-  */
-  float GetTotalArea();
+  float GetAccVcArea();
 
   /** Returns area of one view cell.
@@ -203,4 +203,6 @@
   */
   float GetVolume(ViewCell *viewCell) const;
+
+  virtual AxisAlignedBox3 GetSceneBbox() const = 0;
 
 protected:
@@ -243,4 +245,6 @@
 	BspViewCellsManager(BspTree *tree, int constructionSamples);
 
+	~BspViewCellsManager();
+
 	int Construct(const ObjectContainer &objects, 
 				  const VssRayContainer &rays,
@@ -271,4 +275,6 @@
 	float GetArea(ViewCell *viewCell) const;
 
+	AxisAlignedBox3 GetSceneBbox() const;
+
 protected:
 
@@ -281,4 +287,6 @@
 	bool ShouldMerge(BspLeaf *front, BspLeaf *back) const;
 
+	void ConstructBspRays(const VssRayContainer &rays,
+						  const int numSamples);
 	/// the BSP tree.
 	BspTree *mBspTree;
@@ -290,9 +298,9 @@
 	/** Exports visualization of the BSP splits.
 	*/
-	void ExportSplits(const ObjectContainer &objects, const VssRayContainer &sampleRays);
+	void ExportSplits(const ObjectContainer &objects);
 
 	/** Exports visualization of the BSP PVS.
 	*/
-	void ExportBspPvs(const ObjectContainer &objects, const VssRayContainer &sampleRays);
+	void ExportBspPvs(const ObjectContainer &objects);
 
 };
@@ -334,4 +342,6 @@
 	float GetProbability(ViewCell *viewCell);
 	float GetRendercost(ViewCell *viewCell, float objRendercost) const;
+	
+	AxisAlignedBox3 GetSceneBbox() const;
 
 protected:
@@ -385,4 +395,6 @@
 	float GetRendercost(ViewCell *viewCell, float objRendercost) const;
 
+	AxisAlignedBox3 GetSceneBbox() const;
+
 protected:
 
@@ -431,4 +443,6 @@
 	float GetArea(ViewCell *viewCell) const;
 
+	AxisAlignedBox3 GetSceneBbox() const;
+
 protected:
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp	(revision 476)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp	(revision 477)
@@ -80,5 +80,6 @@
 		// compute render time of PVS times probability that view point is in view cell
 		const float vcCost = pInVc * mViewCellsManager->GetRendercost(vc, mObjRenderCost);
-		Debug << "cost: " << vcCost << " rcost: " << mViewCellsManager->GetRendercost(vc, mObjRenderCost) << endl;
+		Debug << "cost: " << vcCost << " rcost: "
+			  << mViewCellsManager->GetRendercost(vc, mObjRenderCost) << endl;
 
 		// crossing the border of a view cell is depending on the move speed
@@ -104,11 +105,11 @@
 }
 
-float RenderSimulator::GetCrossVcProbability()
+float RenderSimulator::GetCrossVcProbability() const
 {
-	/*const float avgArea = mViewCellsManager->GetTotalArea() / 
-		mViewCellsManager->GetViewCells().size();
+	// assume the view cells are uniformly distributed
+	const float vcNum = 
+		(float)mViewCellsManager->GetViewCells().size();
 
-	return mMoveSpeed * mViewCellsManager->GetSceneBbox()->SurfaceArea() / 	*/
-	return 0;
+	return 1.0f - (1 / mMoveSpeed * vcNum);
 }
 
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp	(revision 475)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/RssPreprocessor.cpp	(revision 477)
@@ -176,5 +176,5 @@
   if (!use2dSampling) {
 	Vector3 normal;
-	int i = (int)RandomValue(0, mObjects.size()-1);
+	int i = (int)RandomValue(0, (Real)((int)mObjects.size()-1));
 	Intersectable *object = mObjects[i];
 	object->GetRandomSurfacePoint(point, normal);
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 475)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 477)
@@ -151,10 +151,10 @@
 		// pickup a random face of each mesh 
 		Mesh *mesh = mi->GetMesh();
-		int face = (int)RandomValue(0, (int)mesh->mFaces.size() - 1);
+		int face = (int)RandomValue(0, (Real)((int)mesh->mFaces.size() - 1));
 		
 		Polygon3 poly(mesh->mFaces[face], mesh);
 		poly.Scale(1.001f);
 		// now extend a random edge of the face
-		int edge = (int)RandomValue(0, (int)poly.mVertices.size() - 1);
+		int edge = (int)RandomValue(0, (Real)((int)poly.mVertices.size() - 1));
 		float t = RandomValue(0.0f, 1.0f);
 		Vector3 target = t*poly.mVertices[edge] + (1.0f-t)*poly.mVertices[(edge + 1)%
@@ -192,5 +192,5 @@
 		Debug << "Finding random neighbour" << endl;	
 		for (int tries = 0; tries < 10; tries++) {
-			int index = (int)RandomValue(0, pvsSize - 1);
+			int index = (int)RandomValue(0, (Real)(pvsSize - 1));
 			KdPvsData data;
 			KdNode *node;
Index: /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp
===================================================================
--- /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 475)
+++ /trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellsManager.cpp	(revision 477)
@@ -281,4 +281,5 @@
 }
 
+
 float ViewCellsManager::GetVolume(ViewCell *viewCell) const
 {
@@ -287,5 +288,4 @@
 
 
-
 float ViewCellsManager::GetArea(ViewCell *viewCell) const
 {
@@ -294,6 +294,5 @@
 
 
-
-float ViewCellsManager::GetTotalArea()
+float ViewCellsManager::GetAccVcArea()
 {
 	// if already computed
@@ -316,4 +315,5 @@
 	s << mViewCellsStats << endl;
 }
+
 
 /**********************************************************************/
@@ -409,11 +409,21 @@
 {
 	// compute view cell area as subsititute for probability
+#if 0
 	return GetArea(viewCell) / mBspTree->GetBoundingBox().SurfaceArea();
-	//return GetArea(viewCell) / GetTotalArea();
-}
+#else
+	return GetArea(viewCell) / GetAccVcArea();
+#endif
+}
+
 
 float BspViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const
 {
 	return viewCell->GetPvs().GetSize() * objRendercost;
+}
+
+
+AxisAlignedBox3 BspViewCellsManager::GetSceneBbox() const
+{
+	return mBspTree->GetBoundingBox();
 }
 
@@ -430,4 +440,7 @@
 									 const VssRayContainer &rays)
 {
+	if (mBspRays.empty())
+		ConstructBspRays(rays, mConstructionSamples);
+	
 	if (!ViewCellsConstructed())
 	{
@@ -442,5 +455,5 @@
 	Debug << "original view cell partition:\n" << mViewCellsStats << endl;
 		
-	if (1) // export view cells before merge
+	if (1) // export view cells
 	{
 		cout << "exporting initial view cells (=leaves) ... ";
@@ -449,11 +462,12 @@
 		if (exporter)
 		{
-			exporter->SetWireframe();
-			exporter->ExportBspLeaves(*mBspTree, mViewCellsStats.maxPvs);
-			//exporter->ExportBspViewCellPartition(*mBspTree, 0);
+			//exporter->SetWireframe();
+			exporter->SetFilled();
+			exporter->ExportBspViewCellPartition(*mBspTree, 
+				mViewCellsStats.maxPvs);
 				
 			if (0)
 			{
-				Material m;//= RandomMaterial();
+				Material m;
 				m.mDiffuseColor = RgbColor(0, 1, 0);
 				exporter->SetForcedMaterial(m);
@@ -466,21 +480,10 @@
 		}
 		cout << "finished" << endl;
-
-		//-- render simulation after merge
-		cout << "\nevaluating bsp view cells render time after merge ... ";
-  
-		 mRenderSimulator->RenderScene();
-		 SimulationStatistics ss;
-		 mRenderSimulator->GetStatistics(ss);
-         
-		 cout << " finished" << endl;
-		 cout << ss << endl;
-		 Debug << ss << endl;
-
 	}
 
 	cout << "starting post processing using " << mPostProcessSamples << " samples ... ";
-
+		
 	long startTime = GetTime();
+
 
 	// $$JB we do not have connectivity information from the ray in the moment
@@ -489,26 +492,22 @@
 	//-- merge or subdivide view cells
 	int merged = 0;
-#if 0
-
-	RayContainer::const_iterator rit, rit_end = rays.end();
+
 	vector<BspIntersection>::const_iterator iit;
 
-	int limit = min((int)rays.size(), mPostProcessSamples);
-
-	for (int i = 0; i < limit; ++ i)
+	for (int i = 0; i < (int)mBspRays.size(); ++ i)
 	{  
-		Ray *ray = rays[i];
-
+		BspRay *ray = mBspRays[i];
+	  
 		// traverse leaves stored in the rays and compare and merge consecutive
 		// leaves (i.e., the neighbors in the tree)
-		if (ray->bspIntersections.size() < 2)
+		if (ray->intersections.size() < 2)
 			continue;
-
-		iit = ray->bspIntersections.begin();
+	  
+		iit = ray->intersections.begin();
 
 		BspLeaf *previousLeaf = (*iit).mLeaf;
 		++ iit;
 		
-		for (; iit != ray->bspIntersections.end(); ++ iit)
+		for (; iit != ray->intersections.end(); ++ iit)
 		{
 			BspLeaf *leaf = (*iit).mLeaf;
@@ -524,5 +523,5 @@
 		}
 	}
-#endif
+
 	//-- stats and visualizations
 	cout << "finished" << endl;
@@ -531,7 +530,9 @@
 
 	Debug << "Postprocessing: Merged " << merged << " view cells in "
-		  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl;
-
-	//-- recount pvs
+		  << TimeDiff(startTime, GetTime()) *1e-3 << " secs" << endl << endl;
+	
+	// reset view cells and stats
+	mViewCells.clear();
+	mBspTree->CollectViewCells(mViewCells);
 	mViewCellsStats.Reset();
 	mBspTree->EvaluateViewCellsStats(mViewCellsStats);
@@ -540,4 +541,11 @@
 }
 
+
+BspViewCellsManager::~BspViewCellsManager()
+{
+	CLEAR_CONTAINER(mBspRays);
+}
+
+
 int BspViewCellsManager::GetType() const
 {
@@ -551,36 +559,35 @@
 	if (!ViewCellsConstructed())
 		return;
-  
-	//-- recount pvs
-	ViewCellsStatistics vcStats;
-	mBspTree->EvaluateViewCellsStats(vcStats);
-  
+
+	if (mBspRays.empty())
+		ConstructBspRays(sampleRays, mConstructionSamples);
+	
 	if (1) // export view cells
 	{
 		cout << "exporting view cells after merge ... ";
 		Exporter *exporter = Exporter::GetExporter("merged_view_cells.x3d");
-	  
+
 		if (exporter)
 		{
-			exporter->ExportBspViewCellPartition(*mBspTree, vcStats.maxPvs);
-			//exporter->ExportBspViewCellPartition(*mBspTree, 0);
+			exporter->ExportBspViewCellPartition(*mBspTree, 
+				mViewCellsStats.maxPvs);
 			delete exporter;
 		}
-	  
+		
 		cout << "finished" << endl;
 	}	
-  
+
 	//-- visualization of the BSP splits
 	bool exportSplits = false;
 	environment->GetBoolValue("BspTree.Visualization.exportSplits", exportSplits);
-  
+	
 	if (exportSplits)
 	{
 		cout << "exporting splits ... ";
-		ExportSplits(objects, sampleRays);
+	 	ExportSplits(objects);
 		cout << "finished" << endl;
 	}
-  
-	ExportBspPvs(objects, sampleRays);
+
+	ExportBspPvs(objects);
 }
 
@@ -591,6 +598,6 @@
 }
 
-void BspViewCellsManager::ExportSplits(const ObjectContainer &objects,
-									   const VssRayContainer &sampleRays)
+
+void BspViewCellsManager::ExportSplits(const ObjectContainer &objects)
 {
 	Exporter *exporter = Exporter::GetExporter("bsp_splits.x3d");
@@ -602,4 +609,5 @@
 		exporter->SetForcedMaterial(m);
 		exporter->SetWireframe();
+		
 		exporter->ExportBspSplits(*mBspTree, true);
 
@@ -611,218 +619,243 @@
 		exporter->ResetForcedMaterial();
 		
-		bool exportRays = false;
-		bool exportGeometry = false;
-
-		environment->GetBoolValue("BspTree.Visualization.exportRays", exportRays);
-		environment->GetBoolValue("BspTree.Visualization.exportGeometry", exportGeometry);
-
 		// export rays
-		if (exportRays)
+		if (0)
 		{
 			VssRayContainer outRays;
-		  
-			int raysSize = min((int)sampleRays.size(), mVisualizationSamples);
+		
+			int raysSize = min((int)mBspRays.size(), mVisualizationSamples);
+
 			for (int i = 0; i < raysSize; ++ i)
-			{
 				// only rays piercing geometry
-				outRays.push_back(sampleRays[i]);			
-			}
-		  	
+				outRays.push_back(mBspRays[i]->vssRay);
+						
 			// export rays 
 			exporter->ExportRays(outRays, RgbColor(1, 1, 0));
 		}
-		
-		if (exportGeometry)
+
+		if (0)
 			exporter->ExportGeometry(objects);
-		
+
 		delete exporter;
 	}
 }
 
-void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects,
-									   const VssRayContainer &sampleRays)
-{
-  const int leafOut = 10;
-  
-  ViewCell::NewMail();
-  
-  //-- some rays for output
-  const int raysOut = min((int)sampleRays.size(), mVisualizationSamples);
-
-  Debug << "Output view cells:" << endl;
-
-  if (1)
-  {
-	  //-- some random view cells and rays for output
-	  vector<BspLeaf *> bspLeaves;
-	  
-	  for (int i = 0; i < leafOut; ++ i)
-		  bspLeaves.push_back(mBspTree->GetRandomLeaf());	
-
-	  for (int i = 0; i < bspLeaves.size(); ++ i)
-	  {
-		  BspLeaf *leaf = bspLeaves[i];
-		  RayContainer vcRays;
-		  
-		  cout << "creating output for view cell " << i << " ... ";
-		  
-		  // TODO matt
-		  // check whether we can add the current ray to the output rays
-		  /*for (int k = 0; k < raysOut; ++ k) 
-		  {
-			  Ray *ray = sampleRays[k];
-			  
-			  for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
-			  {
-				  BspLeaf *leaf2 = ray->bspIntersections[j].mLeaf;
-				  
-				  if (leaf->GetViewCell() == leaf2->GetViewCell()) 
-				  {
-					  vcRays.push_back(ray);
-				  }
-			  }
-		  }*/
-		  
-		  Intersectable::NewMail();
-		  
-		  BspViewCell *vc = dynamic_cast<BspViewCell *>(leaf->GetViewCell());
-		  
-		  //bspLeaves[j]->Mail();
-		  char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
-		  
-		  Exporter *exporter = Exporter::GetExporter(s);
-		  exporter->SetFilled();
-
-		  exporter->SetWireframe();
-		  //exporter->SetFilled();
-		  
-		  Material m;//= RandomMaterial();
-		  m.mDiffuseColor = RgbColor(1, 1, 0);
-		  exporter->SetForcedMaterial(m);
-		  
-		  if (vc->GetMesh())
-			  exporter->ExportViewCell(vc);
-		  else
-		  {
-			  PolygonContainer vcGeom;
-			  // export view cell geometry
-			  mBspTree->ConstructGeometry(vc, vcGeom);
-			  exporter->ExportPolygons(vcGeom);
-			  CLEAR_CONTAINER(vcGeom);
-		  }		  
-
-		  Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 
-				<< ", piercing rays=" << (int)vcRays.size() << endl;
-		  
-		  // export rays piercing this view cell
-		  //exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));	
-		  
-		  m.mDiffuseColor = RgbColor(1, 0, 0);
-		  exporter->SetForcedMaterial(m);
-		  
-		  // exporter->SetWireframe();
-		  exporter->SetFilled();
-		  
-		  ObjectPvsMap::iterator it, it_end = vc->GetPvs().mEntries.end();
-		  // output PVS of view cell
-		  for (it = vc->GetPvs().mEntries.begin(); it !=  it_end; ++ it) 
-		  {
-			  Intersectable *intersect = (*it).first;
-			  if (!intersect->Mailed())
-			  {
-				  exporter->ExportIntersectable(intersect);
-				  intersect->Mail();
-			  }			
-		  }
-		  
-		  DEL_PTR(exporter);
-		  cout << "finished" << endl;
-	  }
-  }
-  else
-  {
-	  ViewCellContainer viewCells;
-	  RayContainer vcRays;
-	  
-	  mBspTree->CollectViewCells(viewCells);
-	  stable_sort(viewCells.begin(), viewCells.end(), vc_gt);
-	  
-	  const int limit = min(leafOut, (int)viewCells.size()); 
-	  
-	  for (int i = 0; i < limit; ++ i)
-	  {
-		  cout << "creating output for view cell " << i << " ... ";
-			
-		  Intersectable::NewMail();
-		  BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]);
-
-		  cout << "creating output for view cell " << i << " ... ";
-
-		  // TODO matt
-		  // check whether we can add the current ray to the output rays
-		  /*for (int k = 0; k < raysOut; ++ k) 
-		  {
-			  Ray *ray = sampleRays[k];
-
-			  for (int j = 0; j < (int)ray->bspIntersections.size(); ++ j)
-			  {
-				  BspLeaf *leaf = ray->bspIntersections[j].mLeaf;
-
-				  if (vc == leaf->GetViewCell()) 
-					  vcRays.push_back(ray);
-			  }
-		  }*/
-
-		  //bspLeaves[j]->Mail();
-		  char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
-
-		  Exporter *exporter = Exporter::GetExporter(s);	
-		  exporter->SetWireframe();
-
-		  Material m;//= RandomMaterial();
-		  m.mDiffuseColor = RgbColor(0, 1, 0);
-		  exporter->SetForcedMaterial(m);
-
-		  if (vc->GetMesh())
-			  exporter->ExportViewCell(vc);
-		  else
-		  {
-			  PolygonContainer cell;
-			  // export view cell
-			  mBspTree->ConstructGeometry(vc, cell);
-			  exporter->ExportPolygons(cell);
-			  CLEAR_CONTAINER(cell);
-		  }
-		  Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 
-			    << ", piercing rays=" << (int)vcRays.size() << endl;
-
-		  // export rays piercing this view cell
-		  exporter->ExportRays(vcRays, 1000, RgbColor(0, 1, 0));
-	
-		  m.mDiffuseColor = RgbColor(1, 0, 0);
-		  exporter->SetForcedMaterial(m);
-
-		  ObjectPvsMap::const_iterator it, it_end = vc->GetPvs().mEntries.end();
-
-		  // output PVS of view cell
-		  for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 
-		  {
-			  Intersectable *intersect = (*it).first;
-
-			  if (!intersect->Mailed())
-			  {
-				  Material m = RandomMaterial();
-				  exporter->SetForcedMaterial(m);
-
-				  exporter->ExportIntersectable(intersect);
-			
-				  intersect->Mail();
-			  }			
-		  }
+
+void BspViewCellsManager::ExportBspPvs(const ObjectContainer &objects)
+{
+	bool exportRays = false;
+	bool exportGeometry = false;
+
+	environment->GetBoolValue("VspBspTree.Visualization.exportRays", exportRays);
+	environment->GetBoolValue("VspBspTree.Visualization.exportGeometry", exportGeometry);
+
+	const int leafOut = 10;
+	
+	ViewCell::NewMail();
+
+	//-- some rays for output
+	const int raysOut = min((int)mBspRays.size(), mVisualizationSamples);
+	cout << "visualization using " << mVisualizationSamples << " samples" << endl;
+	Debug << "\nOutput view cells: " << endl;
+
+	if (1)
+	{
+		//-- some random view cells and rays for output
+		vector<BspLeaf *> vspBspLeaves;
+
+		for (int i = 0; i < leafOut; ++ i)
+			vspBspLeaves.push_back(mBspTree->GetRandomLeaf());	
+		
+		for (int i = 0; i < (int)vspBspLeaves.size(); ++ i)
+		{
+			VssRayContainer vcRays;
+			cout << "creating output for view cell " << i << " ... ";
+
+			// check whether we can add the current ray to the output rays
+			for (int k = 0; k < raysOut; ++ k) 
+			{
+				BspRay *ray = mBspRays[k];
+
+				for	(int j = 0; j < (int)ray->intersections.size(); ++ j)
+				{
+					BspLeaf *leaf = ray->intersections[j].mLeaf;
+
+					if (vspBspLeaves[i]->GetViewCell() == leaf->GetViewCell()) 
+					{
+						vcRays.push_back(ray->vssRay);
+					}
+				}
+			}
+
+			Intersectable::NewMail();
+
+			BspViewCell *vc = dynamic_cast<BspViewCell *>
+				(vspBspLeaves[i]->GetViewCell());
+
+			//bspLeaves[j]->Mail();
+			char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
+
+			Exporter *exporter = Exporter::GetExporter(s);
+			exporter->SetFilled();
+
+			ObjectPvsMap::iterator it = vc->GetPvs().mEntries.begin();
+
+			exporter->SetWireframe();
+			//exporter->SetFilled();
+
+			Material m;//= RandomMaterial();
+			m.mDiffuseColor = RgbColor(0, 1, 0);
+			exporter->SetForcedMaterial(m);
+
+			if (vc->GetMesh())
+				exporter->ExportViewCell(vc);
+			else
+			{
+				PolygonContainer vcGeom;
+
+				// export view cell geometry
+				mBspTree->ConstructGeometry(vc, vcGeom);
+				exporter->ExportPolygons(vcGeom);
+				CLEAR_CONTAINER(vcGeom);
+			}
+
+			Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 
+					<< ", piercing rays=" << (int)vcRays.size() << endl;
+
+			// export rays piercing this view cell
+			if (exportRays)
+			{
+				//exporter->ExportRays(vcRays, RgbColor(1, 0, 0));
+				exporter->ExportRays(vspBspLeaves[i]->mVssRays, RgbColor(1, 1, 1));
+			}
+
+			m.mDiffuseColor = RgbColor(0, 1, 1);
+			exporter->SetForcedMaterial(m);
+
+			//exporter->SetWireframe();
+			exporter->SetFilled();
+
+			// output PVS of view cell
+			for (; it != vc->GetPvs().mEntries.end(); ++ it) 
+			{
+				Intersectable *intersect = (*it).first;
+				if (!intersect->Mailed())
+				{
+					exporter->ExportIntersectable(intersect);
+					intersect->Mail();
+				}			
+			}
+			Debug << "here1 exportgeom: " << exportGeometry << endl;
+			// output rest of the objects
+			if (exportGeometry)
+			{
+				Material m;//= RandomMaterial();
+				m.mDiffuseColor = RgbColor(0, 0, 1);
+				exporter->SetForcedMaterial(m);
+
+				for (int j = 0; j < objects.size(); ++ j)
+					if (!objects[j]->Mailed())
+					{
+						exporter->SetForcedMaterial(m);
+						exporter->ExportIntersectable(objects[j]);
+						objects[j]->Mail();
+					}
+			}
+			DEL_PTR(exporter);
+			cout << "finished" << endl;
+		}
+	}
+	else
+	{
+		ViewCellContainer viewCells;
+
+		mBspTree->CollectViewCells(viewCells);
+		stable_sort(viewCells.begin(), viewCells.end(), vc_gt);
+
+		int limit = min(leafOut, (int)viewCells.size()); 
+		
+		for (int i = 0; i < limit; ++ i)
+		{
+			cout << "creating output for view cell " << i << " ... ";
+			VssRayContainer vcRays;
+            Intersectable::NewMail();
+			BspViewCell *vc = dynamic_cast<BspViewCell *>(viewCells[i]);
+
+			cout << "creating output for view cell " << i << " ... ";
+
+			// check whether we can add the current ray to the output rays
+			for (int k = 0; k < raysOut; ++ k) 
+			{
+				BspRay *ray = mBspRays[k];
+
+				for	(int j = 0; j < (int)ray->intersections.size(); ++ j)
+				{
+					BspLeaf *leaf = ray->intersections[j].mLeaf;
+
+					if (vc == leaf->GetViewCell()) 
+					{
+						vcRays.push_back(ray->vssRay);
+					}
+				}
+			}
+
+			//bspLeaves[j]->Mail();
+			char s[64]; sprintf(s, "bsp-pvs%04d.x3d", i);
+
+			Exporter *exporter = Exporter::GetExporter(s);
+			
+			exporter->SetWireframe();
+
+			Material m;//= RandomMaterial();
+			m.mDiffuseColor = RgbColor(0, 1, 0);
+			exporter->SetForcedMaterial(m);
+
+			if (vc->GetMesh())
+				exporter->ExportViewCell(vc);
+			else
+			{
+				PolygonContainer vcGeom;
+				// export view cell
+				mBspTree->ConstructGeometry(vc, vcGeom);
+				exporter->ExportPolygons(vcGeom);
+				CLEAR_CONTAINER(vcGeom);
+			}
+
+			
+			Debug << i << ": pvs size=" << (int)vc->GetPvs().GetSize() 
+				  << ", piercing rays=" << (int)vcRays.size() << endl;
+
+			
+			// export rays piercing this view cell
+			exporter->ExportRays(vcRays, RgbColor(0, 1, 0));
+	
+			m.mDiffuseColor = RgbColor(1, 0, 0);
+			exporter->SetForcedMaterial(m);
+
+			ObjectPvsMap::const_iterator it,
+				it_end = vc->GetPvs().mEntries.end();
+
+			// output PVS of view cell
+			for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it) 
+			{
+				Intersectable *intersect = (*it).first;
+
+				if (!intersect->Mailed())
+				{
+					Material m = RandomMaterial();
+			
+					exporter->SetForcedMaterial(m);
+
+					exporter->ExportIntersectable(intersect);
+					intersect->Mail();
+				}			
+			}
 				
-		  DEL_PTR(exporter);
-		  cout << "finished" << endl;
-	  }
-  }
+			DEL_PTR(exporter);
+			cout << "finished" << endl;
+		}
+	}
+
+	Debug << endl;
 }
 
@@ -886,4 +919,30 @@
 
 
+void BspViewCellsManager::ConstructBspRays(const VssRayContainer &rays,
+										   const int numSamples)
+{
+	VssRayContainer::const_iterator it, it_end = rays.end();
+
+	for (it = rays.begin(); it != rays.end() && mBspRays.size() < numSamples; ++ it)
+	{
+		VssRay *vssRay = *it;
+		BspRay *ray = new BspRay(vssRay);
+
+		ViewCellContainer viewCells;
+
+		CastLineSegment(vssRay->mTermination, vssRay->mOrigin, viewCells);
+
+		ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
+		
+		for (vit = viewCells.begin(); vit != vit_end; ++ vit)
+		{
+			BspViewCell *vc = dynamic_cast<BspViewCell *>(*vit);
+			ray->intersections.push_back(BspIntersection(0, vc->mLeaves[0]));
+		}
+
+		mBspRays.push_back(ray);
+	}
+}
+
 
 /**********************************************************************/
@@ -900,7 +959,9 @@
 	// compute view cell area as subsititute for probability
 	AxisAlignedBox3 box = mKdTree->GetBox(mKdTree->GetRoot());
-
+#if 0
 	return GetArea(viewCell) / box.SurfaceArea();
-	//return GetArea(viewCell) / GetTotalArea();
+#else
+	return GetArea(viewCell) / GetAccVcArea();
+#endif
 }
 
@@ -909,4 +970,9 @@
 {
 	return viewCell->GetPvs().GetSize() * objRendercost;
+}
+
+AxisAlignedBox3 KdViewCellsManager::GetSceneBbox() const
+{
+	return mKdTree->GetBox();
 }
 
@@ -1160,5 +1226,5 @@
 
 	return GetArea(viewCell) / box.SurfaceArea();
-	//return GetArea(viewCell) / GetTotalArea();
+	//return GetArea(viewCell) / GetAccVcArea();
 }
 
@@ -1219,4 +1285,9 @@
 
 	return 0;
+}
+
+AxisAlignedBox3 VspKdViewCellsManager::GetSceneBbox() const
+{
+	return mVspKdTree->GetBBox(mVspKdTree->GetRoot());
 }
 
@@ -1354,4 +1425,6 @@
 }
 
+
+
 /**********************************************************************/
 /*                 VspBspViewCellsManager implementation              */
@@ -1365,4 +1438,5 @@
 }
 
+
 VspBspViewCellsManager::~VspBspViewCellsManager()
 {
@@ -1370,9 +1444,14 @@
 }
 
+
 float VspBspViewCellsManager::GetProbability(ViewCell *viewCell)
 {
-	return GetArea(viewCell) / mVspBspTree->GetBoundingBox().SurfaceArea();
-	//return GetArea(viewCell) / GetTotalArea();
-}
+#if 0
+	return GetArea(viewCell) / mVspBspTree->GetBbox().SurfaceArea();
+#else
+	return GetArea(viewCell) / GetAccVcArea();
+#endif
+}
+
 
 float VspBspViewCellsManager::GetArea(ViewCell *viewCell) const
@@ -1389,7 +1468,15 @@
 }
 
-float VspBspViewCellsManager::GetRendercost(ViewCell *viewCell, float objRendercost) const
+
+float VspBspViewCellsManager::GetRendercost(ViewCell *viewCell, 
+											float objRendercost) const
 {
 	return viewCell->GetPvs().GetSize() * objRendercost;
+}
+
+
+AxisAlignedBox3 VspBspViewCellsManager::GetSceneBbox() const
+{
+	return mVspBspTree->GetBoundingBox();
 }
 
