Index: GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 2233)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/TestPreprocessor.vcproj	(revision 2237)
@@ -253,5 +253,5 @@
 			ConfigurationType="1"
 			CharacterSet="2"
-			WholeProgramOptimization="FALSE">
+			WholeProgramOptimization="TRUE">
 			<Tool
 				Name="VCCLCompilerTool"
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 2233)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.vcproj	(revision 2237)
@@ -271,4 +271,5 @@
 				InlineFunctionExpansion="2"
 				EnableIntrinsicFunctions="TRUE"
+				ImproveFloatingPointConsistency="TRUE"
 				FavorSizeOrSpeed="1"
 				OmitFramePointers="TRUE"
@@ -1168,8 +1169,8 @@
 			</File>
 			<File
+				RelativePath=".\sparsehash\src\google\sparsehash\hash_fun.h">
+			</File>
+			<File
 				RelativePath=".\sparsehash\src\windows\hash_fun.h">
-			</File>
-			<File
-				RelativePath=".\sparsehash\src\google\sparsehash\hash_fun.h">
 			</File>
 			<File
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.h	(revision 2234)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.h	(revision 2237)
@@ -3,9 +3,10 @@
 
 #include <vector>
+#include "VssRay.h"
 
 
 namespace GtpVisibilityPreprocessor {
 
-class VssRay;
+//class VssRay;
 class RayInfo;
 class Plane3;
@@ -58,16 +59,16 @@
 	/** Extracts the starting point of the ray segment.
 	*/
-	Vector3 ExtrapOrigin() const;
+	inline Vector3 ExtrapOrigin() const;
 	
 	/** Extracts the end point of the ray segment.
 	*/
-	Vector3 ExtrapTermination() const;
+	inline Vector3 ExtrapTermination() const;
 	
-	float GetMinT () const;
-	float GetMaxT () const;
+	inline float GetMinT () const;
+	inline float GetMaxT () const;
 	
-	void SetMinT (const float t);
+	inline void SetMinT (const float t);
 	
-	void SetMaxT (const float t);
+	inline void SetMaxT (const float t);
 
 	float SegmentLength() const;
@@ -99,4 +100,25 @@
 };
 
+		
+float RayInfo::ExtrapOrigin(const int axis) const 
+{
+	return mRay->GetOrigin(axis) + GetMinT() * mRay->GetDir(axis);
+}
+		
+float RayInfo::ExtrapTermination(const int axis) const 
+{
+	return mRay->GetOrigin(axis) + GetMaxT() * mRay->GetDir(axis);
+}
+
+Vector3 RayInfo::ExtrapOrigin() const 
+{
+	return mRay->GetOrigin() + GetMinT() * mRay->GetDir();
+}
+		
+Vector3 RayInfo::ExtrapTermination() const 
+{
+	return mRay->GetOrigin() + GetMaxT() * mRay->GetDir();
+}
+
 }
 #endif 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 2233)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 2237)
@@ -46,5 +46,5 @@
 
 
-#define COUNT_ORIGIN_OBJECTS 0
+#define COUNT_ORIGIN_OBJECTS 1
 #define USE_AVGRAYCONTRI 0
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 2233)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 2237)
@@ -801,5 +801,8 @@
 	*/
 	float EvalRenderCostDecrease(VspSubdivisionCandidate &splitData, 
-								 float &normalizedOldRenderCost) const;
+								 float &normalizedOldRenderCost,
+								 const float totalPvs,
+								 const float pvsFront,
+								 const float pvsBack) const;
 
 	/** Collects view cells in the subtree under root.
@@ -890,5 +893,8 @@
 	float EvalPvsCost(const RayInfoContainer &rays) const;
 
-	int EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate) const;
+	int EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate,
+						   const int oldPvsSize,
+						   const int fPvsSize,
+						   const int bPvsSize) const;
 
 	/** Returns number of effective entries in the pvs.
@@ -919,17 +925,17 @@
 	/** Evaluates contribution of min event to pvs
 	*/
