Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1251)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1259)
@@ -18,5 +18,8 @@
 #include "KdTree.h"
 #include "KdIntersectable.h"
+#include "HierarchyManager.h"
+#include "BvHierarchy.h"
 #include "OspTree.h"
+
 
 namespace GtpVisibilityPreprocessor {
@@ -358,5 +361,5 @@
 mStoreRays(false),
 mTimeStamp(1),
-mOspTree(NULL)
+mHierarchyManager(NULL)
 {
 	bool randomize = false;
@@ -397,5 +400,5 @@
 	Environment::GetSingleton()->GetBoolValue("VspTree.simulateOctree", mCirculatingAxis);
 	
-	Environment::GetSingleton()->GetBoolValue("VspTree.useKdPvsForHeuristics", mUseKdPvsForHeuristics);
+	//Environment::GetSingleton()->GetBoolValue("VspTree.useKdPvsForHeuristics", mUseKdPvsForHeuristics);
 
 	char subdivisionStatsLog[100];
@@ -433,9 +436,4 @@
 	Debug << "maxband: " << mMaxBand << endl;
 
-	if (!mUseKdPvsForHeuristics)
-		Debug << "pvs heuristics: per object" << endl;
-	else
-		Debug << "pvs heuristics: per kd node" << endl;
-
 	mLocalSubdivisionCandidates = new vector<SortableEntry>;
 
@@ -911,43 +909,4 @@
 
 
-bool VspTree::AddKdLeafToPvs(KdLeaf *leaf, 
-							 ViewCell *vc, 
-							 const float pdf, 
-							 float &contribution)
-{
-	bool contri = false;
-
-#if 1 // add kd intersecable to pvs
-	KdIntersectable *kdObj = mOspTree->GetOrCreateKdIntersectable(leaf);
-	
-	if (vc->AddPvsSample(kdObj, pdf, contribution))
-	{
-		return true;
-	}
-
-#else // add all objects of kd node
-
-	contribution = 0;
-
-	ObjectContainer::const_iterator it, it_end = leaf->mObjects.end();
-
-	for (it = leaf->mObjects.begin(); it != it_end; ++ it)
-	{
-		Intersectable *object = *it;						
-
-		float newcontri;
-						
-		if (vc->AddPvsSample(object, pdf, newcontri))
-		{
-			contri = true;
-		}
-
-		//pdf += newPdf;
-		newContri += contribution;
-	}
-#endif
-
-	return contri;
-}
 
 
@@ -977,15 +936,11 @@
 		if (obj) 
 		{
-			if (!mStoreKdPvs)
-			{
-				// potentially visible objects
-				madeContrib = vc->AddPvsSample(obj, ray->mPdf, contribution);
-			}
-			else
-			{
-				// potentially visible kd cells
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);	
-				madeContrib = AddKdLeafToPvs(leaf, vc, ray->mPdf, contribution);
-			}	
+			madeContrib = 
+				mViewCellsManager->AddSampleToPvs(
+					obj, 
+					ray->mTermination, 
+					vc, 
+					ray->mPdf, 
+					contribution);
 
 			sc += contribution;
@@ -996,15 +951,11 @@
 		if (obj) 
 		{
-			if (!mStoreKdPvs)
-			{
-				// potentially visible objects
-				madeContrib = vc->AddPvsSample(obj, ray->mPdf, contribution);
-			}
-			else
-			{
-				// potentially visible kd cells
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);	
-				madeContrib = AddKdLeafToPvs(leaf, vc, ray->mPdf, contribution);
-			}	
+			madeContrib = 
+				mViewCellsManager->AddSampleToPvs(
+					obj,
+					ray->mOrigin, 
+					vc, 
+					ray->mPdf, 
+					contribution);
 
 			sc += contribution;
@@ -1092,4 +1043,65 @@
 
 
+int VspTree::PrepareHeuristics(const VssRay &ray, const bool isTermination)
+{
+	int pvsSize = 0;
+	
+	Intersectable *obj;
+	Vector3 pt;
+	KdNode *node;
+
+	ray.GetSampleData(isTermination, pt, &obj, &node);
+
+	if (!obj)
+		return 0;
+
+	switch (mHierarchyManager->GetObjectSpaceSubdivisonType())
+	{
+	case HierarchyManager::NO_OBJ_SUBDIV:
+		{
+			if (!obj->Mailed())
+			{
+				obj->Mail();
+				obj->mCounter = 1;
+
+				++ pvsSize;
+			}
+			else
+			{
+				++ obj->mCounter;
+			}
+			break;
+		}
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
+		{
+			KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);
+			pvsSize += PrepareHeuristics(leaf);	
+			break;
+		}
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj, NULL);
+
+			if (!leaf->Mailed())
+			{
+				leaf->Mail();
+				leaf->mCounter = 1;
+
+				++ pvsSize;
+			}
+			else
+			{
+				++ leaf->mCounter;
+			}
+			break;
+		}
+	default:
+		break;
+	}
+
+	return pvsSize;
+}
+
+
 int VspTree::PrepareHeuristics(KdLeaf *leaf)
 {	
@@ -1144,57 +1156,11 @@
 	RayInfoContainer::const_iterator ri, ri_end = rays.end();
 
-	//-- set all kd nodes / objects as belonging to the front pvs
-
+    // set all kd nodes / objects as belonging to the front pvs
 	for (ri = rays.begin(); ri != ri_end; ++ ri)
 	{
 		VssRay *ray = (*ri).mRay;
-		Intersectable *oObject = ray->mOriginObject;
-
-		if (oObject)
-		{
-			if (!mUseKdPvsForHeuristics)
-			{
-				if (!oObject->Mailed())
-				{
-					oObject->Mail();
-					oObject->mCounter = 1;
-
-					++ pvsSize;
-				}
-				else
-				{
-					++ oObject->mCounter;
-				}
-			}
-			else
-			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
-				pvsSize += PrepareHeuristics(leaf);	
-			}	
-		}
-
-		Intersectable *tObject = (*ri).mRay->mTerminationObject;
-
-		if (tObject)
-		{
-			if (!mUseKdPvsForHeuristics)
-			{
-				if (!tObject->Mailed())
-				{
-					tObject->Mail();
-					tObject->mCounter = 1;
-					++ pvsSize;
-				}
-				else
-				{
-					++ tObject->mCounter;
-				}
-			}
-			else
-			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
-				pvsSize += PrepareHeuristics(leaf);	
-			}	
-		}
+		
+		pvsSize += PrepareHeuristics(*ray, true);
+		pvsSize += PrepareHeuristics(*ray, false);
 	}
 
