Index: GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 1845)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 1912)
@@ -206,5 +206,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 QtCore4.lib qtmain.lib QtOpenGL4.lib Qt3Support4.lib QtTest4.lib QtGui4.lib QtGlRenderer.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;&quot;$(QTDIR)\lib&quot;;.\QtGlRenderer\Release"
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1902)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1912)
@@ -2658,4 +2658,9 @@
 					"99999.0");
 	
+	RegisterOption("Hierarchy.Construction.minAvgRayContri",
+					optFloat,
+					"hierarchy_construction_min_avg_raycontri=",
+					"99990.0");
+	
 	/////////////////////////////////////////////////////////////////
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1911)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1912)
@@ -296,7 +296,7 @@
 	void CreateUniqueObjectIds();
 
-	float EvalPvsCorrectionFactor(const float pvsFront, 
-								  const float totalPvs,
-								  const float avgRayContri) const;
+	float EvalCorrectedPvs(const float pvsFront, 
+						   const float totalPvs,
+						   const float avgRayContri) const;
 
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 1845)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 1912)
@@ -372,11 +372,12 @@
 
 		VspTraversalData():
-		mNode(NULL),
-		mDepth(0),
-		mRays(NULL),
-		mPvs(0),
-		mProbability(0.0),
-		mMaxCostMisses(0), 
-		mPriority(0)
+			mNode(NULL),
+			mDepth(0),
+			mRays(NULL),
+			mPvs(0),
+			mProbability(0.0),
+			mMaxCostMisses(0), 
+			mPriority(0),
+			mCorrectedPvs(0)
 		{}
 		
@@ -387,12 +388,15 @@
 						 const float p,
 						 const AxisAlignedBox3 &box):
-		mNode(node), 
-		mDepth(depth), 
-		mRays(rays),
-		mPvs(pvs),
-		mProbability(p),
-		mBoundingBox(box),
-		mMaxCostMisses(0),
-		mPriority(0)
+			mNode(node), 
+			mDepth(depth), 
+			mRays(rays),
+			mProbability(p),
+			mBoundingBox(box),
+			mMaxCostMisses(0),
+			mPriority(0),
+			mCorrectedPvs(0),
+			mPvs(pvs),
+			mRenderCost(0),
+			mCorrectedRenderCost(0)
 		{}
 
@@ -400,11 +404,14 @@
 						 RayInfoContainer *rays,
 						 const AxisAlignedBox3 &box): 
-		mNode(NULL), 
-		mDepth(depth), 
-		mRays(rays),
-		mPvs(0),
-		mProbability(0),
-		mMaxCostMisses(0),
-		mBoundingBox(box)
+			mNode(NULL), 
+			mDepth(depth), 
+			mRays(rays),
+			mProbability(0),
+			mMaxCostMisses(0),
+			mBoundingBox(box),
+			mCorrectedPvs(0),
+			mPvs(0)	,
+			mRenderCost(0),
+			mCorrectedRenderCost(0)	
 		{}
 
@@ -425,4 +432,5 @@
 				// delete old view cell
 				delete mNode->GetViewCell();
+
 				delete mNode;
 				mNode = NULL;
@@ -440,12 +448,17 @@
 		/// the bounding box of the node
 		AxisAlignedBox3 mBoundingBox;
-		/// pvs size
-		float mPvs;
 		/// how often this branch has missed the max-cost ratio
 		int mMaxCostMisses;
 		// current priority
 		float mPriority;
-
-		
+		/// pvs size
+		float mPvs;
+		/// the correction factor for this pvs
+		float mCorrectedPvs;
+		/// pvs size
+		float mRenderCost;
+		/// the correction factor for this pvs
+		float mCorrectedRenderCost;
+
 		friend bool operator<(const VspTraversalData &a, const VspTraversalData &b)
 		{
@@ -460,11 +473,4 @@
 	public:
 
-		static VspTree* sVspTree;
-
-		/// the current split plane
-		AxisAlignedPlane mSplitPlane;
-		/// parent node traversal data
-		VspTraversalData mParentData;
-		
 		VspSubdivisionCandidate(const VspTraversalData &tData): mParentData(tData)
 		{};
@@ -502,6 +508,6 @@
 		}
 
