Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 441)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp	(revision 442)
@@ -218,10 +218,10 @@
 /****************************************************************/
 
-VspBspTree::VspBspTree(BspViewCell *viewCell): 
-mRootCell(viewCell), 
-mRoot(NULL), 
-mStoreLeavesWithRays(false),
-mPvsUseLen(true)
-{
+VspBspTree::VspBspTree(): 
+mRoot(NULL),
+mPvsUseArea(true)
+{
+	mRootCell = new BspViewCell();
+
 	Randomize(); // initialise random generator for heuristics
 
@@ -349,4 +349,5 @@
 {
 	DEL_PTR(mRoot);
+	DEL_PTR(mRootCell);
 }
 
@@ -485,5 +486,5 @@
 
 	VspBspTraversalData tData(mRoot, polys, 0, mRootCell, rays, 
-						   ComputePvsSize(*rays));
+						   ComputePvsSize(*rays), cell->GetArea(), cell);
 
 	tStack.push(tData);
@@ -515,4 +516,5 @@
 		(((int)data.mRays->size() <= mTermMinRays) ||
 		 (data.mPvs <= mTermMinPvs) ||
+		 (data.mArea <= mTermMinArea) ||
 		 (data.mDepth >= mTermMaxDepth) ||
 		 (data.GetAvgRayContribution() < mTermMaxRayContribution));
@@ -547,5 +549,5 @@
 		DEL_PTR(tData.mPolygons);
 		DEL_PTR(tData.mRays);
-		//DEL_PTR(tData.mGeometry);
+		DEL_PTR(tData.mGeometry);
 		
 		return leaf;
@@ -556,7 +558,7 @@
 	
 	VspBspTraversalData tFrontData(NULL, new PolygonContainer(), tData.mDepth + 1, mRootCell, 
-								new RayInfoContainer(), 0);
+								new RayInfoContainer(), 0, 0, new VspBspNodeGeometry());
 	VspBspTraversalData tBackData(NULL, new PolygonContainer(), tData.mDepth + 1, mRootCell, 
-							   new RayInfoContainer(), 0);
+							   new RayInfoContainer(), 0, 0, new VspBspNodeGeometry());
 
 	// create new interior node and two leaf nodes
@@ -582,5 +584,5 @@
 	DEL_PTR(tData.mPolygons);
 	DEL_PTR(tData.mRays);
-	//DEL_PTR(tData.mGeometry);		
+	DEL_PTR(tData.mGeometry);		
 
 	return interior;
@@ -615,4 +617,17 @@
 	frontData.mPvs = ComputePvsSize(*frontData.mRays);
 	backData.mPvs = ComputePvsSize(*backData.mRays);
+
+	// split geometry and compute area
+	if (1)
+	{
+		tData.mGeometry->SplitGeometry(*frontData.mGeometry, 
+									   *backData.mGeometry, 
+									   *this, 
+									   interior->mPlane);
+	
+		
+		frontData.mArea = frontData.mGeometry->GetArea();
+		backData.mArea = backData.mGeometry->GetArea();
+	}
 
 	// compute accumulated ray length
@@ -991,8 +1006,25 @@
 	float pBack = 0;
 
+	const bool pvsUseLen = false;
+
 	if (mSplitPlaneStrategy & PVS)
+	{
 		// create unique ids for pvs heuristics
 		GenerateUniqueIdsForPvs();
 	
+		if (mPvsUseArea) // use front and back cell areas to approximate volume
+		{	
+			// construct child geometry with regard to the candidate split plane
+			VspBspNodeGeometry frontCell;
+			VspBspNodeGeometry backCell;
+
+			data.mGeometry->SplitGeometry(frontCell, backCell, *this, candidatePlane);
+		
+			pFront = frontCell.GetArea();
+			pBack = backCell.GetArea();
+
+			pOverall = data.mArea;
+		}
+	}
 			
 	RayInfoContainer::const_iterator rit, rit_end = data.mRays->end();
@@ -1026,41 +1058,44 @@
 			AddObjToPvs(ray->mOriginObject, cf, frontPvs, backPvs);
 			
-			float len = 1;
-
-			if (mPvsUseLen) // use front and back cell areas to approximate volume
-				len = (*rit).SqrSegmentLength();
+			// use number or length of rays to approximate volume
+			if (!mPvsUseArea)
+			{
+				float len = 1;
+
+				if (pvsUseLen) // use length of rays
+					len = (*rit).SqrSegmentLength();
 			
-			pOverall += len;
-
-			// use length of rays to approximate volume
-			if (cf == 1)
-				pFront += len;
-			if (cf == -1)
-				pBack += len;
-			if (cf == 0)
-			{
-				if (mPvsUseLen)
+				pOverall += len;
+
+				if (cf == 1)
+					pFront += len;
+				if (cf == -1)
+					pBack += len;
+				if (cf == 0)
 				{
-					float newLen = len * 
-						((*rit).GetMaxT() - (*rit).mRay->mT) / 
-						((*rit).GetMaxT() - (*rit).GetMinT());
-
-				
-					if (candidatePlane.Side((*rit).ExtrapOrigin()) <= 0)
+					// use length of rays to approximate volume
+					if (pvsUseLen) 
 					{
-						pBack += newLen;
-						pFront += len - newLen;
+						float newLen = len * 
+							((*rit).GetMaxT() - (*rit).mRay->mT) / 
+							((*rit).GetMaxT() - (*rit).GetMinT());
+		
+						if (candidatePlane.Side((*rit).ExtrapOrigin()) <= 0)
+						{
+							pBack += newLen;
+							pFront += len - newLen;
+						}
+						else
+						{
+							pFront += newLen;
+							pBack += len - newLen;
+						}
 					}
 					else
 					{
-						pFront += newLen;
-						pBack += len - newLen;
+						++ pFront;
+						++ pBack;
 					}
 				}
-				else
-				{
-					++ pFront;
-					++ pBack;
-				}
 			}
 		}
@@ -1083,5 +1118,6 @@
 		// give penalty to unbalanced split
 		if (0)
-		if (((pFront * 0.2 + Limits::Small) > pBack) || (pFront < (pBack * 0.2 + Limits::Small)))
+		if (((pFront * 0.2 + Limits::Small) > pBack) || 
+			(pFront < (pBack * 0.2 + Limits::Small)))
 			val += 0.5;
 	}
@@ -1199,4 +1235,6 @@
 		++ mStat.maxRayContribNodes;
 	
+	if (data.mGeometry->GetArea() <= mTermMinArea) 
+		++ mStat.minAreaNodes;
 
 #ifdef _DEBUG
@@ -1984,2 +2022,7 @@
 	app << "===== END OF VspBspViewCells statistics ==========\n";
 }
+
+BspViewCell *VspBspTree::GetRootCell() const
+{
+	return mRootCell;
+}