@@ -1203,6 +1169,8 @@
 
 
-void VspTree::RemoveContriFromPvs(KdLeaf *leaf, int &pvs) const
-{
+int VspTree::EvalMaxEventContribution(KdLeaf *leaf) const
+{
+	int pvs = 0;
+
 	// leaf falls out of right pvs
 	if (-- leaf->mCounter == 0)
@@ -1211,5 +1179,6 @@
 	}
 
-	//-- handle objects which are in several kd leaves separately 
+	//-- separately handle objects which are in several kd leaves
+
 	ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
 
@@ -1220,21 +1189,23 @@
 		if (-- object->mCounter == 0)
 		{
-			-- pvs;
-		}
-	}
-}
-
-
-void VspTree::AddContriToPvs(KdLeaf *leaf, int &pvs) const
+			++ pvs;
+		}
+	}
+
+	return pvs;
+}
+
+
+int VspTree::EvalMinEventContribution(KdLeaf *leaf) const
 {
 	if (leaf->Mailed())
-		return;
+		return 0;
 	
 	leaf->Mail();
 
 	// add objects without those which are part of several kd leaves
-	pvs += ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
-
-	//-- handle objects of several kd leaves separately
+	int pvs = ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());
+
+	// separately handle objects which are part of several kd leaves 
 	ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
 