-        VspSubdivisionCandidate(const AxisAlignedPlane &plane, const VspTraversalData &tData): 
-		mSplitPlane(plane), mParentData(tData)
+		VspSubdivisionCandidate(const AxisAlignedPlane &plane, const VspTraversalData &tData): 
+			mSplitPlane(plane), mParentData(tData)
 		{}
 
@@ -510,4 +516,19 @@
 			return mPriority;
 		}
+
+		////////////////////
+
+		static VspTree* sVspTree;
+
+		/// the current split plane
+		AxisAlignedPlane mSplitPlane;
+		/// parent node traversal data
+		VspTraversalData mParentData;
+	
+		float mCorrectedFrontPvs;
+		float mCorrectedBackPvs;
+
+		float mCorrectedFrontRenderCost;
+		float mCorrectedBackRenderCost;
 	};
 
@@ -729,6 +750,5 @@
 	/** Evaluates render cost decrease of next split.
 	*/
-	float EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
-								 const VspTraversalData &data,
+	float EvalRenderCostDecrease(VspSubdivisionCandidate &splitData, 
 								 float &normalizedOldRenderCost) const;
 
@@ -790,6 +810,5 @@
 		@returns the root of the subdivision
 	*/
-	VspInterior *SubdivideNode(const AxisAlignedPlane &splitPlane,
-							   VspTraversalData &tData,
+	VspInterior *SubdivideNode(const VspSubdivisionCandidate &sc,
 							   VspTraversalData &frontData,
                                VspTraversalData &backData);
@@ -813,7 +832,7 @@
 	*/
 	void SortSubdivisionCandidates(const RayInfoContainer &rays, 
-							 const int axis, 
-							 float minBand, 
-							 float maxBand);
+								   const int axis, 
+								   float minBand, 
+								   float maxBand);
 
 	/** Evaluate render cost of this pvs.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1911)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1912)
@@ -381,4 +381,5 @@
 	const BvhTraversalData &tData = sc.mParentData;
 	BvhLeaf *leaf = tData.mNode;
+
 	AxisAlignedBox3 parentBox = leaf->GetBoundingBox();
 
@@ -424,5 +425,5 @@
 
 	////////////////////////////////////////
-	//-- fill  front and back traversal data with the new values
+	//-- fill front and back traversal data with the new values
 
 	frontData.mDepth = backData.mDepth = tData.mDepth + 1;
@@ -442,19 +443,23 @@
 	AssociateObjectsWithLeaf(front);
    
-#if PROBABILIY_IS_BV_VOLUME
-	// volume of bvh (= probability that this bvh can be seen)
-	frontData.mProbability = fbox.GetVolume();
-	backData.mProbability = bbox.GetVolume();
-#else
+	//-- compute pvs correction to cope with undersampling
+	frontData.mPvs = CountViewCells(front->mObjects);
+	backData.mPvs = CountViewCells(back->mObjects);
+
+	frontData.mCorrectedPvs = sc.mCorrectedFrontPvs;
+	backData.mCorrectedPvs = sc.mCorrectedBackPvs;
+
 	// compute probability of this node being visible, 
 	// i.e., volume of the view cells that can see this node
-	frontData.mProbability = EvalViewCellsVolume(sc.mFrontObjects);
-	backData.mProbability = EvalViewCellsVolume(sc.mBackObjects);
-#endif
+	frontData.mRenderCost = EvalRenderCost(sc.mFrontObjects);
+	backData.mRenderCost = EvalRenderCost(sc.mBackObjects);
+
+	frontData.mCorrectedRenderCost = sc.mCorrectedFrontCost;
+	backData.mCorrectedRenderCost = sc.mCorrectedBackCost;
 
     // how often was max cost ratio missed in this branch?
 	frontData.mMaxCostMisses = sc.GetMaxCostMisses();
 	backData.mMaxCostMisses = sc.GetMaxCostMisses();
-	
+
 	// set the time stamp so the order of traversal can be reconstructed
 	node->SetTimeStamp(mHierarchyManager->mTimeStamp ++);
@@ -619,34 +624,46 @@
 	}
 
-	BvhLeaf *leaf = splitCandidate.mParentData.mNode;
-
-	if (USE_AVGRAYCONTRI)
-	{
-		// this leaf is a pvs entry in all the view cells
-		// that see one of the objects.
-		const int pvs = CountViewCells(leaf->mObjects);
-		//const int pvs = (int)leaf->mObjects.size();
-	
-		// avg contribution of a ray to a pvs
-		const float avgRayContri = 
-			AvgRayContribution(pvs, splitCandidate.mParentData.mNumRays);
-
-		// high avg ray contri, the result is influenced by undersampling
-		splitCandidate.SetAvgRayContri(avgRayContri);
-	}
-
-	const float oldProp = EvalViewCellsVolume(leaf->mObjects);
+	const BvhTraversalData &tData = splitCandidate.mParentData;
+	BvhLeaf *leaf = tData.mNode;
+
+	// avg contribution of a ray to a pvs
+	const float pvs = CountViewCells(leaf->mObjects);
+	const float avgRayContri = AvgRayContribution(pvs, tData.mNumRays);
+
+	cout << "bvh avg ray contri: " << avgRayContri << endl;
+	// high avg ray contri, the result is influenced by undersampling
+	splitCandidate.SetAvgRayContribution(avgRayContri);
+
 	const float oldRenderCost = EvalRenderCost(leaf->mObjects);
+	const float oldRatio = oldRenderCost / tData.mRenderCost;
+	const float parentCost = tData.mCorrectedRenderCost * oldRatio;
+
+	cout << "old ratio: " << oldRatio << endl;
+	// this leaf is a pvs entry in all the view cells
+	// that see one of the objects.
+	const int frontCost = EvalRenderCost(splitCandidate.mFrontObjects);
+	const int backCost = EvalRenderCost(splitCandidate.mBackObjects);
+
+	cout <<"here8 ============ "<< parentCost << endl;
+	splitCandidate.mCorrectedFrontCost = 
+		mHierarchyManager->EvalCorrectedPvs(frontCost, parentCost, avgRayContri);
+
+	cout << "bvh front cost: " << frontCost << " corrected: " << splitCandidate.mCorrectedFrontCost << endl;
+	cout <<"here104 "<< endl;
+
+	splitCandidate.mCorrectedBackCost = 
+		mHierarchyManager->EvalCorrectedPvs(backCost, parentCost, avgRayContri);
+	
+	cout << "back cost: " << backCost << " corrected: " << splitCandidate.mCorrectedBackCost << endl;
 
 	// compute global decrease in render cost
-	const float newRenderCost = EvalRenderCost(splitCandidate.mFrontObjects) +
-								EvalRenderCost(splitCandidate.mBackObjects);
-
-	const float renderCostDecr = oldRenderCost - newRenderCost;
+	const float newRenderCost = 
+		splitCandidate.mCorrectedFrontCost + splitCandidate.mCorrectedBackCost;
+	const float renderCostDecr = parentCost - newRenderCost;
 	
 	splitCandidate.SetRenderCostDecrease(renderCostDecr);
 
 	// increase in pvs entries
-	const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate);
+	const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate, avgRayContri);
 	splitCandidate.SetPvsEntriesIncr(pvsEntriesIncr);
 	
@@ -666,12 +683,24 @@
 
 
-int BvHierarchy::EvalPvsEntriesIncr(BvhSubdivisionCandidate &splitCandidate) const
+int BvHierarchy::EvalPvsEntriesIncr(BvhSubdivisionCandidate &splitCandidate, 
+									const float avgRayContri) const
 {
 	const int oldPvsSize = CountViewCells(splitCandidate.mParentData.mNode->mObjects);
-	
-	const int fPvsSize = CountViewCells(splitCandidate.mFrontObjects);
-	const int bPvsSize = CountViewCells(splitCandidate.mBackObjects);
-
-	return fPvsSize + bPvsSize - oldPvsSize;
+	const float oldPvsRatio = splitCandidate.mParentData.mPvs > 0 ? oldPvsSize / splitCandidate.mParentData.mPvs : 1;
+
+	const float parentPvs = splitCandidate.mParentData.mCorrectedPvs * oldPvsRatio;
+
+	const int frontViewCells = CountViewCells(splitCandidate.mFrontObjects);
+	const int backViewCells = CountViewCells(splitCandidate.mBackObjects);
+	
+	cout <<"here105 " << splitCandidate.mParentData.mCorrectedPvs << endl;
+	cout <<"here106 " << oldPvsRatio << endl;
+
+	splitCandidate.mCorrectedFrontPvs = 
+		mHierarchyManager->EvalCorrectedPvs(frontViewCells, parentPvs, avgRayContri);
+	splitCandidate.mCorrectedBackPvs =
+		mHierarchyManager->EvalCorrectedPvs(backViewCells, parentPvs, avgRayContri);
+
+	return splitCandidate.mCorrectedFrontPvs + splitCandidate.mCorrectedBackPvs - parentPvs;
 }
 
@@ -730,8 +759,8 @@
 
 	
-	if (data.mProbability <= mTermMinProbability)
+	/*if (data.mProbability <= mTermMinProbability)
 	{
 		++ mBvhStats.minProbabilityNodes;
-	}
+	}*/
 
 	////////////////////////////////////////////
