Index: GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 2342)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 2347)
@@ -226,5 +226,5 @@
 				Name="VCLinkerTool"
 				AdditionalDependencies="xerces-c_2.lib glew32.lib zdll.lib zziplib.lib devil.lib glut32.lib OpenGL32.Lib glu32.lib Preprocessor.lib RTScene.lib RTWorld.lib"
-				OutputFile="../bin/release/Preprocessor.exe"
+				OutputFile="../bin/release/Preprocessor2.exe"
 				LinkIncremental="1"
 				AdditionalLibraryDirectories="..\src\GL;..\lib\release;..\..\Preprocessing\lib\release;..\..\..\..\..\..\NonGTP\Boost\lib;..\..\..\..\..\..\NonGTP\Xerces\xercesc\lib;..\..\..\..\..\..\NonGTP\Zlib\lib;..\..\..\..\..\..\NonGTP\Devil\lib;..\MultiLevelRayTracing\RTScene\Release;..\MultiLevelRayTracing\RTWorld\Release"
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 2283)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 2347)
@@ -1066,7 +1066,6 @@
 
 	// max cost threshold violated?
-	splitCandidate.mMaxCostMisses = costRatioViolated ? 
-		splitCandidate.mParentData.mMaxCostMisses : 
-		splitCandidate.mParentData.mMaxCostMisses + 1;
+	splitCandidate.mMaxCostMisses = costRatioViolated ? splitCandidate.mParentData.mMaxCostMisses : 
+	                                                    splitCandidate.mParentData.mMaxCostMisses + 1;
 
 	float oldRenderCost;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.h	(revision 2332)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.h	(revision 2347)
@@ -120,4 +120,6 @@
 }
 
+
+
 #if USE_FIXEDPOINT_T
 	float RayInfo::GetMinT () const 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 2342)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 2347)
@@ -49,8 +49,4 @@
 #define USE_AVGRAYCONTRI 0
 
-#define BOUND_RENDERCOST 0
-
-static const float MIN_RENDERCOST = 100.0f;
-
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 2342)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 2347)
@@ -500,4 +500,32 @@
     };
 
+	struct SplitData 
+	{
+		SplitData(): 
+        mFrontRenderCost(0), 
+		mBackRenderCost(0), 
+		mTotalRenderCost(0), 
+		mFrontObjects(0),
+        mBackObjects(0),
+		mTotalObjects(0),
+		mFrontTriangles(0),
+		mBackTriangles(0),
+		mTotalTriangles(0) {}
+
+
+		float mFrontRenderCost;
+		float mBackRenderCost;
+		float mTotalRenderCost;
+
+		int mFrontObjects;
+		int mBackObjects;
+		int mTotalObjects;
+
+		int mFrontTriangles;
+		int mBackTriangles;
+		int mTotalTriangles;
+	};
+
+
 	/** Candidate for a view space split.
 	*/
@@ -707,8 +735,4 @@
 	*/
 	void ValidateTree();
-
-	/** Invalid view cells are added to the unbounded space
-	*/
-	void CollapseViewCells();
 
 	/** Collects rays stored in the leaves.
@@ -797,7 +821,5 @@
 	float EvalRenderCostDecrease(VspSubdivisionCandidate &splitData, 
 								 float &normalizedOldRenderCost,
-								 const float totalRenderCost,
-								 const float frontRenderCost,
-								 const float backRenderCost) const;
+								 const SplitData &data) const;
 
 	/** Collects view cells in the subtree under root.
@@ -889,7 +911,5 @@
 
 	int EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate,
-						   const int oldPvsSize,
-						   const int fPvsSize,
-						   const int bPvsSize) const;
+						   const SplitData &sData) const;
 
 	/** Returns number of effective entries in the pvs.
@@ -1013,10 +1033,5 @@
 	inline void UpdateContributionsToPvs(BvhLeaf *leaf,
 										 const int cf,
-										 float &frontPvs, 
-										 float &backPvs, 
-										 float &totalPvs,
-										 int &frontSize, 
-										 int &backSize, 
-										 int &totalSize) const;
+										 SplitData &sdata) const;
 
 	/** Evaluates the contribution for kd leaves.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Trackball.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Trackball.cpp	(revision 2332)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Trackball.cpp	(revision 2347)
@@ -60,5 +60,5 @@
  * Programmer.
  */
-#define TRACKBALLSIZE  (0.8)
+#define TRACKBALLSIZE  (0.8f)
 
 /*
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 2342)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 2347)
@@ -53,4 +53,5 @@
 /*              class BvhNode implementation                   */
 /***************************************************************/
+
 
 BvhNode::BvhNode(): 
@@ -394,7 +395,9 @@
 	CollectViewCells(sc.mSampledBackObjects, backViewCells, false, false);
 
-	const float frontTri = (float)sc.mFrontObjects.size();
-	const float backTri = (float)sc.mBackObjects.size();
-	const float totalTri = (float)(*sc.mParentData.mSortedObjects[0]).size();
+	const int frontTri = (int)sc.mFrontObjects.size();
+	const int backTri = (int)sc.mBackObjects.size();
+	const int totalTri = (int)(*sc.mParentData.mSortedObjects[0]).size();
+
+	//cout << "totalTri: " << totalTri << " f: " << frontTri << " back: " << backTri << endl;
 
 	ViewCell::NewMail(3);
@@ -405,6 +408,5 @@
 	for (fit = frontViewCells.begin(); fit != fit_end; ++ fit)
 	{
-		ViewCell *vc = *fit;
-		vc->Mail(0);
+		(*fit)->Mail(0);
 	}
 
@@ -422,4 +424,5 @@
 	}
 
+	// traverse through view cells and compute changes
 	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
 	
@@ -428,8 +431,8 @@
 		ViewCell *vc = *vit;
 
-		float vcTri;
+		int vcTri;
 		int vcObj;
 
-		float oldVcTri = vc->GetTrianglesInPvs();
+		int oldVcTri = (int)vc->GetTrianglesInPvs();
 		int oldVcObj = vc->GetEntriesInPvs();
 
@@ -445,20 +448,81 @@
 		else if (vc->Mailed(1))
 		{
-			vcTri = oldVcTri - totalTri + backTri; 
+			vcTri = oldVcTri + backTri - totalTri; 
 			vcObj = oldVcObj;   
 		}
 		else // front object
 		{
-			vcTri = oldVcTri - totalTri + frontTri; 
+			vcTri = oldVcTri + frontTri - totalTri; 
 			vcObj = oldVcObj;
 		}
 
-		vc->SetTrianglesInPvs(vcTri);
+		vc->SetTrianglesInPvs((float)vcTri);
 		vc->SetEntriesInPvs(vcObj);
 
 		//cout << "old pvs tri: " << oldVcTri << " new: " << vcTri << endl;