-	inline int EvalMinEventContribution(const VssRay &ray, const bool isTermination) const;
+	inline float EvalMinEventContribution(const VssRay &ray, const bool isTermination) const;
 
 	/** Evaluates contribution of max event to pvs
 	*/
-	inline int EvalMaxEventContribution(const VssRay &ray, const bool isTermination) const;
+	inline float EvalMaxEventContribution(const VssRay &ray, const bool isTermination) const;
 
 	/** Evaluates contribution of kd leaf when encountering a min event
 	*/
-	inline int EvalMinEventContribution(KdLeaf *leaf) const;
+	inline float EvalMinEventContribution(KdLeaf *leaf) const;
 
 	/**  Evaluates contribution of kd leaf when encountering a max event
 	*/
-	inline int EvalMaxEventContribution(KdLeaf *leaf) const;
+	inline float EvalMaxEventContribution(KdLeaf *leaf) const;
 
 	/** Prepares objects for the heuristics.
@@ -1011,4 +1017,9 @@
 		const bool countEntries) const;
 
+	inline void UpdateContributionsToPvs(BvhLeaf *leaf,
+										 const int cf,
+										 float &frontPvs, float &backPvs, float &totalPvs,
+										 int &frontSize, int &backSize, int &totalSize) const;
+
 	/** Evaluates the contribution for kd leaves.
 	*/
@@ -1085,9 +1096,9 @@
 	/** Evaluates pvs contribution of this ray.
 	*/
-	int EvalContributionToPvs(const VssRay &ray, const bool isTermination) const;
+	float EvalContributionToPvs(const VssRay &ray, const bool isTermination) const;
 
 	/** Evaluates pvs contribution of a kd node.
 	*/