@@ -2167,5 +2196,5 @@
 	// create bvh traversal data
 	BvhTraversalData oData(bvhLeaf, 0, prop, nRays);
-
+	
 	// create sorted object lists for the first data
 	if (mUseGlobalSorting)
@@ -2178,11 +2207,16 @@
 	//-- add first candidate for object space partition	
 
+	mTotalCost = EvalRenderCost(objects);
+	mPvsEntries = CountViewCells(objects);
+
+	oData.mCorrectedPvs = oData.mPvs = mPvsEntries;
+	oData.mCorrectedRenderCost = oData.mRenderCost = mTotalCost;
+	cout << "here52 " << oData.mCorrectedPvs << " " << oData.mRenderCost << " " << oData.mCorrectedRenderCost << endl;
+
+
 	BvhSubdivisionCandidate *oSubdivisionCandidate = 
 		new BvhSubdivisionCandidate(oData);
 
 	bvhLeaf->SetSubdivisionCandidate(oSubdivisionCandidate);
-
-	mTotalCost = EvalRenderCost(objects);
-	mPvsEntries = CountViewCells(objects);
 
 	if (mApplyInitialPartition)
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1903)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1912)
@@ -382,8 +382,11 @@
 		mNode(NULL),
 		mDepth(0),
-		mProbability(0.0),
 		mMaxCostMisses(0), 
 		mAxis(0),