-		//cout << "old pvs obj: " << oldVcObj << " new: " << vcObj<< endl;
-	}
-}
+		//cout << "old pvs obj: " << oldVcObj << " new: " << vcObj << endl;
+	}
+}
+
+
+void BvHierarchy::TestEvaluation(const BvhSubdivisionCandidate &sc)
+{
+	ViewCellContainer viewCells, frontViewCells, backViewCells;
+	
+	CollectViewCells(*sc.mParentData.mSampledObjects, viewCells, false, false);
+
+	// traverse through view cells and compute changes
+	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
+	
+	for (vit = viewCells.begin(); vit != viewCells.end(); ++ vit)
+	{
+		ViewCell *vc = *vit;
+
+		int vcTri;
+		int vcObj;
+
+		int oldVcTri = (int)vc->GetTrianglesInPvs();
+		int oldVcObj = vc->GetEntriesInPvs();
+
+		int nTriangles = 0;
+		int nObjects = 0;
+
+		Intersectable::NewMail();
+
+		VspViewCell *vspVc = static_cast<VspViewCell *>(vc);
+		VssRayContainer::const_iterator vit, vit_end = vspVc->mLeaves[0]->mVssRays.end();
+
+		for (vit = vspVc->mLeaves[0]->mVssRays.begin(); vit != vit_end; ++ vit)
+		{
+			VssRay *ray = *vit;
+			
+			BvhLeaf *obj = ray->mTerminationObject->mBvhLeaf;
+		
+			if (!obj->Mailed())
+			{
+				obj->Mail();
+
+				nTriangles += (int)obj->mObjects.size();
+				nObjects ++;
+			}
+
+			if (ray->mOriginObject)
+			{
+				obj = ray->mOriginObject->mBvhLeaf;
+			
+				if (!obj->Mailed())
+				{
+					obj->Mail();
+					nTriangles += (int)obj->mObjects.size();
+					nObjects ++;
+				}
+			}
+		}
+
+		cout << "old pvs tri: " << oldVcTri << " real: " << nTriangles << endl;
+		cout << "old pvs obj: " << oldVcObj << " real: " << nObjects << endl;
+	}
+}
+
 
 
@@ -467,4 +531,6 @@
 										BvhTraversalData &backData)
 { 
+	//TestEvaluation(sc);
+
 	// fill view cells cache
 	mNodeTimer.Entry();
@@ -627,5 +693,8 @@
 		AssociateViewCellsWithObjects(*tData.mSampledObjects);
 
+		EvalSubdivisionCandidate2(*frontCandidate, true, false);
+		cout << "\nfc2: " << frontCandidate->GetPriority() << endl;
 		EvalSubdivisionCandidate(*frontCandidate, true, false);
+		cout << "fc1: " << frontCandidate->GetPriority() << endl;
 		EvalSubdivisionCandidate(*backCandidate, true, false);
 
@@ -680,8 +749,6 @@
 	BvhLeaf *leaf = splitCandidate.mParentData.mNode;
 
-	// surface area heuristics is used when there is 
-	// no view space subdivision available. 
-	// In order to have some prioritized traversal, 
-	// we use this formula instead
+	// use urface area heuristics if no view space subdivision available. 
+	// For prioritized traversal we use this formula instead
 	if (mHierarchyManager->GetViewSpaceSubdivisionType() == 
 		HierarchyManager::NO_VIEWSPACE_SUBDIV)
@@ -693,7 +760,6 @@
 		// take render cost of node into account 
 		// otherwise danger of being stuck in a local minimum!
-		const float factor = mRenderCostDecreaseWeight;
-
-		priority = factor * renderCostDecr + (1.0f - factor) * oldRenderCost;
+		priority = mRenderCostDecreaseWeight          * renderCostDecr + 
+			       (1.0f - mRenderCostDecreaseWeight) * oldRenderCost;
 		
 		if (mHierarchyManager->mConsiderMemory)
@@ -723,5 +789,5 @@
 
 
-void BvHierarchy::EvalSubdivisionCandidate(BvhSubdivisionCandidate &splitCandidate, 
+void BvHierarchy::EvalSubdivisionCandidate2(BvhSubdivisionCandidate &splitCandidate, 
 										   const bool computeSplitPlane,
 										   const bool preprocessViewCells)
@@ -778,4 +844,6 @@
 	mEvalTimer.Entry();
 
+	// mark view cells according to what part of the split they see
+	// and compute volume
 	ViewCellContainer viewCells, frontViewCells, backViewCells;
 	
@@ -784,5 +852,4 @@
 	CollectViewCells(splitCandidate.mSampledBackObjects, backViewCells, false, false);
 
-	// compute view cells seen from front and back side of the split
 	float volFront = 0, volBack = 0, parentVol = 0;
 
@@ -810,5 +877,5 @@
 		if (vc->Mailed(0))
 		{
-			// view cell sees front AND on back side
+			// view cell sees front AND back object
 			++ frontAndBackViewCells;
 			vc->Mail(2);
@@ -823,5 +890,7 @@
 	}
 
-	
+	//cout << "pvol: " << parentVol << " front: " << volFront << " back: " << volBack << " diff: " <<  parentVol - volFront - volBack << endl;
+	
+
 	/////////////////////
 	//-- this bvh node is a pvs entry in all the view cells that see one of the objects.
@@ -829,8 +898,9 @@
 	// pvs size induced by this bvh node is #view cells
 	const float pvs = (float)viewCells.size();
+	
+	// for low #rays per object => the result is influenced by undersampling
 	const float avgRaysPerObject = AvgRaysPerObject((int)pvs, tData.mNumRays);
-
-	// for low #rays per object => the result is influenced by undersampling
 	splitCandidate.SetAvgRaysPerObject(avgRaysPerObject);
+
 	const float viewSpaceVol = GetViewSpaceVolume();
 
@@ -841,6 +911,9 @@
 	splitCandidate.mNumBackViewCells = (int)backViewCells.size();
 
-	// currently not working!!
-	// todo matt: fix this to cope with undersampling for new evaluation method
+	
+	////////////////////////
+	// warning: currently not working for new evaluation method!
+
+	// todo matt: fix this to cope with undersampling
 	splitCandidate.mCorrectedFrontVolume = 
 		mHierarchyManager->EvalCorrectedPvs(splitCandidate.mVolumeFrontViewCells, 
@@ -858,11 +931,13 @@
 	float newRenderCost = 0, oldRenderCost = 0;
 
-	const float frontTri = (float)splitCandidate.mFrontObjects.size();
-	const float backTri = (float)splitCandidate.mBackObjects.size();
-	// total #triangles in parent
-	const float totalTri = (float)(*tData.mSortedObjects[0]).size();
-
-
-	// compute render cost decrease in the seen view cells
+	// total #triangles in parent node
+	const int totalTri = (int)(*tData.mSortedObjects[0]).size();
+	const int frontTri = (int)splitCandidate.mFrontObjects.size();
+	const int backTri = (int)splitCandidate.mBackObjects.size();
+	
+	if (totalTri - frontTri - backTri != 0)
+		cout << "big error!!!" << endl;
+
+	// compute render cost decrease in the view cells which can see the object
 	ViewCellContainer::const_iterator vit, vit_end = viewCells.end();
 	
@@ -871,12 +946,12 @@
 		ViewCell *vc = *vit;
 
+		const int oldVcTri = (int)vc->GetTrianglesInPvs();
+		const int oldVcObj = vc->GetEntriesInPvs();
+
 		// triangles in this view cell
-		float vcTri;
+		int vcTri;
 		// #entries in this view cell
 		int vcObj;
-
-		float oldVcTri = vc->GetTrianglesInPvs();
-		int oldVcObj = vc->GetEntriesInPvs();
-
+		
 		// both nodes in this view cell
 		if (vc->Mailed(2))
@@ -888,33 +963,188 @@
 		else if (vc->Mailed(1))
 		{
+			// only back node in this view cell: #triangles is decreasing
+			vcTri = oldVcTri + backTri - totalTri; 
+			vcObj = oldVcObj;   
+		}
+		else // (vc->Mailed(0))
+		{
 			// only front node in this view cell: #triangles is decreasing
-			vcTri = oldVcTri - totalTri + backTri; 
-			vcObj = oldVcObj;   
-		}
-		else // (vc->Mailed(0))
-		{
-			// // only back node in this view cell: #triangles is decreasing
-			vcTri = oldVcTri - totalTri + frontTri; 
+			vcTri = oldVcTri + frontTri - totalTri; 
 			vcObj = oldVcObj;
 		}
 
-		oldRenderCost += mViewCellsManager->ComputeRenderCost((int)oldVcTri, (int)oldVcObj) * vc->GetVolume()  / viewSpaceVol;
-		newRenderCost += mViewCellsManager->ComputeRenderCost((int)vcTri, (int)vcObj) * vc->GetVolume() / viewSpaceVol;
+		const float oldRc = mViewCellsManager->ComputeRenderCost(oldVcTri, oldVcObj);
+		const float newRc = mViewCellsManager->ComputeRenderCost(vcTri, vcObj);
+
+		// compute weighted render cost 
+		oldRenderCost += oldRc * vc->GetVolume() / viewSpaceVol;
+		newRenderCost += newRc * vc->GetVolume() / viewSpaceVol;
 		//cout << "old rc=" << oldRenderCost << " new rc " << newRenderCost << endl;
 	}
 
+
+	const float dummyFrontVol = EvalViewCellsVolume(splitCandidate.mSampledFrontObjects) / viewSpaceVol;
+	const float dummyBackVol = EvalViewCellsVolume(splitCandidate.mSampledBackObjects) / viewSpaceVol;
+	const float dummyParentVol = EvalViewCellsVolume(leaf->mObjects) / viewSpaceVol;
+
+	const int dummyNumFrontViewCells = CountViewCells(splitCandidate.mSampledFrontObjects);
+	const int dummyNumBackViewCells = CountViewCells(splitCandidate.mSampledBackObjects);
+	const int dummyPvs = CountViewCells(*tData.mSampledObjects);
+	
+	const int dummyPvsEntriesIncr = - dummyPvs + dummyNumFrontViewCells + dummyNumBackViewCells;
+
+	const float relfrontCost = dummyFrontVol * (float)splitCandidate.mFrontObjects.size();
+	const float relBackCost =  dummyBackVol * (float)splitCandidate.mBackObjects.size();
+	const float relParentCost = dummyParentVol * (float)leaf->mObjects.size();
+
 	// compute global decrease in render cost
-	const float renderCostDecr = (oldRenderCost - newRenderCost);
-
-	// for each view cell seen from front and back there is a new entry
-	const int pvsEntriesIncr = frontAndBackViewCells;
-
+	const float dummyNewRenderCost = relfrontCost + relBackCost;
+	const float dummyRenderCostDecr = relParentCost - dummyNewRenderCost;
+
+
+
+	// compute global decrease in render cost
+	const float renderCostDecr = oldRenderCost - newRenderCost;
+
+	// for each view cell seeing both front and back object there is a new pvs entry
+	splitCandidate.SetPvsEntriesIncr(frontAndBackViewCells);
 	splitCandidate.SetRenderCostDecrease(renderCostDecr);
+	
+	float pseudoOldRenderCost = parentVol * (float)leaf->mObjects.size() / viewSpaceVol;
+
+	//cout << "cor. entries: " << dummyPvsEntriesIncr << " entries: " << frontAndBackViewCells << endl;
+	cout << "\nv1: " << renderCostDecr << " " << pseudoOldRenderCost << " " << newRenderCost << endl;
+	cout << "v2: " << dummyRenderCostDecr << " " << relParentCost << " " << dummyNewRenderCost << endl;
+
+	// at last computed priority based on render cost reduction / memory increase
+	const float priority = EvalPriority(splitCandidate, renderCostDecr,	pseudoOldRenderCost);
+	cout << "\nfc0: " << priority << endl;
+	const float priority2 = EvalPriority(splitCandidate, dummyRenderCostDecr, relParentCost);
+	splitCandidate.SetPriority(priority2);
+
+#if STORE_VIEWCELLS_WITH_BVH
+	if (preprocessViewCells)
+		ReleaseViewCells(*splitCandidate.mParentData.mSampledObjects);
+#endif
+
+	mEvalTimer.Exit();
+}
+
+
+void BvHierarchy::EvalSubdivisionCandidate(BvhSubdivisionCandidate &splitCandidate, 
+										   const bool computeSplitPlane,
+										   const bool preprocessViewCells)
+{
+	mPlaneTimer.Entry();
+
+#if STORE_VIEWCELLS_WITH_BVH
+	if (preprocessViewCells) // fill view cells cache
+		AssociateViewCellsWithObjects(*splitCandidate.mParentData.mSampledObjects);
+#endif
+
+	if (computeSplitPlane)
+	{
+		splitCandidate.mFrontObjects.clear();
+		splitCandidate.mBackObjects.clear();
+		splitCandidate.mSampledFrontObjects.clear();
+		splitCandidate.mSampledBackObjects.clear();
+
+		const bool sufficientSamples = 
+			splitCandidate.mParentData.mNumRays > mMinRaysForVisibility;
+
+		//if (!sufficientSamples) cout << splitCandidate.mParentData.mNumRays << " ";
+
+		const bool useVisibiliyBasedHeuristics = 
+					!mUseSah &&
+					(mHierarchyManager->GetViewSpaceSubdivisionType() == 
+					HierarchyManager::KD_BASED_VIEWSPACE_SUBDIV) &&
+					sufficientSamples;
+
+		// compute best object partition
+		const float ratio =	SelectObjectPartition(splitCandidate.mParentData, 
+												  splitCandidate.mFrontObjects, 
+												  splitCandidate.mBackObjects,
+												  useVisibiliyBasedHeuristics);
+	
+		// cost ratio violated?
+		const bool maxCostRatioViolated = mTermMaxCostRatio < ratio;
+		const int previousMisses = splitCandidate.mParentData.mMaxCostMisses;
+
+		splitCandidate.SetMaxCostMisses(maxCostRatioViolated ? 
+										previousMisses + 1 : previousMisses);
+
+		StoreSampledObjects(splitCandidate.mSampledFrontObjects, splitCandidate.mFrontObjects);
+		StoreSampledObjects(splitCandidate.mSampledBackObjects, splitCandidate.mBackObjects);
+	}
+
+	mPlaneTimer.Exit();
+
+	mEvalTimer.Entry();
+
+	const BvhTraversalData &tData = splitCandidate.mParentData;
+	BvhLeaf *leaf = tData.mNode;
+
+	// avg contribution of a ray to a pvs
+	const float pvs = (float)CountViewCells(*tData.mSampledObjects);
+	//const float avgRayContri = AvgRayContribution((int)pvs, tData.mNumRays);
+	const float avgRaysPerObject = AvgRaysPerObject((int)pvs, tData.mNumRays);
+
+	// high avg ray contri, the result is influenced by undersampling
+	splitCandidate.SetAvgRaysPerObject(avgRaysPerObject);
+	const float viewSpaceVol = GetViewSpaceVolume();
+
+	const float oldVolume = EvalViewCellsVolume(*tData.mSampledObjects) / viewSpaceVol;
+	const float oldRatio = (tData.mVolume > 0) ? oldVolume / tData.mVolume : 1;
+	const float parentVol = tData.mCorrectedVolume * oldRatio;
+
+	// this leaf is a pvs entry in all the view cells
+	// that see one of the objects.
+	splitCandidate.mVolumeFrontViewCells = EvalViewCellsVolume(splitCandidate.mSampledFrontObjects) / viewSpaceVol;
+	splitCandidate.mVolumeBackViewCells = EvalViewCellsVolume(splitCandidate.mSampledBackObjects) / viewSpaceVol;
+
+	splitCandidate.mNumFrontViewCells = CountViewCells(splitCandidate.mSampledFrontObjects);
+	splitCandidate.mNumBackViewCells = CountViewCells(splitCandidate.mSampledBackObjects);
+
+	splitCandidate.mCorrectedFrontVolume = 
+		mHierarchyManager->EvalCorrectedPvs(splitCandidate.mVolumeFrontViewCells, parentVol, avgRaysPerObject);
+	
+	splitCandidate.mCorrectedBackVolume = 
+		mHierarchyManager->EvalCorrectedPvs(splitCandidate.mVolumeBackViewCells, parentVol, avgRaysPerObject);
+
+#if 0
+	const float relfrontCost = splitCandidate.mCorrectedFrontVolume * splitCandidate.mFrontObjects.size();
+	const float relBackCost =  splitCandidate.mCorrectedBackVolume * splitCandidate.mBackObjects.size();
+	const float relParentCost = parentVol * leaf->mObjects.size();
+#else
+	const float relfrontCost = splitCandidate.mVolumeFrontViewCells * splitCandidate.mFrontObjects.size();
+	const float relBackCost =  splitCandidate.mVolumeBackViewCells * splitCandidate.mBackObjects.size();
+	const float relParentCost = oldVolume * leaf->mObjects.size();
+#endif
+	// compute global decrease in render cost
+	const float newRenderCost = relfrontCost + relBackCost;
+	const float renderCostDecr = relParentCost - newRenderCost;
+	
+	splitCandidate.SetRenderCostDecrease(renderCostDecr);
+
+	// increase in pvs entries
+	const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate, 
+												  avgRaysPerObject, 
+												  (int)pvs, 
+												  splitCandidate.mNumFrontViewCells, 
+												  splitCandidate.mNumBackViewCells);
+
 	splitCandidate.SetPvsEntriesIncr(pvsEntriesIncr);
 
-	//cout << "bvh render cost decrease=" << renderCostDecr << endl;
-
-	// at last computed priority based on render cost reduction / memory increase
-	const float priority = EvalPriority(splitCandidate, renderCostDecr,	oldRenderCost);
+#ifdef GTP_DEBUG
+	Debug << "old render cost: " << oldRenderCost << endl;
+	Debug << "new render cost: " << newRenderCost << endl;
+	Debug << "render cost decrease: " << renderCostDecr << endl;
+#endif
+
+	float priority = EvalPriority(splitCandidate, 
+								  renderCostDecr,
+								  relParentCost);
+
+  	// compute global decrease in render cost
 	splitCandidate.SetPriority(priority);
 
@@ -948,10 +1178,11 @@
 		mHierarchyManager->EvalCorrectedPvs((float)backViewCells, parentPvs, avgRaysPerObjects);
 
-	if (0)
-	cout << "bvh pvs"
-		 << " avg ray contri: " << avgRaysPerObjects << " ratio: " << oldPvsRatio 
-		 << " parent: " << parentPvs << " " << " old vol: " << oldPvsSize
-		 << " frontpvs: " << frontViewCells << " corr. " << splitCandidate.mCorrectedFrontPvs 
-		 << " backpvs: " << frontViewCells << " corr. " << splitCandidate.mCorrectedBackPvs << endl;
+#if GTP_DEBUG
+	Debug << "bvh node pvs"
+		  << " avg ray contri: " << avgRaysPerObjects << " ratio: " << oldPvsRatio 
+		  << " parent: " << parentPvs << " " << " old vol: " << oldPvsSize
+		  << " frontpvs: " << frontViewCells << " corr. " << splitCandidate.mCorrectedFrontPvs 
+		  << " backpvs: " << frontViewCells << " corr. " << splitCandidate.mCorrectedBackPvs << endl;
+#endif
 
 	return (int)(splitCandidate.mCorrectedFrontPvs + splitCandidate.mCorrectedBackPvs - parentPvs);
@@ -971,6 +1202,6 @@
 	if (terminationCriteriaMet)
 	{
-		cout << "bvh local termination criteria met:" << endl;
-		cout << "objects: " << (int)tData.mNode->mObjects.size() << " (" << mTermMinObjects << ")" << endl;
+		Debug << "bvh local termination criteria met:" << endl;
+		Debug << "objects: " << (int)tData.mNode->mObjects.size() << " (" << mTermMinObjects << ")" << endl;
 	}
 #endif
@@ -1011,11 +1242,5 @@
 	++ mCreatedLeaves;
 
-	
-	/*if (data.mProbability <= mTermMinProbability)
-	{
-		++ mBvhStats.minProbabilityNodes;
-	}*/
-
-	////////////////////////////////////////////
+	////////////////
 	// depth related stuff
 
@@ -1034,5 +1259,5 @@
 
 
-	////////////////////////////////////////////
+	//////////////////////
 	// objects related stuff
 
@@ -1082,7 +1307,7 @@
 
 #ifdef _DEBUG
-	cout << "depth: " << data.mDepth << " objects: " << (int)leaf->mObjects.size() 
-		 << " rays: " << data.mNumRays << " rays / objects " 
-		 << (float)data.mNumRays / (float)leaf->mObjects.size() << endl;
+	Debug << "depth: " << data.mDepth << " objects: " << (int)leaf->mObjects.size() 
+		  << " rays: " << data.mNumRays << " rays / objects " 
+		  << (float)data.mNumRays / (float)leaf->mObjects.size() << endl;
 #endif
 }