-	int EvalContributionToPvs(KdLeaf *leaf) const;
+	float EvalContributionToPvs(KdLeaf *leaf) const;
 
 	/** Creates new root of hierarchy and computes bounding box.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 2233)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 2237)
@@ -1812,4 +1812,5 @@
 		if (ray->mOriginObject)
 		{
+			cout << "o";
 			ray->mOriginObject->GetOrCreateRays()->push_back(ray);
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.cpp	(revision 2176)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RayInfo.cpp	(revision 2237)
@@ -46,24 +46,5 @@
 	SetMinT(_min);
 }
-		
-float RayInfo::ExtrapOrigin(const int axis) const 
-{
-	return mRay->GetOrigin(axis) + GetMinT() * mRay->GetDir(axis);
-}
-		
-float RayInfo::ExtrapTermination(const int axis) const 
-{
-	return mRay->GetOrigin(axis) + GetMaxT() * mRay->GetDir(axis);
-}
 
-Vector3 RayInfo::ExtrapOrigin() const 
-{
-	return mRay->GetOrigin() + GetMinT() * mRay->GetDir();
-}
-		
-Vector3 RayInfo::ExtrapTermination() const 
-{
-	return mRay->GetOrigin() + GetMaxT() * mRay->GetDir();
-}
 
 #if USE_FIXEDPOINT_T
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 2233)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 2237)
@@ -32,4 +32,6 @@
 #define VISUALIZE_SPLIT 0
 #define USE_FIXEDPOINT_T 0
+#define HACK_PERFORMANCE 1
+
 
 /////////////
@@ -513,4 +515,5 @@
 	//////////////////////////////////////////////
 	// bounding box of view space includes all visibility events
+
 	mBoundingBox.Initialize();
 	VssRayContainer::const_iterator rit, rit_end = rays.end();
@@ -802,10 +805,63 @@
 	VspLeaf *leaf = static_cast<VspLeaf *>(splitCandidate.mParentData.mNode);
 
+		//////////////
+	//-- compute global decrease in render cost
+
+	const AxisAlignedPlane candidatePlane = splitCandidate.mSplitPlane;
+
+	RayInfoContainer::const_iterator rit, rit_end = splitCandidate.mParentData.mRays->end();
+
+	float frontRenderCost = 0, backRenderCost = 0, totalRenderCost = 0;
+	int  frontSize = 0, backSize = 0, totalSize = 0;
+
+	Intersectable::NewMail(3);
+	KdLeaf::NewMail(3);
+
+	for (rit = splitCandidate.mParentData.mRays->begin(); rit != rit_end; ++ rit)
+	{
+		RayInfo rayInf = *rit;
+
+		float t;
+		
+		// classify ray
+		const int cf = rayInf.ComputeRayIntersection(candidatePlane.mAxis, 
+													 candidatePlane.mPosition, 
+													 t);
+
+		VssRay *ray = rayInf.mRay;
+#if HACK_PERFORMANCE
+		Intersectable *obj = (*ray).mTerminationObject;
+
+		BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
+
+		// evaluate contribution of ray endpoint to front 
+		// and back pvs with respect to the classification
+		UpdateContributionsToPvs(leaf, cf, 
+								 frontRenderCost, backRenderCost, totalRenderCost),
+								 frontSize, backSize, totalSize;
+
+#if COUNT_ORIGIN_OBJECTS
+
+		obj = (*ray).mOriginObject;
+
+		if (obj)
+		{
+			leaf = mBvHierarchy->GetLeaf(obj);
+
+			UpdateContributionsToPvs(leaf, cf, 
+									 frontRenderCost, backRenderCost, totalRenderCost,
+									 frontSize, backSize, totalSize);
+		}
+#endif
+
+#else
+		cerr << "TODO classify" << endl;
+#endif
+	}
+
 	/////////////
 	// avg ray contri
 
-	const int pvs = EvalPvsEntriesSize(*splitCandidate.mParentData.mRays);
-
-	const float avgRayContri = (float)pvs / 
+	const float avgRayContri = (float)totalSize / 
 		((float)splitCandidate.mParentData.mRays->size() + Limits::Small);
 
@@ -813,16 +869,17 @@
 
 	const float avgRaysPerObject = 
-		(float)splitCandidate.mParentData.mRays->size() / ((float)pvs + Limits::Small);
+		(float)splitCandidate.mParentData.mRays->size() / ((float)totalSize + Limits::Small);
 
 	splitCandidate.SetAvgRayContribution(avgRayContri);
 	splitCandidate.SetAvgRaysPerObject(avgRaysPerObject);
 
-	// compute global decrease in render cost
+
 	float oldRenderCost;
-	const float renderCostDecr = EvalRenderCostDecrease(splitCandidate, oldRenderCost);
+	const float renderCostDecr = EvalRenderCostDecrease(splitCandidate, oldRenderCost,
+														 totalRenderCost, frontRenderCost, backRenderCost);
 	splitCandidate.SetRenderCostDecrease(renderCostDecr);
 
 	// the increase in pvs entries num induced by this split
-	const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate);
+	const int pvsEntriesIncr = EvalPvsEntriesIncr(splitCandidate, totalSize, frontSize, backSize);
 	splitCandidate.SetPvsEntriesIncr(pvsEntriesIncr);
 
@@ -844,33 +901,11 @@
 
 
-int VspTree::EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate) const
-{
-	float oldPvsSize = 0;
-	float fPvsSize = 0;
-	float bPvsSize = 0;
-	
-	const AxisAlignedPlane candidatePlane = splitCandidate.mSplitPlane;
-	
-	Intersectable::NewMail(3);
-	KdLeaf::NewMail(3);
-
+int VspTree::EvalPvsEntriesIncr(VspSubdivisionCandidate &splitCandidate,
+								const float oldPvsSize,
+								const float fPvsSize,
+								const float bPvsSize) const
+{
+	
 	RayInfoContainer::const_iterator rit, rit_end = splitCandidate.mParentData.mRays->end();
-
-    // this is the main ray classification loop!
-	for(rit = splitCandidate.mParentData.mRays->begin(); rit != rit_end; ++ rit)
-	{
-		VssRay *ray = (*rit).mRay;
-		RayInfo rayInf = *rit;
-		
-		float t;
-		// classify ray
-		const int cf = 	rayInf.ComputeRayIntersection(candidatePlane.mAxis, 
-													  candidatePlane.mPosition, t);
-
-		UpdatePvsEntriesContribution(*ray, true, cf, fPvsSize, bPvsSize, oldPvsSize);
-#if COUNT_ORIGIN_OBJECTS
-		UpdatePvsEntriesContribution(*ray, false, cf, fPvsSize, bPvsSize, oldPvsSize);
-#endif
-	}
 
 	const float oldPvsRatio = (splitCandidate.mParentData.mPvs > 0) ? 
@@ -1188,12 +1223,12 @@
 
 
-int VspTree::EvalMaxEventContribution(KdLeaf *leaf) const
-{
-	int pvs = 0;
+float VspTree::EvalMaxEventContribution(KdLeaf *leaf) const
+{
+	float pvs = 0;
 
 	// leaf falls out of right pvs
 	if (-- leaf->mCounter == 0)
 	{
-		pvs -= ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
+		pvs -= ((float)leaf->mObjects.size() - (float)leaf->mMultipleObjects.size());
 	}
 
@@ -1217,5 +1252,5 @@
 
 
-int VspTree::EvalMinEventContribution(KdLeaf *leaf) const
+float VspTree::EvalMinEventContribution(KdLeaf *leaf) const
 {
 	if (leaf->Mailed())
@@ -1225,5 +1260,5 @@
 
 	// add objects without those which are part of several kd leaves
-	int pvs = ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
+	float pvs = ((float)leaf->mObjects.size() - (float)leaf->mMultipleObjects.size());
 
 	// separately handle objects which are part of several kd leaves 
@@ -1644,10 +1679,9 @@
 
 float VspTree::EvalRenderCostDecrease(VspSubdivisionCandidate &sc,
-									  float &normalizedOldRenderCost) const
-{
-	float pvsFront = 0;
-	float pvsBack = 0;
-	float totalPvs = 0;
-
+									  float &normalizedOldRenderCost,
+									  const float totalPvs,
+									  const float pvsFront,
+									  const float pvsBack) const
+{
 	const float viewSpaceVol = mBoundingBox.GetVolume();
 	const VspTraversalData &tData = sc.mParentData;
@@ -1663,28 +1697,4 @@
 	Intersectable::NewMail(3);
 	KdLeaf::NewMail(3);
-
-	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
-
-	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
-	{
-		RayInfo rayInf = *rit;
-
-		float t;
-		
-		// classify ray
-		const int cf = rayInf.ComputeRayIntersection(candidatePlane.mAxis, 
-													 candidatePlane.mPosition, 
-													 t);
-
-		VssRay *ray = rayInf.mRay;
-
-		// evaluate contribution of ray endpoint to front 
-		// and back pvs with respect to the classification
-		UpdateContributionsToPvs(*ray, true, cf, pvsFront, pvsBack, totalPvs);
-
-#if COUNT_ORIGIN_OBJECTS
-		UpdateContributionsToPvs(*ray, false, cf, pvsFront, pvsBack, totalPvs);
-#endif
-	}
     
 	AxisAlignedBox3 frontBox;
@@ -1802,5 +1812,5 @@
 	if (!obj) return;
 
-	const float renderCost = mViewCellsManager->EvalRenderCost(obj);
+	const float renderCost = ViewCellsManager::EvalRenderCost(obj);
 
 	// object in none of the pvss => new object
@@ -1881,4 +1891,54 @@
 			backPvs += renderCost;
 		
+			// already in front pvs => in both pvss
+			if (leaf->Mailed())
+				leaf->Mail(2);
+			else
+				leaf->Mail(1);
+		}
+	}
+}
+
+
+void VspTree::UpdateContributionsToPvs(BvhLeaf *leaf,
+									   const int cf,
+									   float &frontPvs,
+									   float &backPvs,
+									   float &totalPvs,
+									   int &frontSize,
+									   int &backSize,
+									   int &totalSize) const
+{
+	const float renderCost = mBvHierarchy->EvalAbsCost(leaf->mObjects);
+	
+	// leaf in no pvs => new
+	if (!leaf->Mailed() && !leaf->Mailed(1) && !leaf->Mailed(2))
+	{
+		totalPvs += renderCost;
+		++ totalSize;
+	}
+
+	if (cf >= 0) // front pvs
+	{
+		if (!leaf->Mailed() && !leaf->Mailed(2))
+		{
+			frontPvs += renderCost;
+			++ frontSize;
+
+			// already in back pvs => in both pvss
+			if (leaf->Mailed(1))
+				leaf->Mail(2);
+			else
+				leaf->Mail();
+		}
+	}
+
+	if (cf <= 0) // back pvs
+	{
+		if (!leaf->Mailed(1) && !leaf->Mailed(2))
+		{
+			backPvs += renderCost;
+			++ backSize;
+
 			// already in front pvs => in both pvss
 			if (leaf->Mailed())
@@ -2379,8 +2439,10 @@
 
 {
-	
+
 #if HACK_PERFORMANCE
-	
-	BvhLeaf *bvhleaf = mBvHierarchy->GetLeaf(mTerminationObject);
+	Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 
+
+	if (!obj) return 0;
+	BvhLeaf *bvhleaf = mBvHierarchy->GetLeaf(obj);
 
 	if (!bvhleaf->Mailed())
@@ -2389,11 +2451,13 @@
 		return 1;
 	}
+
 #else
+
 	Intersectable *obj; 
-	Vector3 pt;
+	static Vector3 pt;
 	KdNode *node;
 
 	ray.GetSampleData(isTermination, pt, &obj, &node);
-
+	
 	if (!obj) return 0;
 
@@ -2961,22 +3025,40 @@
 	Intersectable::NewMail();
 
+	////////////////
 	//-- store rays and objects
+	
+	VssRay *lastVssRay = NULL;
+
 	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
 	{
 		VssRay *ray = *rit;
-		float minT, maxT;
-		static Ray hray;
-
-		hray.Init(*ray);
+
+		// filter out double rays (last ray the same as this ray
+		if (!lastVssRay ||
+			!(ray->mOrigin == lastVssRay->mTermination) ||
+			!(ray->mTermination == lastVssRay->mOrigin)) 
+		{
+			lastVssRay = ray;
+
+			float minT, maxT;
+			static Ray hray;
+
+			hray.Init(*ray);
 		
-		// TODO: not very efficient to implictly cast between rays types
-		if (GetBoundingBox().GetRaySegment(hray, minT, maxT))
-		{
-			float len = ray->Length();
-
-			if (!len)
-				len = Limits::Small;
-
-			rays.push_back(RayInfo(ray, minT / len, maxT / len));
+			// TODO: not very efficient to implictly cast between rays types
+			if (GetBoundingBox().GetRaySegment(hray, minT, maxT))
+			{
+				const float len = ray->Length();
+
+				if (len) // ray not degenerate 
+				{	//len = Limits::Small;
+					rays.push_back(RayInfo(ray, minT / len, maxT / len));
+				}
+			}
+		}
+		else
+		{
+			// store object only for one ray
+			lastVssRay->mOriginObject = ray->mTerminationObject;
 		}
 	}
@@ -3086,7 +3168,11 @@
 #if HACK_PERFORMANCE
 
+	Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 
+
+	if (!obj) return;
+
+	BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
+
 	SubdivisionCandidate *candidate;
-
-	BvhLeaf *leaf = mBvHierarchy->GetLeaf(ray.mTerminationObject);
 
 	if (!leaf->Mailed())
@@ -3164,5 +3250,5 @@
 	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
 
-	// add all kd nodes seen by the rays
+	// add all nodes seen by the rays
 	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
 	{
@@ -3170,23 +3256,28 @@
 		
 		CollectDirtyCandidate(*ray, true, dirtyList, onlyUnmailed);
+
+#if COUNT_ORIGIN_OBJECTS
         CollectDirtyCandidate(*ray, false, dirtyList, onlyUnmailed);
-	}
-}
-
-
-int VspTree::EvalMaxEventContribution(const VssRay &ray, 
+#endif
+	}
+}
+
+
+float VspTree::EvalMaxEventContribution(const VssRay &ray, 
 									  const bool isTermination) const
 {
-	int pvs = 0;
-
 #if HACK_PERFORMANCE
 
-	BvhLeaf *leaf = mBvHierarchy->GetLeaf(ray.mTerminationObject);
+	Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 
+
+	if (!obj) return 0.0f;
+
+	BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
 			
 	// simple render cost evaluation
 	if (-- leaf->mCounter == 0)
-		//pvs += (int)leaf->mObjects.size();
-		pvs += mBvHierarchy::EvalAbsCost((int)leaf->mObjects.size());
-
+		return BvHierarchy::EvalAbsCost(leaf->mObjects);
+	else
+		return 0.0f;
 #else
 
@@ -3197,5 +3288,7 @@
 	ray.GetSampleData(isTermination, pt, &obj, &node);
 
-	if (!obj) return 0;
+	if (!obj) return 0.0f;
+
+	float pvs = 0.0f;
 
 	switch (mHierarchyManager->GetObjectSpaceSubdivisionType())
@@ -3221,6 +3314,6 @@
 			// simple render cost evaluation
 			if (-- leaf->mCounter == 0)
-				pvs += (int)leaf->mObjects.size();
-				//pvs += (int)BvHierarchy::EvalAbsCost(leaf->mObjects);
+				//pvs += (int)leaf->mObjects.size();
+				pvs += BvHierarchy::EvalAbsCost(leaf->mObjects);
 			break;
 		}
@@ -3228,6 +3321,7 @@
 		break;
 	}
+	return pvs;
+
 #endif
-	return pvs;
 }
 
@@ -3235,20 +3329,29 @@
 float VspTree::PrepareHeuristics(const VssRay &ray, const bool isTermination)
 {
+	
+#if HACK_PERFORMANCE
+	
+	Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 
+
+	if (!obj) return 0.0f;
+
+	BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
+
+	if (!leaf->Mailed())
+	{
+		leaf->Mail();
+		leaf->mCounter = 1;
+		return BvHierarchy::EvalAbsCost(leaf->mObjects);
+	}
+	else
+	{
+		++ leaf->mCounter;	
+		return 0.0f;
+	}
+
+#else
+
 	float pvsSize = 0;
-	
-#if HACK_PERFORMANCE
-	BvhLeaf *leaf = mBvHierarchy->GetLeaf(ray.mTerminationObject);
-
-	if (!leaf->Mailed())
-	{
-		leaf->Mail();
-		leaf->mCounter = 0;
-		pvsSize += (int)leaf->mObjects.size();
-	}
-
-	++ leaf->mCounter;	
-
-#else
-	
+
 	Intersectable *obj;
 	Vector3 pt;
@@ -3257,5 +3360,5 @@
 	ray.GetSampleData(isTermination, pt, &obj, &node);
 
-	if (!obj) return 0;
+	if (!obj) return 0.0f;
 
 	switch (mHierarchyManager->GetObjectSpaceSubdivisionType())
@@ -3287,5 +3390,5 @@
 				leaf->Mail();
 				leaf->mCounter = 0;
-				pvsSize += (int)leaf->mObjects.size();
+				pvsSize += BvHierarchy::EvalAbsCost(leaf->mObjects);
 			}
 
@@ -3296,26 +3399,34 @@
 		break;
 	}
+	return pvsSize;
 #endif
-	return pvsSize;
-}
-
-
-int VspTree::EvalMinEventContribution(const VssRay &ray, 
-									  const bool isTermination) const
+	
+}
+
+
+float VspTree::EvalMinEventContribution(const VssRay &ray, 
+										const bool isTermination) const
 {
 #if HACK_PERFORMANCE
 
-	BvhLeaf *leaf = mBvHierarchy->GetLeaf(ray.mTerminationObject);
+	Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 
+
+	if (!obj) return 0.0f;
+
+	BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
 	
 	if (!leaf->Mailed())
 	{
 		leaf->Mail();
-		pvs += (int)leaf->mObjects.size();
-	}
-
+		return BvHierarchy::EvalAbsCost(leaf->mObjects);
+	}
+	else
+	{
+		return 0.0f;
+	}
 #else
 
 	Intersectable *obj;
-	Vector3 pt;
+	static Vector3 pt;
 	KdNode *node;
 
@@ -3324,5 +3435,5 @@
 	if (!obj) return 0;
 
-	int pvs = 0;
+	float pvs = 0.0f;
 
 	switch (mHierarchyManager->GetObjectSpaceSubdivisionType())
@@ -3350,5 +3461,5 @@
 			{
 				leaf->Mail();
-				pvs += (int)leaf->mObjects.size();
+				pvs += BvHierarchy->EvalAbsCost(leaf->mObjects);
 			}
 			break;
@@ -3357,6 +3468,7 @@
 		break;
 	}
+	return pvs;
+
 #endif
-	return pvs;
 }
 
@@ -3377,5 +3489,5 @@
 
 	Intersectable *obj;
-	Vector3 pt;
+	static Vector3 pt;
 	KdNode *node;
 
@@ -3421,9 +3533,8 @@
 	UpdateContributionsToPvs(leaf, cf, pvsFront, pvsBack, totalPvs, true);
 
-
 #else
 
 	Intersectable *obj;
-	Vector3 pt;
+	static Vector3 pt;
 	KdNode *node;
 
@@ -3443,6 +3554,8 @@
 		}
 	default:
-		UpdateContributionsToPvs(obj, cf, pvsFront, pvsBack, totalPvs);	
-		break;
+		{
+			UpdateContributionsToPvs(obj, cf, pvsFront, pvsBack, totalPvs);	
+			break;
+		}
 	}
 #endif
@@ -3450,22 +3563,29 @@
 
 
-int VspTree::EvalContributionToPvs(const VssRay &ray, const bool isTermination) const
+float VspTree::EvalContributionToPvs(const VssRay &ray, const bool isTermination) const
 {
 
 #if HACK_PERFORMANCE
-	int pvs = 0;
-
-	BvhLeaf *bvhleaf = mBvHierarchy->GetLeaf(ray.mTerminationObject);
-
-	if (!bvhleaf->Mailed())
-	{
-		bvhleaf->Mail();
-		pvs += (int)bvhleaf->mObjects.size();
+
+	Intersectable *obj = isTermination ? ray.mTerminationObject : ray.mOriginObject; 
+
+	if (!obj) return 0;
+
+	BvhLeaf *leaf = mBvHierarchy->GetLeaf(obj);
+
+	if (!leaf->Mailed())
+	{
+		leaf->Mail();
+		return BvHierarchy::EvalAbsCost(leaf->mObjects);
+	}
+	else
+	{
+		return 0.0f;
 	}
 
 #else
-		
+	
 	Intersectable *obj; 
-	Vector3 pt;
+	static Vector3 pt;
 	KdNode *node;
 
@@ -3474,5 +3594,5 @@
 	if (!obj) return 0;
 
-	int pvs = 0;
+	float pvs = 0.0f;
 
 	switch (mHierarchyManager->GetObjectSpaceSubdivisionType())
@@ -3500,5 +3620,5 @@
 			{
 				bvhleaf->Mail();
-				pvs += (int)bvhleaf->mObjects.size();
+				pvs += BvHierarchy::EvalAbsCost(bvhleaf->mObjects);
 			}
 			break;
@@ -3507,10 +3627,11 @@
 		break;
 	}
+	return pvs;
+
 #endif
-	return pvs;
-}
-
-
-int VspTree::EvalContributionToPvs(KdLeaf *leaf) const
+}
+
+
+float VspTree::EvalContributionToPvs(KdLeaf *leaf) const
 {
 	if (leaf->Mailed()) // leaf already mailed
@@ -3520,5 +3641,5 @@
 
 	// this is the pvs which is uniquely part of this kd leaf
-	int pvs = (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
+	float pvs = (float)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
 
 	ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 2233)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 2237)
@@ -544,4 +544,5 @@
 	///////////////
 	//-- create view space
+	
 	PrepareViewSpaceSubdivision(viewSpaceQueue, sampleRays, objects);
 
