Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 408)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 409)
@@ -34,17 +34,18 @@
 VspKdTreeLeaf::mailID = 0;
 
-inline void
-AddObject2Pvs(Intersectable *object,
-							const int side,
-							int &pvsBack,
-							int &pvsFront)
-{
-
+inline void AddObject2Pvs(Intersectable *object,
+						  const int side,
+						  int &pvsBack,
+						  int &pvsFront)
+{
 	if (!object)
 		return;
 		
-	if (side <= 0) {
-		if (!object->Mailed() && !object->Mailed(2)) {
-			pvsBack++;
+	if (side <= 0) 
+	{
+		if (!object->Mailed() && !object->Mailed(2)) 
+		{
+			++ pvsBack;
+
 			if (object->Mailed(1))
 				object->Mail(2);
@@ -54,7 +55,9 @@
 	}
 	
-	if (side >= 0) {
-		if (!object->Mailed(1) && !object->Mailed(2)) {
-			pvsFront++;
+	if (side >= 0) 
+	{
+		if (!object->Mailed(1) && !object->Mailed(2)) 
+		{
+			++ pvsFront;
 			if (object->Mailed())
 				object->Mail(2);
@@ -69,58 +72,54 @@
 VspKdTree::VspKdTree()
 {
-  environment->GetIntValue("VspKdTree.maxDepth", termMaxDepth);
+	environment->GetIntValue("VspKdTree.maxDepth", termMaxDepth);
 	environment->GetIntValue("VspKdTree.minPvs", termMinPvs);
 	environment->GetIntValue("VspKdTree.minRays", termMinRays);
 	environment->GetFloatValue("VspKdTree.maxRayContribution", termMaxRayContribution);
-  environment->GetFloatValue("VspKdTree.maxCostRatio", termMaxCostRatio);
-
-  environment->GetFloatValue("VspKdTree.minSize", termMinSize);
-  termMinSize = sqr(termMinSize);
-	
-  environment->GetFloatValue("VspKdTree.refDirBoxMaxSize", refDirBoxMaxSize);
-  refDirBoxMaxSize = sqr(refDirBoxMaxSize);
-  
-  environment->GetFloatValue("VspKdTree.epsilon", epsilon);
-  environment->GetFloatValue("VspKdTree.ct_div_ci", ct_div_ci);
-	
-  environment->GetFloatValue("VspKdTree.maxTotalMemory", maxTotalMemory);
-  environment->GetFloatValue("VspKdTree.maxStaticMemory", maxStaticMemory);
-  
-  
-
-
-  float refDirAngle;
-  environment->GetFloatValue("VspKdTree.refDirAngle", refDirAngle);
-
-  environment->GetIntValue("VspKdTree.accessTimeThreshold", accessTimeThreshold);
-  //= 1000;
-  environment->GetIntValue("VspKdTree.minCollapseDepth", minCollapseDepth);
-  //  int minCollapseDepth = 4;
-
-  //  pRefDirThresh = cos(0.5*M_PI - M_PI*refDirAngle/180.0);
-	//  cosRefDir = cos(M_PI*refDirAngle/180.0);
-	//  sinRefDir = sin(M_PI*refDirAngle/180.0);
-  
-  
-  // split type
+	environment->GetFloatValue("VspKdTree.maxCostRatio", termMaxCostRatio);
+
+	environment->GetFloatValue("VspKdTree.minSize", termMinSize);
+	termMinSize = sqr(termMinSize);
+	
+	environment->GetFloatValue("VspKdTree.refDirBoxMaxSize", refDirBoxMaxSize);
+	refDirBoxMaxSize = sqr(refDirBoxMaxSize);
+  
+	environment->GetFloatValue("VspKdTree.epsilon", epsilon);
+	environment->GetFloatValue("VspKdTree.ct_div_ci", ct_div_ci);
+	
+	environment->GetFloatValue("VspKdTree.maxTotalMemory", maxTotalMemory);
+	environment->GetFloatValue("VspKdTree.maxStaticMemory", maxStaticMemory);
+  
+  
+	float refDirAngle;
+	environment->GetFloatValue("VspKdTree.refDirAngle", refDirAngle);
+
+	environment->GetIntValue("VspKdTree.accessTimeThreshold", accessTimeThreshold);
+	//= 1000;
+	environment->GetIntValue("VspKdTree.minCollapseDepth", minCollapseDepth);
+ 
+
+	// split type
 	char sname[128];
 	environment->GetStringValue("VspKdTree.splitType", sname);
-  string name(sname);
-	
-  if (name.compare("regular") == 0)
-    splitType = ESplitRegular;
-  else
-    if (name.compare("heuristic") == 0)
-      splitType = ESplitHeuristic;
-		else {
-			cerr<<"Invalid VspKdTree split type "<<name<<endl;
+	string name(sname);
+	
+	if (name.compare("regular") == 0)
+		splitType = ESplitRegular;
+	else
+	{
+		if (name.compare("heuristic") == 0)
+			splitType = ESplitHeuristic;
+		else 
+		{
+			cerr << "Invalid VspKdTree split type " << name << endl;
 			exit(1);
 		}
-	
-  environment->GetBoolValue("VspKdTree.randomize", randomize);
-
-  root = NULL;
-  
-  splitCandidates = new vector<SortableEntry>;
+	}
+
+	environment->GetBoolValue("VspKdTree.randomize", randomize);
+
+	root = NULL;
+
+	splitCandidates = new vector<SortableEntry>;
 }
 
@@ -128,6 +127,6 @@
 VspKdTree::~VspKdTree()
 {
-  if (root)
-    delete root;
+	if (root)
+		delete root;
 }
 
@@ -204,25 +203,32 @@
 VspKdTreeLeaf::UpdatePvsSize()
 {
-	if (!mValidPvs) {
+	if (!mValidPvs) 
+	{
 		Intersectable::NewMail();
 		int pvsSize = 0;
-		for(VspKdTreeNode::RayInfoContainer::iterator ri = rays.begin();
-				ri != rays.end();
-				ri++)
-			if ((*ri).mRay->IsActive()) {
+		for(VspKdTreeNode::RayInfoContainer::iterator ri = rays.begin(); 
+			ri != rays.end(); ++ ri)
+		{
+			if ((*ri).mRay->IsActive()) 
+			{
 				Intersectable *object;
 #if BIDIRECTIONAL_RAY
 				object = (*ri).mRay->mOriginObject;
-				if (object && !object->Mailed()) {
-					pvsSize++;
+			
+				if (object && !object->Mailed()) 
+				{
+					++ pvsSize;
 					object->Mail();
 				}
 #endif
 				object = (*ri).mRay->mTerminationObject;
-				if (object && !object->Mailed()) {
-					pvsSize++;
+				if (object && !object->Mailed()) 
+				{
+					++ pvsSize;
 					object->Mail();
 				}
 			}
+		}
+
 		mPvsSize = pvsSize;
 		mValidPvs = true;
@@ -232,44 +238,37 @@
 
 void
-VspKdTree::Construct(
-									 VssRayContainer &rays,
-									 AxisAlignedBox3 *forcedBoundingBox
-									 )
-{
-  stat.Start();
+VspKdTree::Construct(VssRayContainer &rays,
+					 AxisAlignedBox3 *forcedBoundingBox)
+{
+	stat.Start();
   
 	maxMemory = maxStaticMemory;
 
-  if (root)
-    delete root;
-
-  root = new VspKdTreeLeaf(NULL, rays.size());
-  // first construct a leaf that will get subdivide
-  VspKdTreeLeaf *leaf = (VspKdTreeLeaf *) root;
-
-  stat.nodes = 1;
-  
-  bbox.Initialize();
-  dirBBox.Initialize();
-  
-  for(VssRayContainer::const_iterator ri = rays.begin();
-      ri != rays.end();
-      ri++) {
-    leaf->AddRay(VspKdTreeNode::RayInfo(*ri));
-
-    bbox.Include((*ri)->GetOrigin());
-    bbox.Include((*ri)->GetTermination());
-    
-		
-		dirBBox.Include(Vector3(
-														(*ri)->GetDirParametrization(0),
-														(*ri)->GetDirParametrization(1),
-														0
-														)
-										);
-	}
-	
-	
-	if ( forcedBoundingBox )
+	if (root)
+		delete root;
+
+	root = new VspKdTreeLeaf(NULL, rays.size());
+
+	// first construct a leaf that will get subdivide
+	VspKdTreeLeaf *leaf = (VspKdTreeLeaf *) root;
+
+	
+	stat.nodes = 1;
+  	
+	bbox.Initialize();
+	dirBBox.Initialize();
+  
+	
+	for (VssRayContainer::const_iterator ri = rays.begin(); ri != rays.end(); ++ ri)
+	{
+		leaf->AddRay(VspKdTreeNode::RayInfo(*ri));
+
+		bbox.Include((*ri)->GetOrigin());
+		bbox.Include((*ri)->GetTermination());    
+		
+		dirBBox.Include(Vector3((*ri)->GetDirParametrization(0), (*ri)->GetDirParametrization(1), 0));
+	}
+	
+	if (forcedBoundingBox)
 		bbox = *forcedBoundingBox;
 
@@ -277,82 +276,85 @@
 	cout<<"Dirr Bbox = "<<dirBBox<<endl;
 
-  stat.rays = leaf->rays.size();
+	stat.rays = leaf->rays.size();
 	leaf->UpdatePvsSize();
-  stat.initialPvsSize = leaf->GetPvsSize();
-  // Subdivide();
-  root = Subdivide(TraversalData(leaf, bbox, 0));
-
-  if (splitCandidates) {
-    // force realease of this vector
-    delete splitCandidates;
-    splitCandidates = new vector<SortableEntry>;
-  }
-  
-  stat.Stop();
+	
+	stat.initialPvsSize = leaf->GetPvsSize();
+	
+	// Subdivide();
+	root = Subdivide(TraversalData(leaf, bbox, 0));
+
+	if (splitCandidates) 
+	{
+		// force realease of this vector
+		delete splitCandidates;
+		splitCandidates = new vector<SortableEntry>;
+	}
+  
+	stat.Stop();
 
 	stat.Print(cout);
-	cout<<"#Total memory="<<GetMemUsage()<<endl;
-
-}
-
-
-
-VspKdTreeNode *
-VspKdTree::Subdivide(const TraversalData &tdata)
-{
-  VspKdTreeNode *result = NULL;
-
-  priority_queue<TraversalData> tStack;
-  //  stack<TraversalData> tStack;
-  
-  tStack.push(tdata);
-
-  AxisAlignedBox3 backBox;
-  AxisAlignedBox3 frontBox;
-
+	cout<<"#Total memory=" << GetMemUsage() << endl;
+}
+
+
+
+VspKdTreeNode *VspKdTree::Subdivide(const TraversalData &tdata)
+{
+	VspKdTreeNode *result = NULL;
+
+	priority_queue<TraversalData> tStack;
+	//  stack<TraversalData> tStack;
+  
+	tStack.push(tdata);
+
+	AxisAlignedBox3 backBox;
+	AxisAlignedBox3 frontBox;
   
 	int lastMem = 0;
-  while (!tStack.empty()) {
-
+	while (!tStack.empty()) 
+	{
 		float mem = GetMemUsage();
 		
-		if ( lastMem/10 != ((int)mem)/10) {
-			cout<<mem<<" MB"<<endl;
+		if ( lastMem/10 != ((int)mem)/10) 
+		{
+			cout << mem << " MB" << endl;
 		}
 		lastMem = (int)mem;
 		
-		if (  mem > maxMemory ) {
-      // count statistics on unprocessed leafs
-      while (!tStack.empty()) {
+		if (  mem > maxMemory ) 
+		{
+			// count statistics on unprocessed leafs
+			while (!tStack.empty()) 
+			{
 				EvaluateLeafStats(tStack.top());
 				tStack.pop();
-      }
-      break;
-    }
+			}
+			break;
+		}
     
-    TraversalData data = tStack.top();
-    tStack.pop();
+		TraversalData data = tStack.top();
+		tStack.pop();
     
-    VspKdTreeNode *node = SubdivideNode((VspKdTreeLeaf *) data.node,
-																			data.bbox,
-																			backBox,
-																			frontBox
-																			);
-    if (result == NULL)
-      result = node;
+		
+		VspKdTreeNode *node = SubdivideNode((VspKdTreeLeaf *) data.node,
+											data.bbox, backBox,	frontBox);
+		if (result == NULL)
+			result = node;
     
-    if (!node->IsLeaf()) {
-			
-      VspKdTreeInterior *interior = (VspKdTreeInterior *) node;
-      // push the children on the stack
-      tStack.push(TraversalData(interior->back, backBox, data.depth+1));
-      tStack.push(TraversalData(interior->front, frontBox, data.depth+1));
-			
-    } else {
-      EvaluateLeafStats(data);
-    }
-  }
-
-  return result;
+		if (!node->IsLeaf()) 
+		{
+			VspKdTreeInterior *interior = (VspKdTreeInterior *) node;
+
+			// push the children on the stack
+			tStack.push(TraversalData(interior->back, backBox, data.depth+1));
+			tStack.push(TraversalData(interior->front, frontBox, data.depth+1));
+		} 
+		else 
+		{
+			EvaluateLeafStats(data);
+		}
+	}
+
+	return result;
 }
 
@@ -360,13 +362,11 @@
 // returns selected plane for subdivision
 int
-VspKdTree::SelectPlane(
-										 VspKdTreeLeaf *leaf,
-										 const AxisAlignedBox3 &box,
-										 float &position,
-										 int &raysBack,
-										 int &raysFront,
-										 int &pvsBack,
-										 int &pvsFront
-										 )
+VspKdTree::SelectPlane(VspKdTreeLeaf *leaf,
+					   const AxisAlignedBox3 &box,
+					   float &position,
+					   int &raysBack,
+					   int &raysFront,
+					   int &pvsBack,
+					   int &pvsFront)
 {
 
@@ -776,9 +776,8 @@
 {
   
-  if ( (leaf->GetPvsSize() < termMinPvs) ||
-			 (leaf->rays.size() < termMinRays) ||
-			 //			 (leaf->GetAvgRayContribution() > termMaxRayContribution ) ||
-       (leaf->depth >= termMaxDepth) ||
-			 SqrMagnitude(box.Size()) <= termMinSize ) {
+  if ( (leaf->GetPvsSize() < termMinPvs) || (leaf->rays.size() < termMinRays) ||
+	// (leaf->GetAvgRayContribution() > termMaxRayContribution ) ||
+       (leaf->depth >= termMaxDepth) || SqrMagnitude(box.Size()) <= termMinSize ) 
+  {
 
 #if 0
Index: trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.h	(revision 407)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.h	(revision 409)
@@ -16,18 +16,19 @@
 public:
 	RenderSimulator();
-	RenderSimulator(float objRendercost, float vcOverhead);
+	RenderSimulator(float objRendercost, float vcOverhead, float moveSpeed);
 	virtual Real SimulateRendering() = 0;
 
-protected:
-	// render time for single object of the PVS
+	/// render time for single object of the PVS
 	float mObjRenderCost;
-	// const overhead for crossing a view cell border
+	/// const overhead for crossing a view cell border
 	float mVcOverhead;
+	/// move speed of player
+	float mMoveSpeed;
 };
 
-class BspTreeRenderSimulator: public RenderSimulator
+class BspViewCellRenderSimulator: public RenderSimulator
 {
 public:
-	BspTreeRenderSimulator(float objRenderCost, float vcOverhead, BspTree *bspTree);
+	BspViewCellRenderSimulator(float objRenderCost, float vcOverhead, float moveSpeed, BspTree *bspTree);
 
 	Real SimulateRendering();
@@ -43,8 +44,8 @@
 };
 
-class KdTreeRenderSimulator: public RenderSimulator
+class KdViewCellRenderSimulator: public RenderSimulator
 {
 public:
-	KdTreeRenderSimulator(float objRenderCost, float vcOverhead, KdTree *kdTree);
+	KdViewCellRenderSimulator(float objRenderCost, float vcOverhead, float moveSpeed, KdTree *kdTree);
 	Real SimulateRendering();
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 407)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 409)
@@ -734,4 +734,6 @@
 	bool TerminationCriteriaMet(const BspTraversalData &data) const;
 
+	float AccumulatedRayLength(BoundedRayContainer &rays) const;
+
 	/// Pointer to the root of the tree
 	BspNode *mRoot;
@@ -794,4 +796,7 @@
 	static int sTermMaxObjectsForAxisAligned;
 
+	static float sTermMaxRayContribution;
+	static float sTermMaxAccRayLength;
+
 	static bool sStoreLeavesWithRays;
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 408)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 409)
@@ -1210,4 +1210,9 @@
 		 "0.05");
 
+  RegisterOption("Simulation.moveSpeed",
+		 optFloat,
+		 "-simulation_moveSpeed",
+		 "1.0");
+
   RegisterOption("BspTree.Construction.input",
 	  optString,
@@ -1244,4 +1249,14 @@
 		 "-bsp_term_min_area=",
 		 "0.001");
+  
+  RegisterOption("BspTree.Termination.maxRayContribution",
+		 optFloat,
+		 "-bsp_term_ray_contribution=",
+		 "0.005");
+
+  RegisterOption("BspTree.Termination.maxAccRayLenght",
+		 optFloat,
+		 "-bsp_term_max_acc_ray_length=",
+		 "50");
 
    RegisterOption("BspTree.Termination.maxRays",
@@ -1304,5 +1319,4 @@
 	  "-view_cells_max_viewcells=",
 	  "0");
-
   
   RegisterOption("BspTree.Visualization.samples",
@@ -1347,13 +1361,4 @@
   RegisterOption("VspKdTree.accessTimeThreshold", optInt, "accesstime=", "1000");
   RegisterOption("VspKdTree.minCollapseDepth", optInt, "colldepth=", "4");
-
-
-
-
-
-
-
-
-
 
   	RegisterOption("VssTree.maxDepth", optInt, "kd_depth=", "12");
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 407)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp	(revision 409)
@@ -14,16 +14,22 @@
 #include "Plane3.h"
 
+int BspTree::sMaxPolyCandidates = 10;
+int BspTree::sMaxRayCandidates = 10;
+int BspTree::sSplitPlaneStrategy = BALANCED_POLYS; 
+int BspTree::sConstructionMethod = FROM_INPUT_VIEW_CELLS;
+
+
 int BspTree::sTermMaxPolygons = 10;
 int BspTree::sTermMinPvs = 20;
 int BspTree::sTermMaxDepth = 20;
 float BspTree::sTermMinArea = 0.001f;
-int BspTree::sMaxPolyCandidates = 10;
-int BspTree::sMaxRayCandidates = 10;
-int BspTree::sSplitPlaneStrategy = BALANCED_POLYS; 
-int BspTree::sConstructionMethod = FROM_INPUT_VIEW_CELLS;
 int BspTree::sTermMaxPolysForAxisAligned = 50;
 int BspTree::sTermMaxObjectsForAxisAligned = 50;
 int BspTree::sTermMaxRaysForAxisAligned = -1;
 int BspTree::sTermMaxRays = -1;
+float BspTree::sTermMaxRayContribution = 0.05f;
+float BspTree::sTermMaxAccRayLength = 50;
+
+
 int BspTree::sMinPvsDif = 10;
 int BspTree::sMinPvs = 10;
@@ -704,5 +710,6 @@
 		 (data.mPvs <= sTermMinPvs) ||
 		 (data.mArea <= sTermMinArea) ||
-		 (data.mDepth >= sTermMaxDepth));
+		 (data.mDepth >= sTermMaxDepth) ||
+		 (((float)data.mPvs / (float)data.mRays->size()) < sTermMaxRayContribution));
 }
 
@@ -863,16 +870,24 @@
 											coincident);
 
-	// split geometry
-	tData.mGeometry->SplitGeometry(*frontData.mGeometry, *backData.mGeometry, 
-								   *this, interior->mPlane);
-	
-	// compute area
-	frontData.mArea = frontData.mGeometry->GetArea();
-	backData.mArea = backData.mGeometry->GetArea();
-
-	// compute pvs
+    // compute pvs
 	frontData.mPvs = ComputePvsSize(*frontData.mRays);
 	backData.mPvs = ComputePvsSize(*backData.mRays);
 
+	// split geometry and compute area
+	if (1)
+	{
+		tData.mGeometry->SplitGeometry(*frontData.mGeometry, 
+									   *backData.mGeometry, 
+									   *this, 
+									   interior->mPlane);
+	
+		
+		frontData.mArea = frontData.mGeometry->GetArea();
+		backData.mArea = backData.mGeometry->GetArea();
+	}
+
+	// compute accumulated ray length
+	//frontData.mAccRayLength = AccumulatedRayLength(*frontData.mRays);
+	//backData.mAccRayLength = AccumulatedRayLength(*backData.mRays);
 
 	//-- create front and back leaf
@@ -1502,6 +1517,6 @@
 			   (pOverall * (float)pvs * 2);
 
-		// give penalty for unbalanced cell
-		if (((pFront * 0.2 + 0.00001) > pBack) || (pFront < (pBack * 0.2 + 0.00001)))
+		// give penalty to unbalanced split
+		if (((pFront * 0.2 + Limits::Small) > pBack) || (pFront < (pBack * 0.2 + Limits::Small)))
 			val += 0.5;
 	}
@@ -1633,5 +1648,7 @@
 	environment->GetIntValue("BspTree.Termination.maxPolygons", sTermMaxPolygons);
 	environment->GetIntValue("BspTree.Termination.maxRays", sTermMaxRays);
-	environment->GetFloatValue("BspTree.Termination.minArea", sTermMinArea);
+	environment->GetFloatValue("BspTree.Termination.minArea", sTermMinArea);	
+	environment->GetFloatValue("BspTree.Termination.maxRayContribution", sTermMaxRayContribution);
+	environment->GetFloatValue("BspTree.Termination.maxAccRayLenght", sTermMaxAccRayLength);
 
 	//-- termination criteria for axis aligned split
@@ -1743,9 +1760,5 @@
 		mStat.minDepth = data.mDepth;
 
-	// store minimal and maximal pvs
-	/*if (data.mPvs > mStat.pvs)mStat.pvs = data.mPvs;
-	if (data.mPvs < mStat.pvs)	mStat.pvs = data.mPvs;*/
-
-	// accumulate depth to compute average
+	// accumulate depth to compute average depth
 	mStat.accumDepth += data.mDepth;
 	
@@ -1757,5 +1770,6 @@
 		  << "#polygons: " << (int)data.mPolygons->size() << " (max: " << sTermMaxPolygons << "), "
 		  << "#rays: " << (int)data.mRays->size() << " (max: " << sTermMaxRays << "), " 
-		  << "#pvs: " << leaf->GetViewCell()->GetPvs().GetSize() << endl;
+		  << "#pvs: " << leaf->GetViewCell()->GetPvs().GetSize() << "=, "
+		  << "#avg ray contrib (pvs): " << (float)data.mPvs / (float)data.mRays->size() << endl;
 //#endif
 }
@@ -2028,4 +2042,19 @@
 {
 	return mStat;
+}
+
+float BspTree::AccumulatedRayLength(BoundedRayContainer &rays) const
+{
+	float len = 0;
+
+	BoundedRayContainer::const_iterator it, it_end = rays.end();
+
+	for (it = rays.begin(); it != it_end; ++ it)
+	{
+		len += SqrDistance((*it)->mRay->Extrap((*it)->mMinT), 
+						   (*it)->mRay->Extrap((*it)->mMaxT));
+	}
+
+	return len;
 }
 
@@ -2077,6 +2106,4 @@
 
 				DEL_PTR(bRay);
-
-				++ splits;
 			}
 			break;
@@ -2089,5 +2116,4 @@
 				backRays.push_back(new BoundedRay(ray, bRay->mMinT, newT));
 				frontRays.push_back(new BoundedRay(ray, newT, bRay->mMaxT));
-				
 				DEL_PTR(bRay);
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp	(revision 407)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp	(revision 409)
@@ -7,6 +7,6 @@
 {}
 
-RenderSimulator::RenderSimulator(float objRenderCost, float vcOverhead):
-mObjRenderCost(objRenderCost), mVcOverhead(vcOverhead)
+RenderSimulator::RenderSimulator(float objRenderCost, float vcOverhead, float moveSpeed):
+mObjRenderCost(objRenderCost), mVcOverhead(vcOverhead), mMoveSpeed(moveSpeed)
 {
 }
@@ -16,20 +16,27 @@
  *****************************************************/
 
-BspTreeRenderSimulator::BspTreeRenderSimulator(float objRenderCost, 
+BspViewCellRenderSimulator::BspViewCellRenderSimulator(float objRenderCost, 
 											   float vcOverhead, 
+											   float moveSpeed,
 											   BspTree *bspTree):
-RenderSimulator(objRenderCost, vcOverhead), mBspTree(bspTree)
+RenderSimulator(objRenderCost, vcOverhead, moveSpeed), mBspTree(bspTree)
 {
 }
 
-Real BspTreeRenderSimulator::SimulateRendering()
+Real BspViewCellRenderSimulator::SimulateRendering()
 {
 	Real renderTime = 0;
 
-	// total area of view cells
-	float totalArea = 0;//= mKdTree->GetBox().SurfaceArea();
+	// overhead for loading the PVS of the view cells
+	float loadPvsOverhead = 0;
 
+	// probability that view point lies in a view cell
+	float pInVcTotal = 0;
+
+	// total probability that a view cell border is crossed
+	float pCrossVcTotal = 0;
+
+	// collect all view cells
 	ViewCellContainer viewCells;
-
 	mBspTree->CollectViewCells(viewCells);
 
@@ -37,25 +44,37 @@
 
 	// surface area substitute for probability
-	PolygonContainer cell;
+	PolygonContainer geom;
 
 	for (it = viewCells.begin(); it != it_end; ++ it)
 	{
-		mBspTree->ConstructGeometry(dynamic_cast<BspViewCell *>(*it), cell);
-		CLEAR_CONTAINER(cell);
-		float area = Polygon3::GetArea(cell);
+		mBspTree->ConstructGeometry(dynamic_cast<BspViewCell *>(*it), geom);
+		CLEAR_CONTAINER(geom);
+
+		const float area = Polygon3::GetArea(geom);
+		// area substitute for view point probability
+		float pInVc = area;
+				
+		// compute render time of PVS times probability that view point is in view cell
+		renderTime += pInVc * RenderPvs(*(*it), mObjRenderCost);
 		
-		renderTime += area * (RenderPvs(*(*it), mObjRenderCost) + mVcOverhead);
-		totalArea += area;
+		// probability that a view cell border is crossed
+		float pCrossVc = area;
+
+		loadPvsOverhead += pCrossVc * mVcOverhead * mMoveSpeed;
+
+		pInVcTotal += pInVc;
+		pCrossVcTotal += pCrossVc;
 	}
 
-	renderTime /= totalArea;
+	
+	renderTime /= pInVcTotal;
+	loadPvsOverhead /= pCrossVcTotal;
 
 	//Debug << "render time without overhead: " << renderTime * 1e-3 << endl;
-	//renderTime += (float)viewCells.size() * vcOverhead;
-
-	return renderTime;
+	
+	return renderTime + loadPvsOverhead;
 }
 
-Real BspTreeRenderSimulator::RenderPvs(ViewCell &viewCell, 
+Real BspViewCellRenderSimulator::RenderPvs(ViewCell &viewCell, 
 									   float objRenderTime) const
 {
@@ -67,12 +86,13 @@
  *******************************************************/
 
-KdTreeRenderSimulator::KdTreeRenderSimulator(float objRenderCost, 
-											 float vcOverhead, 
+KdViewCellRenderSimulator::KdViewCellRenderSimulator(float objRenderCost, 
+											 float vcOverhead,
+											 float moveSpeed,
 											 KdTree *kdTree):
-RenderSimulator(objRenderCost, vcOverhead), mKdTree(kdTree)
+RenderSimulator(objRenderCost, vcOverhead, moveSpeed), mKdTree(kdTree)
 {
 }
 
-Real KdTreeRenderSimulator::SimulateRendering()
+Real KdViewCellRenderSimulator::SimulateRendering()
 {
 	//mKdTree->CollectLeavesPvs();
@@ -81,5 +101,5 @@
 	Real renderTime = 0;
 	// overhead for loading a view cell
-	float loadOverhead = 0;
+	float loadPvsOverhead = 0;
 
 	// probability that view point lies in a view cell
@@ -112,5 +132,5 @@
 
 		renderTime += pInVc * RenderPvs(*it, mObjRenderCost);
-		loadOverhead += pCrossVc * mVcOverhead;
+		loadPvsOverhead += pCrossVc * mVcOverhead * mMoveSpeed;
 
 		pInVcTotal += pInVc;
@@ -119,10 +139,10 @@
 
 	renderTime /= pInVcTotal;
-	loadOverhead /= pCrossVcTotal;
+	loadPvsOverhead /= pCrossVcTotal;
 
-	return renderTime + loadOverhead;
+	return renderTime + loadPvsOverhead;
 }
 
-Real KdTreeRenderSimulator::RenderPvs(KdLeaf *leaf, 
+Real KdViewCellRenderSimulator::RenderPvs(KdLeaf *leaf, 
 										   float objRenderTime) const
 {
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 387)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 409)
@@ -6,8 +6,10 @@
 #include "ViewCell.h"
 #include "Environment.h"
+#include "RenderSimulator.h"
 
 Preprocessor::Preprocessor():
 mKdTree(NULL),
-mBspTree(NULL)
+mBspTree(NULL),
+mRenderSimulator(NULL)
 {
 }
@@ -20,4 +22,6 @@
 	DEL_PTR(mBspTree);
 	DEL_PTR(mKdTree);
+
+	DEL_PTR(mRenderSimulator);
 }
 
@@ -52,7 +56,11 @@
 
 	if (strcmp(viewCellsStr, "bspTree") == 0)
+	{
 		ViewCell::sHierarchy = ViewCell::BSP;
+	}
 	else if (strcmp(viewCellsStr, "kdTree") == 0)
+	{
 		ViewCell::sHierarchy = ViewCell::KD;
+	}
 	else if (strcmp(viewCellsStr, "sceneDependent") == 0)
 	{
@@ -68,9 +76,30 @@
 }
 
+RenderSimulator *Preprocessor::GetRenderSimulator()
+{
+	if (mRenderSimulator)
+		return mRenderSimulator;
+
+    float objRenderCost = 0, vcOverhead = 0, moveSpeed = 0;
+
+	environment->GetFloatValue("Simulation.objRenderCost",objRenderCost);
+	environment->GetFloatValue("Simulation.vcOverhead", vcOverhead);
+	environment->GetFloatValue("Simulation.moveSpeed", moveSpeed);
+
+	if (ViewCell::sHierarchy = ViewCell::BSP)
+		mRenderSimulator = new BspViewCellRenderSimulator(objRenderCost, vcOverhead, moveSpeed, mBspTree);
+	else // KD view cells
+		mRenderSimulator = new KdViewCellRenderSimulator(objRenderCost, vcOverhead, moveSpeed, mKdTree);
+
+	return mRenderSimulator;
+}
+
 void Preprocessor::DeleteViewCells()
 {
-	for (int i = 0; i < mViewCells.size(); ++ i)
-		delete mViewCells[i]->GetMesh();
-
+	for (int i = 0; i < (int)mViewCells.size(); ++ i)
+	{
+		Mesh *mesh = mViewCells[i]->GetMesh();
+		DEL_PTR(mesh);
+	}
 	CLEAR_CONTAINER(mViewCells);
 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 387)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 409)
@@ -25,9 +25,8 @@
   BspTree::ParseEnvironment();
 
-	char buff[128];
-
-	environment->GetStringValue("Preprocessor.type", buff);
-
-	string preprocessorType(buff);
+  char buff[128];
+  
+  environment->GetStringValue("Preprocessor.type", buff);
+  string preprocessorType(buff);
 	
   Preprocessor *p;
@@ -83,28 +82,4 @@
 	  p->Export("vc_bsptree.x3d", false, false, true);
 	  p->BspTreeStatistics(Debug);
-
-#if 0
-	  //-- export the complementary view cells
-	  // i.e., the view cells not associated with leafs in the tree.
-	  Exporter *exporter = Exporter::GetExporter("viewcells_compl.x3d");
-
-	  ViewCellContainer::iterator vc_compl_it;
-	  ViewCellContainer vc_compl(p->mViewCells.size() + X3dExporter::foundViewCells.size());
-  
-	  sort(p->mViewCells.begin(), p->mViewCells.end());
-
-	  vc_compl_it = set_difference(p->mViewCells.begin(), p->mViewCells.end(), 
-		  X3dExporter::foundViewCells.begin(), X3dExporter::foundViewCells.end(), vc_compl.begin());
-
-	  vc_compl.erase(vc_compl_it, vc_compl.end());
-  
-
-	  if (exporter) 
-	  {	
-		  Debug << "Exporting complementary view cells" << endl;
-		  exporter->ExportViewCells(vc_compl); // export view cells
-		  delete exporter;
-	  }
-#endif
   }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 406)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.h	(revision 409)
@@ -98,9 +98,4 @@
 	*/
 	int PostprocessViewCells(const RayContainer &rays);
-
-	// rendering costs for a single object
-	float mObjRenderCost;
-	// rendering overhead when crossing a view cell border
-	float mVcOverhead;
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 392)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 409)
@@ -9,6 +9,6 @@
 #include "ViewCellBsp.h"
 #include "ViewCell.h"
-//#include "SceneGraph.h"
 
+class RenderSimulator;
 class SceneGraph;
 
@@ -93,4 +93,6 @@
   void DeleteViewCells();
 
+  RenderSimulator *GetRenderSimulator();
+
   /** Parses the view cell options
   */
@@ -115,4 +117,6 @@
   /// the view cell corresponding to unbounded space
   BspViewCell mUnbounded;
+
+  RenderSimulator *mRenderSimulator;
 };
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 407)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 409)
@@ -17,10 +17,7 @@
   environment->GetIntValue("ViewCells.PostProcessing.samples", mPostProcessSamples);
   environment->GetIntValue("BspTree.Visualization.samples", mVisualizationSamples);
-  environment->GetFloatValue("Simulation.objRenderCost", mObjRenderCost);
-  environment->GetFloatValue("Simulation.vcOverhead", mVcOverhead);
-
+ 
   mKdPvsDepth = 100;
   mStats.open("stats.log");
-
 }
 
@@ -543,5 +540,5 @@
 		//-- render simulation
 		cout << "\nevaluating bsp view cells render time before merge ... ";
-		Real rt = BspTreeRenderSimulator(mObjRenderCost, mVcOverhead, mBspTree).SimulateRendering();
+		Real rt = GetRenderSimulator()->SimulateRendering();
 		
 		cout << "avg render time: " << rt * 1e-3 << endl;
@@ -589,5 +586,5 @@
 		cout << "\nevaluating render time after merge ... ";
 			
-		rt = BspTreeRenderSimulator(mObjRenderCost, mVcOverhead, mBspTree).SimulateRendering();
+		rt = GetRenderSimulator()->SimulateRendering();
 
 		cout << "render time: " << rt * 1e-3 << endl;
@@ -655,5 +652,5 @@
 	{
 		cout << "\nevaluating kd view cells render time ... ";
-		Real rt = KdTreeRenderSimulator(mObjRenderCost, mVcOverhead, mKdTree).SimulateRendering();
+		Real rt = GetRenderSimulator()->SimulateRendering();
 		
 		cout << "avg render time: " << rt * 1e-3 << endl;