@@ -1128,5 +1353,5 @@
 
 	const float oldRenderCost = (float)tData.mNode->mObjects.size() * parentBox.SurfaceArea();
-	const float newRenderCost = (float)objectsFront.size() * fbox.SurfaceArea() +  (float)objectsBack.size() * bbox.SurfaceArea();
+	const float newRenderCost = (float)objectsFront.size() * fbox.SurfaceArea() + (float)objectsBack.size() * bbox.SurfaceArea();
 
 	const float ratio = newRenderCost / oldRenderCost;
@@ -1301,8 +1526,8 @@
   
 #ifdef GTP_DEBUG
-	cout << "\n\nobjects=(" << (int)objectsBack.size() << "," << (int)objectsFront.size() << " of " 
-		 << (int)tData.mNode->mObjects.size() << ")\t area=(" 
-		 << areaLeft << ", " << areaRight << ", " << boxArea << ")" << endl
-		 << "cost= " << newCost << " oldCost=" << totalRenderCost / boxArea << endl;
+	Debug << "\n\nobjects=(" << (int)objectsBack.size() << "," << (int)objectsFront.size() << " of " 
+		  << (int)tData.mNode->mObjects.size() << ")\t area=(" 
+		  << areaLeft << ", " << areaRight << ", " << boxArea << ")" << endl
+		  << "cost= " << newCost << " oldCost=" << totalRenderCost / boxArea << endl;
 #endif
 