-		mNumRays(0)
+		mNumRays(0),
+		mCorrectedPvs(0),
+		mPvs(0),
+		mCorrectedRenderCost(0),
+		mRenderCost(0)
 		{
 			for (int i = 0; i < 4; ++ i)
@@ -397,9 +400,11 @@
 		mNode(node), 
 		mDepth(depth),
-		//mBoundingBox(box),
-		mProbability(v),
 		mMaxCostMisses(0),
 		mAxis(0),
-		mNumRays(numRays)
+		mNumRays(numRays),
+		mCorrectedPvs(0),
+		mPvs(0),
+		mCorrectedRenderCost(0),
+		mRenderCost(v)
 		{
 			for (int i = 0; i < 4; ++ i)
@@ -420,8 +425,8 @@
 		/// current depth
 		int mDepth;
-		/// the probability that this node is seen
-		float mProbability;
-		/// the bounding box of the node
-		//AxisAlignedBox3 mBoundingBox;
+		/// the render cost of the node
+		float mRenderCost;
+		/// the corrected render cost;
+		float mCorrectedRenderCost;
 		/// how often this branch has missed the max-cost ratio
 		int mMaxCostMisses;
@@ -430,4 +435,9 @@
 		/// number of rays
 		int mNumRays;
+		/// parent Pvs;
+		float mPvs;
+		/// parent pvs correction factor
+		float mCorrectedPvs;
+
 		/// the sorted objects for the three dimensions
 		ObjectContainer *mSortedObjects[4];		
@@ -486,4 +496,6 @@
 			return mPriority;
 		}
+
+		/////////////////////////////7
 
 		/// pointer to parent tree.
@@ -496,4 +508,10 @@
 		/// the objects on the back of the potential split
 		ObjectContainer mBackObjects;
+			
+		float mCorrectedFrontPvs;
+		float mCorrectedBackPvs;
+
+		float mCorrectedFrontCost;
+		float mCorrectedBackCost;
 	};
 