@@ -1249,82 +1220,121 @@
 			++ pvs;
 		}
-	}					
-}
-
-
-void VspTree::EvalPvsIncr(const SortableEntry &ci,
-						  int &pvsLeft,
-						  int &pvsRight) const
+	}	
+
+	return pvs;
+}
+
+
+int VspTree::EvalMinEventContribution(const VssRay &ray, 
+									  const bool isTermination) const
+{
+	Intersectable *obj;
+	Vector3 pt;
+	KdNode *node;
+
+	ray.GetSampleData(isTermination, pt, &obj, &node);
+
+	if (!obj) return 0;
+
+	int pvs = 0;
+
+	switch (mHierarchyManager->GetObjectSpaceSubdivisonType())
+	{
+	case HierarchyManager::NO_OBJ_SUBDIV:
+		{
+			if (!obj->Mailed())
+			{
+				obj->Mail();
+				++ pvs;
+			}
+
+			break;
+		}
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
+		{
+			KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);
+			// add contributions of the kd nodes
+			pvs += EvalMinEventContribution(leaf);
+					
+			break;
+		}
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+
+			if (!leaf->Mailed())
+			{
+				leaf->Mail();
+				++ pvs;
+			}
+			break;
+		}
+	default:
+		break;
+	}
+	return pvs;
+}
+
+
+int VspTree::EvalMaxEventContribution(const VssRay &ray, 
+									  const bool isTermination) const
+{
+	Intersectable *obj;
+	Vector3 pt;
+	KdNode *node;
+
+	ray.GetSampleData(isTermination, pt, &obj, &node);
+
+	if (!obj) return 0;
+
+	int pvs = 0;
+
+	switch (mHierarchyManager->GetObjectSpaceSubdivisonType())
+	{
+	case HierarchyManager::NO_OBJ_SUBDIV:
+		{
+			if (-- obj->mCounter == 0)
+				++ pvs;
+			break;
+		}
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
+		{
+			KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);
+
+			// add contributions of the kd nodes
+			pvs += EvalMaxEventContribution(leaf);
+			break;
+		}
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+
+			if (-- leaf->mCounter == 0)
+				++ pvs;
+			break;
+		}
+	default:
+		break;
+	}
+
+	return pvs;
+}
+
+
+void VspTree::EvalHeuristicsContribution(const SortableEntry &ci,
+										 int &pvsLeft,
+										 int &pvsRight) const
 {
 	VssRay *ray = ci.ray;
 
-	Intersectable *oObject = ray->mOriginObject;
-	Intersectable *tObject = ray->mTerminationObject;
-
-	if (oObject)
-	{	
-		if (!mUseKdPvsForHeuristics)
-		{
-			if (ci.type == SortableEntry::ERayMin)
-			{
-				if (!oObject->Mailed())
-				{
-					oObject->Mail();
-					++ pvsLeft;
-				}
-			}
-			else if (ci.type == SortableEntry::ERayMax)
-			{
-				if (-- oObject->mCounter == 0)
-					-- pvsRight;
-			}
-		}
-		else // per kd node
-		{
-			KdLeaf *node = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
-
-			// add contributions of the kd nodes
-			if (ci.type == SortableEntry::ERayMin)
-			{
-				AddContriToPvs(node, pvsLeft);
-			}
-			else if (ci.type == SortableEntry::ERayMax)
-			{
-				RemoveContriFromPvs(node, pvsRight);
-			}
-		}
-	}
-	
-	if (tObject)
-	{	
-		if (!mUseKdPvsForHeuristics)
-		{
-			if (ci.type == SortableEntry::ERayMin)
-			{
-				if (!tObject->Mailed())
-				{
-					tObject->Mail();
-					++ pvsLeft;
-				}
-			}
-			else if (ci.type == SortableEntry::ERayMax)
-			{
-				if (-- tObject->mCounter == 0)
-					-- pvsRight;
-			}
-		}
-		else // per kd node
-		{
-			KdLeaf *node = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
-
-			if (ci.type == SortableEntry::ERayMin)
-			{
-				AddContriToPvs(node, pvsLeft);
-			}
-			else if (ci.type == SortableEntry::ERayMax)
-			{
-				RemoveContriFromPvs(node, pvsRight);
-			}
-		}
+	if (ci.type == SortableEntry::ERayMin)
+	{
+		pvsLeft += EvalMinEventContribution(*ray, true);
+		pvsLeft += EvalMinEventContribution(*ray, false);
+	}
+	else
+	{
+		pvsRight -= EvalMaxEventContribution(*ray, true);
+		pvsRight -= EvalMaxEventContribution(*ray, false);
 	}
 }
@@ -1336,4 +1346,5 @@
 									   float &position)
 {
+	// get subset of rays
 	RayInfoContainer usedRays;
 
@@ -1395,5 +1406,5 @@
 	for (ci = mLocalSubdivisionCandidates->begin(); ci != ci_end; ++ ci)
 	{
-		EvalPvsIncr(*ci, pvsl, pvsr);
+		EvalHeuristicsContribution(*ci, pvsl, pvsr);
 
 		// Note: sufficient to compare size of bounding boxes of front and back side?
@@ -1580,5 +1591,5 @@
 			rayInf.ComputeRayIntersection(candidatePlane.mAxis, 
 										  candidatePlane.mPosition, t);
-
+/*
 		if (!mUseKdPvsForHeuristics)
 		{
@@ -1591,5 +1602,5 @@
 			if (ray->mTerminationObject)
 			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
+				KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
 				UpdateKdLeafPvsContri(leaf, cf, pvsFront, pvsBack, totalPvs);
 			}
@@ -1597,8 +1608,9 @@
 			if (ray->mOriginObject)
 			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
+				KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
 				UpdateKdLeafPvsContri(leaf, cf, pvsFront, pvsBack, totalPvs);
 			}
 		}
+*/
 	}
 
@@ -2243,91 +2255,89 @@
 
 
-int VspTree::EvalPvsSize(const RayInfoContainer &rays) const
-{
-	int pvsSize = 0;
-	Intersectable::NewMail();
-
-	RayInfoContainer::const_iterator rit, rit_end = rays.end();
-
-	if (!mUseKdPvsForHeuristics)
-	{
-		for (rit = rays.begin(); rit != rays.end(); ++ rit)
-		{
-			VssRay *ray = (*rit).mRay;
-
-			if (ray->mOriginObject)
-			{
-				if (!ray->mOriginObject->Mailed())
+int VspTree::EvalPvsContribution(const VssRay &ray, const bool isTermination) const
+{	
+	Intersectable *obj; 
+	Vector3 pt;
+	KdNode *node;
+
+	ray.GetSampleData(isTermination, pt, &obj, &node);
+
+	if (!obj) return 0;
+
+	int pvs = 0;
+
+	switch(mHierarchyManager->GetObjectSpaceSubdivisonType())
+	{
+	case HierarchyManager::NO_OBJ_SUBDIV:
+		{
+			if (!obj->Mailed())
+			{
+				obj->Mail();
+				++ pvs;
+			}
+
+			break;
+		}
+	case HierarchyManager::KD_BASED_OBJ_SUBDIV:
+		{
+			KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);
+
+			if (!leaf->Mailed())
+			{
+				leaf->Mail();
+				pvs += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
+				
+				ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
+				for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
 				{
-					ray->mOriginObject->Mail();
-					++ pvsSize;
-				}
-			}
-			if (ray->mTerminationObject)
-			{
-				if (!ray->mTerminationObject->Mailed())
-				{
-					ray->mTerminationObject->Mail();
-					++ pvsSize;
-				}
-			}
-		}
-	}
-	else // compute pvs from kd nodes
-	{
-		KdNode::NewMail();
-
-		for (rit = rays.begin(); rit != rays.end(); ++ rit)
-		{
-			VssRay *ray = (*rit).mRay;
-
-			if (ray->mTerminationObject)
-			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
-
-				if (!leaf->Mailed())
-				{
-					leaf->Mail();
-					pvsSize += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
-				
-					ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
-					for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
+					Intersectable *obj = *oit;
+
+					if (!obj->Mailed())
 					{
-						Intersectable *obj = *oit;
-
-						if (!obj->Mailed())
-						{
-							obj->Mail();
-							++ pvsSize;
-						}
+						obj->Mail();
+						++ pvs;
 					}
 				}
 			}
 
-			if (ray->mOriginObject)
-			{
-				KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
-
-				if (!leaf->Mailed())
-				{
-					leaf->Mail();
-					pvsSize += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());
-				
-					ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();
-					for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)
-					{
-						Intersectable *obj = *oit;
-
-						if (!obj->Mailed())
-						{
-							obj->Mail();
-							++ pvsSize;
-						}
-					}
-				}
-			}
-		}
-	}
-
+			break;
+		}
+	case HierarchyManager::BV_BASED_OBJ_SUBDIV:
+		{
+			BvhLeaf *bvhleaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);
+
+			if (!bvhleaf->Mailed())
+			{
+				bvhleaf->Mail();
+				pvs += (int)bvhleaf->mObjects.size();
+			}
+
+			break;
+		}
+	default:
+		break;
+	}
+
+	return pvs;
+}
+
+
+int VspTree::EvalPvsSize(const RayInfoContainer &rays) const
+{
+	int pvsSize = 0;
+	
+	Intersectable::NewMail();
+	KdNode::NewMail();
+	BvhNode::NewMail();
+
+	RayInfoContainer::const_iterator rit, rit_end = rays.end();
+
+	for (rit = rays.begin(); rit != rays.end(); ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+		pvsSize += EvalPvsContribution(*ray, true);
+		pvsSize += EvalPvsContribution(*ray, false);
+	}
+	
 	return pvsSize;
 }