@@ -1435,8 +1660,8 @@
   
 #ifdef GTP_DEBUG
-	cout << "\n\nobjects=(" << (int)objectsBack.size() << "," << (int)objectsFront.size() << " of " 
-		 << (int)tData.mNode->mObjects.size() << ")\t area=(" 
-		 << areaLeft << ", " << areaRight << ", " << boxArea << ")" << endl
-		 << "cost= " << newCost << " oldCost=" << totalRenderCost / boxArea << endl;
+	Debug << "\n\nobjects=(" << (int)objectsBack.size() << "," << (int)objectsFront.size() << " of " 
+		  << (int)tData.mNode->mObjects.size() << ")\t area=(" 
+		  << areaLeft << ", " << areaRight << ", " << boxArea << ")" << endl
+		  << "cost= " << newCost << " oldCost=" << totalRenderCost / boxArea << endl;
 #endif
 
@@ -1495,7 +1720,7 @@
 										   ObjectContainer &objectsBack)
 {
-	/////////////////////////////////////////////
-	//-- go through the lists, count the number of objects 
-	//-- left and right and evaluate the cost funcion
+	////////
+	// traverse split candidates, count the number of objects 
+	// left and right and evaluate the cost funcion
 
 	// prepare the heuristics, set mailboxes and counters
@@ -1603,5 +1828,5 @@
 
 #ifdef GTP_DEBUG
-	Debug << "\n§§§§ bvh eval const decrease §§§§" << endl
+	Debug << "\neval bvh split cost decrease" << endl
 		  << "back pvs: " << (int)objectsBack.size() << " front pvs: " 
 		  << (int)objectsFront.size() << " total pvs: " << nTotalObjects << endl 
@@ -1713,8 +1938,10 @@
 }
 