@@ -821,5 +839,5 @@
 	/** Evaluates increase in pvs size.
 	*/
-	int EvalPvsEntriesIncr(BvhSubdivisionCandidate &splitCandidate) const;
+	int EvalPvsEntriesIncr(BvhSubdivisionCandidate &splitCandidate, const float avgRayContri) const;
 
 	/** Rays will be clipped to the bounding box.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1911)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1912)
@@ -724,8 +724,9 @@
 		
 		// create new interior node and two leaf node
-		const AxisAlignedPlane splitPlane = sc->mSplitPlane;
 		const int maxCostMisses = sc->GetMaxCostMisses();
 
-		newNode = SubdivideNode(splitPlane, tData, tFrontData, tBackData);
+		newNode = SubdivideNode(*sc,
+								tFrontData, 
+								tBackData);
 	
 		// how often was max cost ratio missed in this branch?
@@ -832,11 +833,19 @@
 	
 	VspLeaf *leaf = dynamic_cast<VspLeaf *>(splitCandidate.mParentData.mNode);
-	
+
+	/////////////
+	// avg ray contri
+
+	const int pvs = EvalPvsEntriesSize(*splitCandidate.mParentData.mRays);
+
+	const float avgRayContri = (float)pvs / 
+		((float)splitCandidate.mParentData.mRays->size() + Limits::Small);
+
+	splitCandidate.SetAvgRayContribution(avgRayContri);
+	cout << "vsp avg ray contri: " << avgRayContri << endl;
+
 	// compute global decrease in render cost
 	float oldRenderCost;
-	const float renderCostDecr = EvalRenderCostDecrease(splitCandidate.mSplitPlane, 
-														splitCandidate.mParentData,
-														oldRenderCost);
-
+	const float renderCostDecr = EvalRenderCostDecrease(splitCandidate, oldRenderCost);
 	splitCandidate.SetRenderCostDecrease(renderCostDecr);
 
@@ -854,18 +863,4 @@
 	{
 		priority /= ((float)splitCandidate.GetPvsEntriesIncr() + mMemoryConst);
-	}
-
-
-	/////////////
-	// avg ray contri
-
-	if (USE_AVGRAYCONTRI)
-	{
-		const int pvs = EvalPvsEntriesSize(*splitCandidate.mParentData.mRays);
-
-		const float avgRayContri = (float)pvs / 
-			((float)splitCandidate.mParentData.mRays->size() + Limits::Small);
-
-		splitCandidate.SetAvgRayContribution(avgRayContri);
 	}
 
@@ -904,15 +899,36 @@
 	}
 
-	return (int)(fPvsSize + bPvsSize - oldPvsSize);
-}
-
-
-VspInterior *VspTree::SubdivideNode(const AxisAlignedPlane &splitPlane,
-									VspTraversalData &tData,
+	const float oldPvsRatio = oldPvsSize / splitCandidate.mParentData.mPvs;
+	const float correctedOldPvs = splitCandidate.mParentData.mCorrectedPvs * oldPvsRatio;
+
+	cout <<"here102 "<< endl;
+	cout << "old pvs ratio: " << oldPvsRatio << endl;
+	const float correctedFrontPvs = 
+		mHierarchyManager->EvalCorrectedPvs(fPvsSize, 
+											correctedOldPvs, 
+											splitCandidate.GetAvgRayContribution());
+	cout <<"here103 "<< endl;
+	const float correctedBackPvs = 
+		mHierarchyManager->EvalCorrectedPvs(bPvsSize, 
+											correctedOldPvs, 
+											splitCandidate.GetAvgRayContribution());
+
+	
+	cout << "vsp front entries " << fPvsSize << " corrected: " << correctedFrontPvs << endl;
+	cout << "vsp back entries " << bPvsSize << " corrected: " << correctedBackPvs << endl;
+
+	return (int)(correctedFrontPvs + correctedBackPvs - correctedOldPvs);
+}
+
+
+VspInterior *VspTree::SubdivideNode(const VspSubdivisionCandidate &sc,
 									VspTraversalData &frontData,
 									VspTraversalData &backData)
 {
-	VspLeaf *leaf = dynamic_cast<VspLeaf *>(tData.mNode);
-	
+	VspLeaf *leaf = dynamic_cast<VspLeaf *>(sc.mParentData.mNode);
+
+	const VspTraversalData &tData = sc.mParentData;
+	const AxisAlignedPlane splitPlane = sc.mSplitPlane;
+
 	///////////////
 	//-- new traversal values
@@ -928,7 +944,11 @@
 
 	//-- compute pvs
-	frontData.mPvs = EvalPvsCost(*frontData.mRays);
-	backData.mPvs = EvalPvsCost(*backData.mRays);
-		
+	frontData.mPvs = (float)EvalPvsEntriesSize(*frontData.mRays);
+	backData.mPvs = (float)EvalPvsEntriesSize(*backData.mRays);
+	
+	//-- compute pvs correction for coping with undersampling
+	frontData.mCorrectedPvs = sc.mCorrectedFrontPvs;
+	backData.mCorrectedPvs = sc.mCorrectedBackPvs;
+
 	//-- split front and back node geometry and compute area
 	tData.mBoundingBox.Split(splitPlane.mAxis, 
@@ -940,4 +960,10 @@
 	backData.mProbability = tData.mProbability - frontData.mProbability;
 
+	//-- compute render cost
+	frontData.mRenderCost = (float)EvalRenderCost(*frontData.mRays);
+	backData.mRenderCost = (float)EvalRenderCost(*backData.mRays);
+	
+	frontData.mCorrectedRenderCost = sc.mCorrectedFrontPvs;
+	backData.mCorrectedRenderCost = sc.mCorrectedBackPvs;
 
 	////////
@@ -1519,8 +1545,6 @@
 
 
-float VspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane,
-									  const VspTraversalData &tData,
-									  float &normalizedOldRenderCost,
-									  const float avgRayContri) const
+float VspTree::EvalRenderCostDecrease(VspSubdivisionCandidate &sc,
+									  float &normalizedOldRenderCost) const
 {
 	float pvsFront = 0;
@@ -1529,4 +1553,8 @@
 
 	const float viewSpaceVol = mBoundingBox.GetVolume();
+	const VspTraversalData &tData = sc.mParentData;
+	
+	const AxisAlignedPlane &candidatePlane = sc.mSplitPlane;
+	const float avgRayContri = sc.GetAvgRayContribution();
 
 	//////////////////////////////////////////////
@@ -1537,7 +1565,7 @@
 	KdLeaf::NewMail(3);
 
-	RayInfoContainer::const_iterator rit, rit_end = data.mRays->end();
-
-	for (rit = data.mRays->begin(); rit != rit_end; ++ rit)
+	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
+
+	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
 	{
 		RayInfo rayInf = *rit;
@@ -1563,11 +1591,11 @@
 	AxisAlignedBox3 backBox;
 
-	data.mBoundingBox.Split(candidatePlane.mAxis, 
-							candidatePlane.mPosition, 
-							frontBox, 
-							backBox);
-
-	// probability that view point lies in back / front node
-	float pOverall = data.mProbability;
+	tData.mBoundingBox.Split(candidatePlane.mAxis, 
+							 candidatePlane.mPosition, 
+							 frontBox, 
+							 backBox);
+
+    // probability that view point lies in back / front node
+	float pOverall = tData.mProbability;
 	float pFront = frontBox.GetVolume();
 	float pBack = pOverall - pFront;
@@ -1576,21 +1604,19 @@
 	///////////////////
 	//-- evaluate render cost heuristics
-#if 0
-	const float penaltyOld = totalPvs;
-
-    const float penaltyFront = pvsFront;
-	const float penaltyBack = pvsBack;
-#else
-	const float penaltyOld = totalPvs * tData.mPvsCorrectionFactor;
-
-	const float frontCorr = mHierarchyManager->EvalPvsCorrectionFactor(pvsFront, penaltyOld, avgRayContri);
-	const float backCorr = mHierarchyManager->EvalPvsCorrectionFactor(pvsBack, penaltyOld, avgRayContri);
-
-	const float penaltyFront = frontCorr;
-	const float penaltyBack = pvsBack * backCorr;;
-#endif
+
+	const float oldRenderCostRatio = tData.mPvs ? (totalPvs / tData.mPvs) : 1;
+
+	const float penaltyOld = tData.mCorrectedPvs * oldRenderCostRatio;
+
+	cout <<"here107 " << penaltyOld << endl;
+	sc.mCorrectedFrontPvs = mHierarchyManager->EvalCorrectedPvs(pvsFront, penaltyOld, avgRayContri);
+	cout <<"here108 " << tData.mCorrectedPvs << " " << oldRenderCostRatio << endl;
+	sc.mCorrectedBackPvs = mHierarchyManager->EvalCorrectedPvs(pvsBack, penaltyOld, avgRayContri);
+
+	cout << "vsp front pvs " << pvsFront << " corrected: " << sc.mCorrectedFrontPvs << endl;
+	cout << "vsp back pvs " << pvsBack << " corrected: " << sc.mCorrectedBackPvs << endl;
 
 	const float oldRenderCost = pOverall * penaltyOld;
-	const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack;
+	const float newRenderCost = sc.mCorrectedFrontPvs * pFront + sc.mCorrectedBackPvs * pBack;
 
 	// we also return the old render cost
@@ -1612,5 +1638,5 @@
 
 
-float VspTree::EvalLocalSplitCost(const VspTraversalData &data,
+float VspTree::EvalLocalSplitCost(const VspTraversalData &tData,
 								  const AxisAlignedBox3 &box,
 								  const int axis,
@@ -1627,9 +1653,8 @@
 	KdLeaf::NewMail(3);
 
-	const float pvsSize = data.mPvs;
-	RayInfoContainer::const_iterator rit, rit_end = data.mRays->end();
+	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
 
 	// this is the main ray classification loop!
-	for(rit = data.mRays->begin(); rit != rit_end; ++ rit)
+	for(rit = tData.mRays->begin(); rit != rit_end; ++ rit)
 	{
 		VssRay *ray = (*rit).mRay;
@@ -1645,5 +1670,6 @@
 	//////////////
 	//-- evaluate cost heuristics
-	float pOverall = data.mProbability;
+
+	float pOverall = tData.mProbability;
 
 	// we use spatial mid split => simplified computation
@@ -1651,5 +1677,5 @@
 	
 	const float newCost = pvsBack * pBack + pvsFront * pFront;
-	const float oldCost = (float)pvsSize * pOverall + Limits::Small;
+	const float oldCost = (float)pvsTotal * pOverall + Limits::Small;
 	
 #ifdef GTPGTP_DEBUG
@@ -2921,4 +2947,7 @@
 #endif
 
+	mTotalCost = vData.mCorrectedPvs = pvsCost;
+	mPvsEntries = EvalPvsEntriesSize(rays);
+
 	//////////////
 	//-- create the first split candidate
@@ -2927,7 +2956,4 @@
     EvalSubdivisionCandidate(*splitCandidate);
 	leaf->SetSubdivisionCandidate(splitCandidate);
-
-	mTotalCost = pvsCost;
-	mPvsEntries = EvalPvsEntriesSize(rays);
 
 	EvalSubdivisionStats(*splitCandidate);
@@ -3333,5 +3359,4 @@
 		// create new interior node and two leaf node
 		const AxisAlignedPlane splitPlane = oldInterior->GetPlane();
-	
 		sc->mSplitPlane = splitPlane;
 	
@@ -3339,5 +3364,5 @@
 		EvalSubdivisionCandidate(*sc, false);
 
-		newNode = SubdivideNode(splitPlane, tData, tFrontData, tBackData);
+		newNode = SubdivideNode(*sc, tFrontData, tBackData);
 	
 		//oldNode->mRenderCostDecr += sc->GetRenderCostDecrease();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1911)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1912)
@@ -156,4 +156,7 @@
 		"Hierarchy.Construction.maxAvgRayContri", mMaxAvgRayContri);
 
+	Environment::GetSingleton()->GetFloatValue(
+		"Hierarchy.Construction.minAvgRayContri", mMinAvgRayContri);
+
 	// for comparing it with byte - value
 	mTermMaxMemory *= (1024.0f * 1024.0f);
@@ -734,24 +737,24 @@
 
 
-float HierarchyManager::EvalPvsCorrectionFactor(const float childPvs, 
-												const float totalPvs, 
-												const float avgRayContri) const
-{
-	if (!childPvs ||
-		// assume pvs sampled sufficiently => take child pvs
-		(avgRayContri < mMinAvgRayContri))
-		return 1.0f;
+float HierarchyManager::EvalCorrectedPvs(const float childPvs, 
+										 const float totalPvs, 
+										 const float avgRayContri) const
+{
+	// assume pvs sampled sufficiently => take child pvs
+	if (avgRayContri < mMinAvgRayContri)
+		return childPvs;
 
 	// assume pvs not sampled sufficiently => take total pvs
 	if (avgRayContri > mMaxAvgRayContri)
-		return totalPvs / childPvs;
-
-	const float factor = 
-			(mMaxAvgRayContri - avgRayContri) / 
-			(mMaxAvgRayContri - mMinAvgRayContri);
-
-	const float newPvs = factor * childPvs + (1.0f - factor) * totalPvs;	
-	
-	return newPvs / childPvs;
+		return totalPvs;
+
+	const float alpha = (mMaxAvgRayContri - avgRayContri) / 
+						(mMaxAvgRayContri - mMinAvgRayContri);
+
+	cout << "here41 **************** " << alpha << " " << childPvs << " " << totalPvs << endl;
+
+	const float beta = (1.0f - alpha) * (totalPvs + childPvs) / totalPvs;
+
+	return childPvs + beta;
 }
 