@@ -2806,38 +2816,4 @@
 
 
-void VspTree::CollectDirtyCandidates(VspSubdivisionCandidate *sc, 
-									 vector<SubdivisionCandidate *> &dirtyList)
-{
-	VspTraversalData &tData = sc->mParentData;
-	VspLeaf *node = tData.mNode;
-	
-	KdLeaf::NewMail();
-
-	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
-
-	// add all kd nodes seen by the rays
-	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
-	{
-		VssRay *ray = (*rit).mRay;
-	
-		KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
-	
-		if (!leaf->Mailed())
-		{
-			leaf->Mail();
-			dirtyList.push_back(leaf->mSubdivisionCandidate);
-		}
-		
-		leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
-	
-		if (!leaf->Mailed())
-		{
-			leaf->Mail();
-			dirtyList.push_back(leaf->mSubdivisionCandidate);
-		}
-	}
-}
-
-
 void VspTree::PreprocessRays(const VssRayContainer &sampleRays,
 							 RayInfoContainer &rays)
@@ -2965,4 +2941,36 @@
 
 
-
-}
+void VspTree::CollectDirtyCandidates(VspSubdivisionCandidate *sc, 
+									 vector<SubdivisionCandidate *> &dirtyList)
+{
+	VspTraversalData &tData = sc->mParentData;
+	VspLeaf *node = tData.mNode;
+	
+	KdLeaf::NewMail();
+
+	RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();
+
+	// add all kd nodes seen by the rays
+	for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)
+	{
+		VssRay *ray = (*rit).mRay;
+	
+		KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);
+	
+		if (!leaf->Mailed())
+		{
+			leaf->Mail();
+			dirtyList.push_back(leaf->mSubdivisionCandidate);
+		}
+		
+		leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);
+	
+		if (!leaf->Mailed())
+		{
+			leaf->Mail();
+			dirtyList.push_back(leaf->mSubdivisionCandidate);
+		}
+	}
+}
+
+}