+
+
 ///////////////////////////////////////////////////////////
 
 
-void BvHierarchy::EvalHeuristicsContribution(Intersectable *obj,
+void BvHierarchy::EvalHeuristicsContribution(Intersectable *obj, 
 											 float &volLeft, 
 											 float &volRight)
@@ -1804,29 +2031,8 @@
 	}
 
-	// if #rays high consider only use a subset of the rays for 
+	// if #rays high, consider only use a subset of the rays for 
 	// visibility based heuristics
 	VssRay::NewMail();
 
-	/*if ((mMaxTests < tData.mNumRays) && mUseCostHeuristics && useVisibilityBasedHeuristics)
-	{
-		VssRayContainer rays;
-
-		// maximal 2 objects share the same ray
-		rays.reserve(tData.mNumRays * 2);
-		CollectRays(tData.mNode->mObjects, rays);
-
-		const float prop = (float)mMaxTests / (float)rays.size();
-
-		VssRayContainer::const_iterator rit, rit_end = rays.end();
-
-		// mail rays which will not be considered
-		for (rit = rays.begin(); rit != rit_end; ++ rit)
-		{
-			if (Random(1.0f) > prop)
-			{
-				(*rit)->Mail();
-			}
-		}		
-	}*/
 
 	////////////////////////////////////
@@ -1992,7 +2198,4 @@
 	//-- surface area heuristics
 
-	// eraly exit
-	//if (leaf->mObjects.empty())	return 0.0f;
-
 	const AxisAlignedBox3 box = GetBoundingBox(leaf);
 	const float area = box.SurfaceArea();
@@ -2854,6 +3057,6 @@
 		backData.mSortedObjects[i] = new ObjectContainer();
 
-		frontData.mSortedObjects[i]->reserve((int)sc.mFrontObjects.size());
-		backData.mSortedObjects[i]->reserve((int)sc.mBackObjects.size());
+		frontData.mSortedObjects[i]->reserve(sc.mFrontObjects.size());
+		backData.mSortedObjects[i]->reserve(sc.mBackObjects.size());
 
 		ObjectContainer::const_iterator oit, oit_end = sc.mParentData.mSortedObjects[i]->end();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.cpp	(revision 2332)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.cpp	(revision 2347)
@@ -109,6 +109,4 @@
 
 
-
-
 void GetRayInfoSets(const RayInfoContainer &sourceRays,
                     const int maxSize,
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 2342)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 2347)
@@ -1708,7 +1708,7 @@
 
 
-
 float ViewCellsManager::ComputeRenderCost(const int tri, const int obj) //const
 {
+	return (float)tri;
 	return max((float)tri * mTriangleWeight, (float)obj * mObjectWeight);
 }
@@ -2087,5 +2087,4 @@
 			sum += ComputeSampleContribution(*(*it), addContributions, storeViewCells, useHitObjects);
 		}
-
 	}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 2332)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 2347)
@@ -579,4 +579,8 @@
 								  const bool preprocessViewCells);
 
+	void EvalSubdivisionCandidate2(BvhSubdivisionCandidate &splitData,
+								  const bool computeSplitPlane,
+								  const bool preprocessViewCells);
+
 	/** Returns vector of leaves.
 	*/
@@ -990,4 +994,5 @@
 
 	void UpdateViewCells(const BvhSubdivisionCandidate &sc);
+	void TestEvaluation(const BvhSubdivisionCandidate &sc);
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 2342)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 2347)
@@ -31,4 +31,5 @@
 #define HACK_PERFORMANCE 1
 
+#define HAS_TO_BE_REDONE 0
 
 /////////////
@@ -258,4 +259,5 @@
 {
 	VssRayContainer::const_iterator vit, vit_end = mVssRays.end();
+
 	for (vit = mVssRays.begin(); vit != vit_end; ++ vit)
 	{
@@ -266,5 +268,4 @@
 			delete ray;
 	}
-	//CLEAR_CONTAINER(mVssRays);
 }
 
@@ -312,5 +313,6 @@
 mRoot(NULL),
 mOutOfBoundsCell(NULL),
-mStoreRays(false),
+//mStoreRays(false),
+mStoreRays(true),
 mTimeStamp(1),
 mHierarchyManager(NULL)
@@ -554,5 +556,5 @@
 	if (updatePvs)
 	{
-		// update pvs of view cell
+		// store pvs of view cell
 		AddSamplesToPvs(leaf, *tData.mRays, sampCon, conSamp);
 
@@ -579,11 +581,13 @@
 		//-- store sampling rays
 
-        RayInfoContainer::const_iterator it, it_end = tData.mRays->end();
-
-		for (it = tData.mRays->begin(); it != it_end; ++ it)
-		{
-			(*it).mRay->Ref();			
+        RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
+
+		for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
+		{
+			VssRay *ray = new VssRay(*(*rit).mRay);
+			ray->Ref();
+
 			// note: should rather store rays with view cell
-			leaf->mVssRays.push_back((*it).mRay);
+			leaf->mVssRays.push_back(ray);
 		}
 	}
@@ -668,28 +672,10 @@
 	{
 		VspLeaf *leaf = static_cast<VspLeaf *>(newNode);
-		
-#if 0
-        /////////////
-		//-- store pvs optained from rays
-
-		// view cell is created during subdivision
-		ViewCell *viewCell = leaf->GetViewCell();
-
-		int conSamp = 0;
-		float sampCon = 0.0f;
-
-		AddSamplesToPvs(leaf, *tData.mRays, sampCon, conSamp);
-
-		// update scalar pvs size value
-		ObjectPvs &pvs = viewCell->GetPvs();
-		mViewCellsManager->UpdateScalarPvsSize(viewCell, pvs.EvalPvsCost(), pvs.GetSize());
-
-		mVspStats.contributingSamples += conSamp;
-		mVspStats.sampleContributions += (int)sampCon;
-#endif
-		if (mStoreRays)
+	
+		if (0 && mStoreRays)
 		{
 			//////////
 			//-- store rays piercing this view cell
+
 			RayInfoContainer::const_iterator it, it_end = tData.mRays->end();
 			for (it = tData.mRays->begin(); it != it_end; ++ it)
@@ -697,5 +683,4 @@
 				(*it).mRay->Ref();			
 				leaf->mVssRays.push_back((*it).mRay);
-				//leaf->mVssRays.push_back(new VssRay(*(*it).mRay));
 			}
 		}
@@ -753,6 +738,5 @@
 	RayInfoContainer::const_iterator rit, rit_end = splitCandidate.mParentData.mRays->end();
 
-	float frontTriangles = 0, backTriangles = 0, totalTriangles = 0;
-	int frontObjects = 0, backObjects = 0, totalObjects = 0;
+	SplitData sData;
 
 	Intersectable::NewMail(3);
@@ -779,7 +763,5 @@
 		// evaluate contribution of ray endpoint to front 
 		// and back pvs with respect to the classification
-		UpdateContributionsToPvs(leaf, cf, 
-								 frontTriangles, backTriangles, totalTriangles,
-								 frontObjects, backObjects, totalObjects);
+		UpdateContributionsToPvs(leaf, cf, sData);
 
 #if COUNT_ORIGIN_OBJECTS
@@ -791,7 +773,5 @@
 			leaf = mBvHierarchy->GetLeaf(obj);
 
-			UpdateContributionsToPvs(leaf, cf, 
-									 frontTriangles, backTriangles, totalTriangles,
-									 frontObjects, backObjects, totalObjects);
+			UpdateContributionsToPvs(leaf, cf, sData); 
 		}
 #endif
@@ -802,7 +782,7 @@
 	}
 
-	const float totalRenderCost = mViewCellsManager->ComputeRenderCost((int)totalTriangles, totalObjects);
-	const float backRenderCost = mViewCellsManager->ComputeRenderCost((int)backTriangles, backObjects);
-	const float frontRenderCost = mViewCellsManager->ComputeRenderCost((int)frontTriangles, frontObjects);
+	sData.mTotalRenderCost = mViewCellsManager->ComputeRenderCost(sData.mTotalTriangles, sData.mTotalObjects);
+	sData.mBackRenderCost = mViewCellsManager->ComputeRenderCost(sData.mBackTriangles, sData.mBackObjects);
+	sData.mFrontRenderCost = mViewCellsManager->ComputeRenderCost(sData.mFrontTriangles, sData.mFrontObjects);
 	
 
@@ -810,33 +790,27 @@
 	// avg ray contri
 
-	const float avgRayContri = (float)totalObjects / 
+	const float avgRayContri = (float)sData.mTotalObjects / 
 		((float)splitCandidate.mParentData.mRays->size() + Limits::Small);
 
-	splitCandidate.SetAvgRayContribution(avgRayContri);
-
-	const float avgRaysPerObject = 
-		(float)splitCandidate.mParentData.mRays->size() / ((float)totalTriangles + Limits::Small);
+	const float avgRaysPerObject = (float)splitCandidate.mParentData.mRays->size() / 
+		((float)sData.mTotalObjects + Limits::Small);
+
+	//cout << "avg rays per obj: " << avgRaysPerObject << endl;
 
 	splitCandidate.SetAvgRayContribution(avgRayContri);
 	splitCandidate.SetAvgRaysPerObject(avgRaysPerObject);
-
 
 	// todo: compute old render cost in the function
 	// using michi's render cost evaluation
 	float oldRenderCost;
-	const float renderCostDecr = EvalRenderCostDecrease(splitCandidate, 
-														oldRenderCost,
-														totalRenderCost, 
-														frontRenderCost, 
-														backRenderCost);
-
+	const float renderCostDecr = EvalRenderCostDecrease(splitCandidate, oldRenderCost, sData);
 	splitCandidate.SetRenderCostDecrease(renderCostDecr);
 
 	// the increase in pvs entries num induced by this split
-	const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate, totalObjects, frontObjects, backObjects);
+	const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate, sData);
 	splitCandidate.SetPvsEntriesIncr(pvsEntriesIncr);
 
-	splitCandidate.mFrontTriangles = frontTriangles;
-	splitCandidate.mBackTriangles = backTriangles;
+	splitCandidate.mFrontTriangles = (float)sData.mFrontTriangles;
+	splitCandidate.mBackTriangles = (float)sData.mBackTriangles;
 	
 	// take render cost of node into account 
@@ -857,31 +831,26 @@
 
 int VspTree::EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate,
-								const int oldPvsSize,
-								const int fPvsSize,
-								const int bPvsSize) const
-{
-	
-	RayInfoContainer::const_iterator rit, rit_end = splitCandidate.mParentData.mRays->end();
-
+								const SplitData &sData) const
+{
 	const float oldPvsRatio = (splitCandidate.mParentData.mPvs > 0) ? 
-		oldPvsSize / splitCandidate.mParentData.mPvs : 1;
+		sData.mTotalObjects / splitCandidate.mParentData.mPvs : 1;
 	const float correctedOldPvs = splitCandidate.mParentData.mCorrectedPvs * oldPvsRatio;
 
 	splitCandidate.mCorrectedFrontPvs = 
-		mHierarchyManager->EvalCorrectedPvs((float)fPvsSize, 
+		mHierarchyManager->EvalCorrectedPvs((float)sData.mFrontObjects, 
 											(float)correctedOldPvs, 
 											splitCandidate.GetAvgRaysPerObject());
 	splitCandidate.mCorrectedBackPvs = 
-		mHierarchyManager->EvalCorrectedPvs((float)bPvsSize, 
+		mHierarchyManager->EvalCorrectedPvs((float)sData.mBackObjects, 
 											(float)correctedOldPvs, 
 											splitCandidate.GetAvgRaysPerObject());
 	
-	splitCandidate.mFrontPvs = (float)fPvsSize;
-	splitCandidate.mBackPvs = (float)bPvsSize;
-
-#if TODO
+	splitCandidate.mFrontPvs = (float)sData.mFrontObjects;
+	splitCandidate.mBackPvs = (float)sData.mBackObjects;
+
+#if HAS_TO_BE_REDONE
 	return (int)(splitCandidate.mCorrectedFrontPvs + splitCandidate.mCorrectedBackPvs - correctedOldPvs);
 #else
-	return fPvsSize + bPvsSize - oldPvsSize;
+	return sData.mFrontObjects + sData.mBackObjects - sData.mTotalObjects;
 #endif
 }
@@ -1038,7 +1007,4 @@
 			++ contributingSamples;
 		}
-
-		// store rays for visualization
-		if (0) leaf->mVssRays.push_back(new VssRay(*ray));
 	}
 }
@@ -1475,5 +1441,4 @@
 
 			exporter->SetForcedMaterial(m);
-
 			exporter->ExportIntersectable(leaf);
 
@@ -1505,5 +1470,5 @@
 
 #ifdef GTP_DEBUG
-	cout << "\n((((( eval local cost )))))" << endl
+	Debug << "\n((((( eval local vsp cost )))))" << endl
 		  << "back pvs: " << penaltyBack << " front pvs: " << penaltyFront << " total pvs: " << penaltyOld << endl 
 		  << "back p: " << pBack * volRatio << " front p " << pFront * volRatio << " p: " << pOverall * volRatio << endl
@@ -1626,7 +1591,5 @@
 float VspTree::EvalRenderCostDecrease(VspSubdivisionCandidate &sc,
 									  float &normalizedOldRenderCost,
-									  const float totalRenderCost,
-									  const float frontRenderCost,
-									  const float backRenderCost) const
+									  const SplitData &sData) const
 {
 	const float viewSpaceVol = mBoundingBox.GetVolume();
@@ -1655,14 +1618,14 @@
 
 	// ratio of how render cost changed since last evaluation
-	const float oldRenderCostRatio = (tData.mRenderCost > 0)? (totalRenderCost / tData.mRenderCost) : 1;
+	const float oldRenderCostRatio = (tData.mRenderCost > 0)? (sData.mTotalRenderCost / tData.mRenderCost) : 1;
 	const float penaltyOld = tData.mCorrectedRenderCost * oldRenderCostRatio;
 
-	sc.mCorrectedFrontRenderCost = mHierarchyManager->EvalCorrectedPvs(frontRenderCost, penaltyOld, avgRaysPerObject);
-	sc.mCorrectedBackRenderCost = mHierarchyManager->EvalCorrectedPvs(backRenderCost, penaltyOld, avgRaysPerObject);
-
-	sc.mFrontRenderCost = frontRenderCost;
-	sc.mBackRenderCost = backRenderCost;
-
-#if TODO // undersampling evalution does not work yet
+	sc.mCorrectedFrontRenderCost = mHierarchyManager->EvalCorrectedPvs(sData.mFrontRenderCost, penaltyOld, avgRaysPerObject);
+	sc.mCorrectedBackRenderCost = mHierarchyManager->EvalCorrectedPvs(sData.mBackRenderCost, penaltyOld, avgRaysPerObject);
+
+	sc.mFrontRenderCost = sData.mFrontRenderCost;
+	sc.mBackRenderCost = sData.mBackRenderCost;
+
+#if HAS_TO_BE_REDONE // undersampling evalution does not work yet
 
 	const float oldRenderCost = penaltyOld * pOverall;
@@ -1672,6 +1635,6 @@
 #else
 
-	const float oldRenderCost = totalRenderCost * pOverall;
-	const float newRenderCost = frontRenderCost * pFront + backRenderCost * pBack;
+	const float oldRenderCost = sData.mTotalRenderCost * pOverall;
+	const float newRenderCost = sData.mFrontRenderCost * pFront + sData.mBackRenderCost * pBack;
 
 #endif
@@ -1682,4 +1645,6 @@
 	// the render cost decrase for this split
 	const float renderCostDecrease = (oldRenderCost - newRenderCost) / viewSpaceVol;
+
+	//cout << "old: " << normalizedOldRenderCost << " new: " << newRenderCost / viewSpaceVol << " corr: " << tData.mCorrectedRenderCost << " ratio: " << oldRenderCostRatio << endl;
 
 	return renderCostDecrease;
@@ -1834,18 +1799,13 @@
 void VspTree::UpdateContributionsToPvs(BvhLeaf *leaf,
 									   const int cf,
-									   float &frontPvs,
-									   float &backPvs,
-									   float &totalPvs,
-									   int &frontSize,
-									   int &backSize,
-									   int &totalSize) const
-{
-	const float triSize = (float)leaf->mObjects.size();
+									   SplitData &sData) const
+{
+	const int triSize = (int)leaf->mObjects.size();
 	
 	// object in no pvs => count as new
 	if (!leaf->Mailed() && !leaf->Mailed(1) && !leaf->Mailed(2))
 	{
-		totalPvs += triSize;
-		++ totalSize;
+		sData.mTotalTriangles += (int)triSize;
+		++ sData.mTotalObjects;
 	}
 
@@ -1854,6 +1814,6 @@
 		if (!leaf->Mailed() && !leaf->Mailed(2))
 		{
-			frontPvs += triSize;
-			++ frontSize;
+			sData.mFrontTriangles += triSize;
+			++ sData.mFrontObjects;
 
 			// already in back pvs => in both pvss
@@ -1869,6 +1829,6 @@
 		if (!leaf->Mailed(1) && !leaf->Mailed(2))
 		{
-			backPvs += triSize;
-			++ backSize;
+			sData.mBackTriangles += triSize;
+			++ sData.mBackObjects;
 
 			// already in front pvs => in both pvss
@@ -2044,15 +2004,38 @@
 
 
-void VspTree::CollapseViewCells()
-{
-// TODO matt
-#if HAS_TO_BE_REDONE
-	stack<VspNode *> nodeStack;
-
+void VspTree::CollectRays(VssRayContainer &rays)
+{
+	vector<VspLeaf *> leaves;
+	CollectLeaves(leaves);
+
+	vector<VspLeaf *>::const_iterator lit, lit_end = leaves.end();
+
+	for (lit = leaves.begin(); lit != lit_end; ++ lit)
+	{
+		VspLeaf *leaf = *lit;
+		VssRayContainer::const_iterator rit, rit_end = leaf->mVssRays.end();
+
+		for (rit = leaf->mVssRays.begin(); rit != rit_end; ++ rit)
+			rays.push_back(*rit);
+	}
+}
+
+
+void VspTree::SetViewCellsManager(ViewCellsManager *vcm)
+{
+	mViewCellsManager = vcm;
+}
+
+
+void VspTree::ValidateTree()
+{
 	if (!mRoot)
 		return;
 
+	mVspStats.invalidLeaves = 0;
+	stack<VspNode *> nodeStack;
+
 	nodeStack.push(mRoot);
-	
+
 	while (!nodeStack.empty()) 
 	{
@@ -2061,27 +2044,15 @@
 		
 		if (node->IsLeaf())
-        {
-			BspViewCell *viewCell = static_cast<VspLeaf *>(node)->GetViewCell();
-
-			if (!viewCell->GetValid())
-			{
-				BspViewCell *viewCell = static_cast<VspLeaf *>(node)->GetViewCell();
-	
-				ViewCellContainer leaves;
-				mViewCellsTree->CollectLeaves(viewCell, leaves);
-
-				ViewCellContainer::const_iterator it, it_end = leaves.end();
-
-				for (it = leaves.begin(); it != it_end; ++ it)
-				{
-					VspLeaf *l = static_cast<BspViewCell *>(*it)->mLeaf;
-					l->SetViewCell(GetOrCreateOutOfBoundsCell());
-					++ mVspStats.invalidLeaves;
-				}
-
-				// add to unbounded view cell
-				ViewCell *outOfBounds = GetOrCreateOutOfBoundsCell();
-				outOfBounds->GetPvs().AddPvs(viewCell->GetPvs());
-				DEL_PTR(viewCell);
+		{
+			VspLeaf *leaf = static_cast<VspLeaf *>(node);
+
+			if (!leaf->GetViewCell()->GetValid())
+				++ mVspStats.invalidLeaves;
+
+			// validity flags don't match => repair
+			if (leaf->GetViewCell()->GetValid() != leaf->TreeValid())
+			{
+				leaf->SetTreeValid(leaf->GetViewCell()->GetValid());
+				PropagateUpValidity(leaf);
 			}
 		}
@@ -2096,71 +2067,4 @@
 
 	Debug << "invalid leaves: " << mVspStats.invalidLeaves << endl;
-#endif
-}
-
-
-void VspTree::CollectRays(VssRayContainer &rays)
-{
-	vector<VspLeaf *> leaves;
-	CollectLeaves(leaves);
-
-	vector<VspLeaf *>::const_iterator lit, lit_end = leaves.end();
-
-	for (lit = leaves.begin(); lit != lit_end; ++ lit)
-	{
-		VspLeaf *leaf = *lit;
-		VssRayContainer::const_iterator rit, rit_end = leaf->mVssRays.end();
-
-		for (rit = leaf->mVssRays.begin(); rit != rit_end; ++ rit)
-			rays.push_back(*rit);
-	}
-}
-
-
-void VspTree::SetViewCellsManager(ViewCellsManager *vcm)
-{
-	mViewCellsManager = vcm;
-}
-
-
-void VspTree::ValidateTree()
-{
-	if (!mRoot)
-		return;
-
-	mVspStats.invalidLeaves = 0;
-	stack<VspNode *> nodeStack;
-
-	nodeStack.push(mRoot);
-
-	while (!nodeStack.empty()) 
-	{
-		VspNode *node = nodeStack.top();
-		nodeStack.pop();
-		
-		if (node->IsLeaf())
-		{
-			VspLeaf *leaf = static_cast<VspLeaf *>(node);
-
-			if (!leaf->GetViewCell()->GetValid())
-				++ mVspStats.invalidLeaves;
-
-			// validity flags don't match => repair
-			if (leaf->GetViewCell()->GetValid() != leaf->TreeValid())
-			{
-				leaf->SetTreeValid(leaf->GetViewCell()->GetValid());
-				PropagateUpValidity(leaf);
-			}
-		}
-		else
-		{
-			VspInterior *interior = static_cast<VspInterior *>(node);
-		
-			nodeStack.push(interior->GetFront());
-			nodeStack.push(interior->GetBack());
-		}
-	}
-
-	Debug << "invalid leaves: " << mVspStats.invalidLeaves << endl;
 }
 
@@ -2168,7 +2072,7 @@
 
 void VspTree::CollectViewCells(VspNode *root,
-								  bool onlyValid,
-								  ViewCellContainer &viewCells,
-								  bool onlyUnmailed) const
+							   bool onlyValid,
+							   ViewCellContainer &viewCells,
+							   bool onlyUnmailed) const
 {
 	if (!root)
