Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 418)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp	(revision 419)
@@ -28,9 +28,9 @@
 int VspKdTreeLeaf::mailID = 0;
 int VspKdTree::sTermMaxDepth = 10;
-float VspKdTree::sTermMinSize = 0.1;
+float VspKdTree::sTermMinSize = 0.1f;
 int VspKdTree::sTermMinPvs = 10;
 int VspKdTree::sTermMinRays = 20;
-float VspKdTree::sTermMaxCostRatio = 0.1;
-float VspKdTree::sTermMaxRayContribution = 0.1;
+float VspKdTree::sTermMaxCostRatio = 0.1f;
+float VspKdTree::sTermMaxRayContribution = 0.1f;
 
 
@@ -71,5 +71,5 @@
 
 /**************************************************************/
- *                VspKdTreeInterior implementation            *
+/*                VspKdTreeInterior implementation            */
 /**************************************************************/
 
@@ -81,5 +81,5 @@
 int VspKdTreeInterior::GetAccessTime()
 {
-	return lastAccessTime;
+	return mLastAccessTime;
 }
 
@@ -101,5 +101,5 @@
 int VspKdTreeInterior::Type() const  
 { 
-	return VspKdInterior; 
+	return EInterior; 
 }
   
@@ -112,12 +112,12 @@
 void VspKdTreeInterior::Print(ostream &s) const 
 {
-	if (axis == 0)
+	if (mAxis == 0)
 		s << "x ";
 	else
-		if (axis == 1)
+		if (mAxis == 1)
 			s << "y ";
 		else
 			s << "z ";
-	s << position << " ";
+	s << mPosition << " ";
 
 	mBack->Print(s);
@@ -127,20 +127,35 @@
 int VspKdTreeInterior::ComputeRayIntersection(const RayInfo &rayData, float &t) 
 {
-	return rayData.ComputeRayIntersection(axis, position, t);
-}
-
+	return rayData.ComputeRayIntersection(mAxis, mPosition, t);
+}
+
+VspKdTreeNode *VspKdTreeInterior::GetBack() const
+{
+	return mBack;
+}
+
+VspKdTreeNode *VspKdTreeInterior::GetFront() const
+{
+	return mFront;
+}
+
+/**************************************************/
+/*         class VspKdTree implementation         */
+/**************************************************/
+void VspKdTree::ParseEnvironment()
+{
+	environment->GetIntValue("VspKdTree.Termination.maxDepth", sTermMaxDepth);
+	environment->GetIntValue("VspKdTree.Termination.minPvs", sTermMinPvs);
+	environment->GetIntValue("VspKdTree.Termination.minRays", sTermMinRays);
+	environment->GetFloatValue("VspKdTree.Termination.maxRayContribution", sTermMaxRayContribution);
+	environment->GetFloatValue("VspKdTree.Termination.maxCostRatio", sTermMaxCostRatio);
+
+	environment->GetFloatValue("VspKdTree.Termination.minSize", sTermMinSize);
+	sTermMinSize = sqr(sTermMinSize);
+}
 
 // Constructor
 VspKdTree::VspKdTree()
-{
-	environment->GetIntValue("VspKdTree.maxDepth", sTermMaxDepth);
-	environment->GetIntValue("VspKdTree.minPvs", sTermMinPvs);
-	environment->GetIntValue("VspKdTree.minRays", sTermMinRays);
-	environment->GetFloatValue("VspKdTree.maxRayContribution", sTermMaxRayContribution);
-	environment->GetFloatValue("VspKdTree.maxCostRatio", sTermMaxCostRatio);
-
-	environment->GetFloatValue("VspKdTree.minSize", sTermMinSize);
-	termMinSize = sqr(termMinSize);
-	  
+{	  
 	environment->GetFloatValue("VspKdTree.epsilon", epsilon);
 	environment->GetFloatValue("VspKdTree.ct_div_ci", ct_div_ci);
@@ -150,5 +165,4 @@
   
   
-	float refDirAngle;
 	environment->GetIntValue("VspKdTree.accessTimeThreshold", accessTimeThreshold);
 	//= 1000;
@@ -174,6 +188,4 @@
 	}
 
-	environment->GetBoolValue("VspKdTree.randomize", randomize);
-
 	mRoot = NULL;
 
@@ -184,6 +196,5 @@
 VspKdTree::~VspKdTree()
 {
-	if (mRoot)
-		delete mRoot;
+	DEL_PTR(mRoot);
 }
 
@@ -298,18 +309,15 @@
 	maxMemory = maxStaticMemory;
 
-	if (root)
-		delete root;
-
-	root = new VspKdTreeLeaf(NULL, rays.size());
+	DEL_PTR(mRoot);
+
+	mRoot = new VspKdTreeLeaf(NULL, (int)rays.size());
 
 	// first construct a leaf that will get subdivide
-	VspKdTreeLeaf *leaf = (VspKdTreeLeaf *) root;
+	VspKdTreeLeaf *leaf = dynamic_cast<VspKdTreeLeaf *>(mRoot);
 
 	
 	mStat.nodes = 1;
   	
-	bbox.Initialize();
-	dirBBox.Initialize();
-  
+	mBox.Initialize();
 	
 	for (VssRayContainer::const_iterator ri = rays.begin(); ri != rays.end(); ++ ri)
@@ -317,17 +325,14 @@
 		leaf->AddRay(VspKdTreeNode::RayInfo(*ri));
 
-		bbox.Include((*ri)->GetOrigin());
-		bbox.Include((*ri)->GetTermination());    
-		
-		dirBBox.Include(Vector3((*ri)->GetDirParametrization(0), (*ri)->GetDirParametrization(1), 0));
+		mBox.Include((*ri)->GetOrigin());
+		mBox.Include((*ri)->GetTermination()); 
 	}
 	
 	if (forcedBoundingBox)
-		bbox = *forcedBoundingBox;
-
-	cout<<"Bbox = "<<bbox<<endl;
-	cout<<"Dirr Bbox = "<<dirBBox<<endl;
-
-	mStat.rays = leaf->rays.size();
+		mBox = *forcedBoundingBox;
+
+	cout << "Bbox = " << mBox << endl;
+	
+	mStat.rays = (int)leaf->rays.size();
 	leaf->UpdatePvsSize();
 	
@@ -335,5 +340,5 @@
 	
 	// Subdivide();
-	root = Subdivide(TraversalData(leaf, bbox, 0));
+	mRoot = Subdivide(TraversalData(leaf, mBox, 0));
 
 	if (splitCandidates) 
@@ -390,6 +395,6 @@
     
 		
-		VspKdTreeNode *node = SubdivideNode((VspKdTreeLeaf *) data.node,
-											data.bbox, backBox,	frontBox);
+		VspKdTreeNode *node = SubdivideNode((VspKdTreeLeaf *) data.mNode,
+											data.mBox, backBox,	frontBox);
 		if (result == NULL)
 			result = node;
@@ -400,6 +405,6 @@
 
 			// push the children on the stack
-			tStack.push(TraversalData(interior->back, backBox, data.depth+1));
-			tStack.push(TraversalData(interior->front, frontBox, data.depth+1));
+			tStack.push(TraversalData(interior->GetBack(), backBox, data.mDepth + 1));
+			tStack.push(TraversalData(interior->GetFront(), frontBox, data.mDepth + 1));
 		} 
 		else 
@@ -453,5 +458,5 @@
   }
 
-	if (costRatio > termMaxCostRatio) 
+	if (costRatio > sTermMaxCostRatio) 
 	{
 		//		cout<<"Too big cost ratio "<<costRatio<<endl;
@@ -496,73 +501,38 @@
 	Intersectable::NewMail(3);
 
-	if (axis <= VspKdTreeNode::SPLIT_Z) {
-    // this is the main ray classification loop!
+	// this is the main ray classification loop!
     for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin();
 		ri != leaf->rays.end();	ri++)
-		if ((*ri).mRay->IsActive()) 
-		{
-			// determine the side of this ray with respect to the plane
-			int side = (*ri).ComputeRayIntersection(axis, position, (*ri).mRay->mT);
-			//				(*ri).mRay->mSide = side;
+	{
+		if (!(*ri).mRay->IsActive()) 
+			continue;
 			
-			if (side <= 0)
-				raysBack ++;
+		// determine the side of this ray with respect to the plane
+		int side = (*ri).ComputeRayIntersection(axis, position, (*ri).mRay->mT);
+		//				(*ri).mRay->mSide = side;
+			
+		if (side <= 0)
+			++ raysBack;
 				
-			if (side >= 0)
-				raysFront++;
+		if (side >= 0)
+			++ raysFront;
 				
-			AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront);
-		}
+		AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront);
+	}	
+
+	AxisAlignedBox3 box = GetBBox(leaf);
+	
+	float minBox = box.Min(axis);
+	float maxBox = box.Max(axis);
+	float sizeBox = maxBox - minBox;
 		
-		AxisAlignedBox3 box = GetBBox(leaf);
-		
-		float minBox = box.Min(axis);
-		float maxBox = box.Max(axis);
-		float sizeBox = maxBox - minBox;
-		
-		//		float sum = raysBack*(position - minBox) + raysFront*(maxBox - position);
-		float sum = pvsBack*(position - minBox) + pvsFront*(maxBox - position);
-
-		newCost = ct_div_ci + sum/sizeBox;
-	} 
-	else 
-	{
-		// directional split
-		for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin();
-			ri != leaf->rays.end();	++ ri)
-			if ((*ri).mRay->IsActive()) 
-			{
-				// determine the side of this ray with respect to the plane
-				int side;
-				if ((*ri).mRay->GetDirParametrization(axis - 3) > position)
-					side = 1;
-				else
-					side = -1;
-
-				if (side <= 0)
-					raysBack++;
-				
-				if (side >= 0)
-					raysFront++;
-
-				//				(*ri).mRay->mSide = side;
-				AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront);
-			}
-	
-			AxisAlignedBox3 box = GetDirBBox(leaf);
-		
-			float minBox = box.Min(axis - 3);
-			float maxBox = box.Max(axis - 3);
-			float sizeBox = maxBox - minBox;
-		
-			// float sum = raysBack*(position - minBox) + raysFront*(maxBox - position);
-			float sum =	pvsBack*(position - minBox) + pvsFront*(maxBox - position);
-		//		float sum = pvsBack + pvsFront;
-		newCost = ct_div_ci + sum/sizeBox;
-	}
-
+	//		float sum = raysBack*(position - minBox) + raysFront*(maxBox - position);
+	float sum = pvsBack*(position - minBox) + pvsFront*(maxBox - position);
+
+	newCost = ct_div_ci + sum/sizeBox;
+	
 	//	cout<<axis<<" "<<pvsSize<<" "<<pvsBack<<" "<<pvsFront<<endl;
 	//  float oldCost = leaf->rays.size();
-	float oldCost = pvsSize;
+	float oldCost = (float)pvsSize;
 	
 	float ratio = newCost / oldCost;
@@ -587,21 +557,16 @@
 	
 	AxisAlignedBox3 sBox = GetBBox(leaf);
-	AxisAlignedBox3 dBox = GetDirBBox(leaf);
 
 	// int sAxis = box.Size().DrivingAxis();
 	int sAxis = sBox.Size().DrivingAxis();
-	int dAxis = dBox.Size().DrivingAxis() + 3;
-
+	
 	bool onlyDrivingAxis = true; 
 
 	for (axis = 0; axis < 6; ++ axis) 
 	{
-		if (!onlyDrivingAxis || axis == sAxis || axis == dAxis) 
-		{
-			if (axis < 3)
-				nPosition[axis] = (sBox.Min()[axis] + sBox.Max()[axis])*0.5f;
-			else
-				nPosition[axis] = (dBox.Min()[axis-3] + dBox.Max()[axis-3])*0.5f;
-			
+		if (!onlyDrivingAxis || axis == sAxis) 
+		{
+			nPosition[axis] = (sBox.Min()[axis] + sBox.Max()[axis])*0.5f;
+						
 			nCostRatio[axis] = EvalCostRatio(leaf,
 											 axis,
@@ -651,5 +616,5 @@
 	// C = ct_div_ci  + (ql*rl + qr*rr)/queries
 	
-	int rl=0, rr = leaf->rays.size();
+	int rl=0, rr = (int)leaf->rays.size();
 	int pl=0, pr = leaf->GetPvsSize();
 	float minBox = box.Min(axis);
@@ -657,6 +622,6 @@
 	float sizeBox = maxBox - minBox;
 	
-	float minBand = minBox + 0.1*(maxBox - minBox);
-	float maxBand = minBox + 0.9*(maxBox - minBox);
+	float minBand = minBox + 0.1f*(maxBox - minBox);
+	float maxBand = minBox + 0.9f*(maxBox - minBox);
 	
 	float sum = rr*sizeBox;
@@ -743,5 +708,5 @@
 	}
 
-	float oldCost = leaf->GetPvsSize();
+	float oldCost = (float)leaf->GetPvsSize();
 	float newCost = ct_div_ci + minSum / sizeBox;
 	float ratio = newCost / oldCost;
@@ -789,21 +754,21 @@
 {
 	// the node became a leaf -> evaluate stats for leafs
-	VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.node;
-
-	if (data.depth >= termMaxDepth)
+	VspKdTreeLeaf *leaf = dynamic_cast<VspKdTreeLeaf *>(data.mNode);
+
+	if (data.mDepth >= sTermMaxDepth)
 		++ mStat.maxDepthNodes;
   
 	//  if ( (int)(leaf->rays.size()) < termMinCost)
 	//    stat.minCostNodes++;
-	if (leaf->GetPvsSize() < termMinPvs)
+	if (leaf->GetPvsSize() < sTermMinPvs)
 		++ mStat.minPvsNodes;
 
-	if (leaf->GetPvsSize() < termMinRays)
+	if (leaf->GetPvsSize() < sTermMinRays)
 		++ mStat.minRaysNodes;
 
-	if (0 && leaf->GetAvgRayContribution() > termMaxRayContribution)
+	if (0 && leaf->GetAvgRayContribution() > sTermMaxRayContribution)
 		++ mStat.maxRayContribNodes;
 	
-	if (SqrMagnitude(data.bbox.Size()) <= termMinSize) 
+	if (SqrMagnitude(data.mBox.Size()) <= sTermMinSize) 
 		++ mStat.minSizeNodes;
 
@@ -819,12 +784,12 @@
 										AxisAlignedBox3 &frontBBox)
 {
-	if ( (leaf->GetPvsSize() < termMinPvs) || (leaf->rays.size() < termMinRays) ||
+	if ( (leaf->GetPvsSize() < sTermMinPvs) || (leaf->rays.size() < sTermMinRays) ||
 	// (leaf->GetAvgRayContribution() > termMaxRayContribution ) ||
-       (leaf->depth >= termMaxDepth) || SqrMagnitude(box.Size()) <= termMinSize ) 
+       (leaf->mDepth >= sTermMaxDepth) || SqrMagnitude(box.Size()) <= sTermMinSize ) 
 	{
 
 #if 0
-		if (leaf->depth >= termMaxDepth) {
-			cout<<"Warning: max depth reached depth="<<(int)leaf->depth<<" rays="<<leaf->rays.size()<<endl;
+		if (leaf->mDepth >= termMaxDepth) {
+			cout<<"Warning: max depth reached depth="<<(int)leaf->mDepth<<" rays="<<leaf->rays.size()<<endl;
 			cout<<"Bbox: "<<GetBBox(leaf)<<" dirbbox:"<<GetDirBBox(leaf)<<endl;
 		}
@@ -856,11 +821,10 @@
 
 	// add the new nodes to the tree
-	VspKdTreeInterior *node = new VspKdTreeInterior(leaf->parent);
-
-	node->axis = axis;
-	node->position = position;
-	node->bbox = box;
-	node->dirBBox = GetDirBBox(leaf);
-  
+	VspKdTreeInterior *node = new VspKdTreeInterior(leaf->mParent);
+
+	node->mAxis = axis;
+	node->mPosition = position;
+	node->mBox = box;
+	  
 	backBBox = box;
 	frontBBox = box;
@@ -872,6 +836,6 @@
 
 	// replace a link from node's parent
-	if (leaf->parent)
-		leaf->parent->ReplaceChildLink(leaf, node);
+	if (leaf->mParent)
+		leaf->mParent->ReplaceChildLink(leaf, node);
 	// and setup child links
 	node->SetupChildLinks(back, front);
@@ -967,5 +931,5 @@
 	int released;
 
-	tstack.push(root);
+	tstack.push(mRoot);
 
 	while (!tstack.empty()) 
@@ -976,20 +940,20 @@
 		if (!node->IsLeaf()) 
 		{
-			VspKdTreeInterior *in = (VspKdTreeInterior *)node;
+			VspKdTreeInterior *in = dynamic_cast<VspKdTreeInterior *>(node);
 			// cout<<"depth="<<(int)in->depth<<" time="<<in->lastAccessTime<<endl;
-			if (in->depth >= minCollapseDepth && in->lastAccessTime <= maxAccessTime) 
+			if (in->mDepth >= minCollapseDepth && in->mLastAccessTime <= maxAccessTime) 
 			{
 				released = CollapseSubtree(node, time);
 				break;
 			}
-			if (in->back->GetAccessTime() <  in->front->GetAccessTime()) 
+			if (in->GetBack()->GetAccessTime() <  in->GetFront()->GetAccessTime()) 
 			{
-				tstack.push(in->front);
-				tstack.push(in->back);
+				tstack.push(in->GetFront());
+				tstack.push(in->GetBack());
 			} 
 			else 
 			{
-				tstack.push(in->back);
-				tstack.push(in->front);
+				tstack.push(in->GetBack());
+				tstack.push(in->GetFront());
 			}
 		}
@@ -1021,5 +985,5 @@
 	// check if we should perform a dynamic subdivision of the leaf
 	if (// leaf->rays.size() > (unsigned)termMinCost &&
-		(leaf->GetPvsSize() >= termMinPvs) && 
+		(leaf->GetPvsSize() >= sTermMinPvs) && 
 		(SqrMagnitude(leafBBox.Size()) > sizeThreshold) )
 	{
@@ -1078,5 +1042,5 @@
 	stack<RayTraversalData> tstack;
 
-	tstack.push(RayTraversalData(root, VspKdTreeNode::RayInfo(ray)));
+	tstack.push(RayTraversalData(mRoot, VspKdTreeNode::RayInfo(ray)));
   
 	RayTraversalData data;
@@ -1088,5 +1052,5 @@
 		tstack.pop();
 
-		if (!data.node->IsLeaf()) 
+		if (!data.mNode->IsLeaf()) 
 		{
 			// split the set of rays in two groups intersecting the
@@ -1099,5 +1063,5 @@
 			// remove the ray from the leaf
 			// find the ray in the leaf and swap it with the last ray...
-			VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.node;
+			VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.mNode;
       
 			if (!leaf->Mailed()) 
@@ -1168,5 +1132,5 @@
 	stack<RayTraversalData> tstack;
   
-	tstack.push(RayTraversalData(root, VspKdTreeNode::RayInfo(ray)));
+	tstack.push(RayTraversalData(mRoot, VspKdTreeNode::RayInfo(ray)));
   
 	RayTraversalData data;
@@ -1177,5 +1141,5 @@
 		tstack.pop();
 
-		if (!data.node->IsLeaf()) 
+		if (!data.mNode->IsLeaf()) 
 		{
 			TraverseInternalNode(data, tstack);
@@ -1185,6 +1149,6 @@
 			// remove the ray from the leaf
 			// find the ray in the leaf and swap it with the last ray...
-			VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.node;
-			leaf->AddRay(data.rayData);
+			VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.mNode;
+			leaf->AddRay(data.mRayData);
 			++ mStat.addedRayRefs;
 		}
@@ -1195,49 +1159,49 @@
 									 stack<RayTraversalData> &tstack)
 {
-	VspKdTreeInterior *in =  (VspKdTreeInterior *) data.node;
-  
-	if (in->axis <= VspKdTreeNode::SPLIT_Z) 
+	VspKdTreeInterior *in =  (VspKdTreeInterior *) data.mNode;
+  
+	if (in->mAxis <= VspKdTreeNode::SPLIT_Z) 
 	{
 	    // determine the side of this ray with respect to the plane
-		int side = in->ComputeRayIntersection(data.rayData, data.rayData.mRay->mT);
+		int side = in->ComputeRayIntersection(data.mRayData, data.mRayData.mRay->mT);
     
       if (side == 0) 
 	  {
-		if (data.rayData.mRay->HasPosDir(in->axis)) 
-		{
-			tstack.push(RayTraversalData(in->back, 
-						VspKdTreeNode::RayInfo(data.rayData.mRay, data.rayData.mMinT, 
-											   data.rayData.mRay->mT)));
+		if (data.mRayData.mRay->HasPosDir(in->mAxis)) 
+		{
+			tstack.push(RayTraversalData(in->GetBack(), 
+						VspKdTreeNode::RayInfo(data.mRayData.mRay, data.mRayData.mMinT, 
+											   data.mRayData.mRay->mT)));
 				
-			tstack.push(RayTraversalData(in->front,
-						VspKdTreeNode::RayInfo(data.rayData.mRay, data.rayData.mRay->mT, 
-											   data.rayData.mMaxT)));
+			tstack.push(RayTraversalData(in->GetFront(),
+						VspKdTreeNode::RayInfo(data.mRayData.mRay, data.mRayData.mRay->mT, 
+											   data.mRayData.mMaxT)));
 	
 		} 
 		else 
 		{
-			tstack.push(RayTraversalData(in->back,
-										 VspKdTreeNode::RayInfo(data.rayData.mRay,
-																data.rayData.mRay->mT,
-																data.rayData.mMaxT)));
-			tstack.push(RayTraversalData(in->front,
-										 VspKdTreeNode::RayInfo(data.rayData.mRay,
-																data.rayData.mMinT,
-																data.rayData.mRay->mT)));
+			tstack.push(RayTraversalData(in->GetBack(),
+										 VspKdTreeNode::RayInfo(data.mRayData.mRay,
+																data.mRayData.mRay->mT,
+																data.mRayData.mMaxT)));
+			tstack.push(RayTraversalData(in->GetFront(),
+										 VspKdTreeNode::RayInfo(data.mRayData.mRay,
+																data.mRayData.mMinT,
+																data.mRayData.mRay->mT)));
 		}
 	  } 
 	  else
      	  if (side == 1)
-			  tstack.push(RayTraversalData(in->front, data.rayData));
+			  tstack.push(RayTraversalData(in->GetFront(), data.mRayData));
 		  else
-			  tstack.push(RayTraversalData(in->back, data.rayData));
+			  tstack.push(RayTraversalData(in->GetBack(), data.mRayData));
 	} 
 	else 
 	{
 		// directional split
-		if (data.rayData.mRay->GetDirParametrization(in->axis - 3) > in->position)
-			tstack.push(RayTraversalData(in->front, data.rayData));
+		if (data.mRayData.mRay->GetDirParametrization(in->mAxis - 3) > in->mPosition)
+			tstack.push(RayTraversalData(in->GetFront(), data.mRayData));
 		else
-			tstack.push(RayTraversalData(in->back, data.rayData));
+			tstack.push(RayTraversalData(in->GetBack(), data.mRayData));
 	}
 }
@@ -1290,6 +1254,6 @@
 		else 
 		{
-			tstack.push(((VspKdTreeInterior *)node)->back);
-			tstack.push(((VspKdTreeInterior *)node)->front);
+			tstack.push(((VspKdTreeInterior *)node)->GetFront());
+			tstack.push(((VspKdTreeInterior *)node)->GetBack());
 		}
 	}
@@ -1298,8 +1262,8 @@
 
 	// create a new node that will hold the rays
-	VspKdTreeLeaf *newLeaf = new VspKdTreeLeaf(sroot->parent, rayCount);
-	
-	if (newLeaf->parent)
-		newLeaf->parent->ReplaceChildLink(sroot, newLeaf);
+	VspKdTreeLeaf *newLeaf = new VspKdTreeLeaf(sroot->mParent, rayCount);
+	
+	if (newLeaf->mParent)
+		newLeaf->mParent->ReplaceChildLink(sroot, newLeaf);
 
 	tstack.push(sroot);
@@ -1312,5 +1276,5 @@
 		if (node->IsLeaf()) 
 		{
-			VspKdTreeLeaf *leaf = (VspKdTreeLeaf *) node;
+			VspKdTreeLeaf *leaf = dynamic_cast<VspKdTreeLeaf *>(node);
 
 			for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin();
@@ -1333,6 +1297,8 @@
 		else 
 		{
-			tstack.push(((VspKdTreeInterior *)node)->back);
-			tstack.push(((VspKdTreeInterior *)node)->front);
+			VspKdTreeInterior *interior = 
+				dynamic_cast<VspKdTreeInterior *>(node);
+			tstack.push(interior->GetBack());
+			tstack.push(interior->GetFront());
 		}
 	}
@@ -1368,5 +1334,5 @@
 {
 	stack<VspKdTreeNode *> tstack;
-	tstack.push(root);
+	tstack.push(mRoot);
 
 	Intersectable::NewMail();
@@ -1407,19 +1373,19 @@
 		else 
 		{
-			VspKdTreeInterior *in = (VspKdTreeInterior *)node;
-	
-			if (in->axis < 3) 
+			VspKdTreeInterior *in = dynamic_cast<VspKdTreeInterior *>(node);
+	
+			if (in->mAxis < 3) 
 			{
-				if (box.Max(in->axis) >= in->position)
-					tstack.push(in->front);
+				if (box.Max(in->mAxis) >= in->mPosition)
+					tstack.push(in->GetFront());
 				
-				if (box.Min(in->axis) <= in->position)
-					tstack.push(in->back);
+				if (box.Min(in->mAxis) <= in->mPosition)
+					tstack.push(in->GetBack());
 			} 
 			else 
 			{
 				// both nodes for directional splits
-				tstack.push(in->front);
-				tstack.push(in->back);
+				tstack.push(in->GetFront());
+				tstack.push(in->GetBack());
 			}
 		}
@@ -1434,5 +1400,5 @@
 {
 	stack<VspKdTreeNode *> tstack;
-	tstack.push(root);
+	tstack.push(mRoot);
 	
 	minRayContribution = 1.0f;
@@ -1462,11 +1428,11 @@
 			VspKdTreeInterior *in = (VspKdTreeInterior *)node;
 			// both nodes for directional splits
-			tstack.push(in->front);
-			tstack.push(in->back);
-		}
-	}
-	
-	cout<<"sum="<<sumRayContribution<<endl;
-	cout<<"leaves="<<leaves<<endl;
+			tstack.push(in->GetFront());
+			tstack.push(in->GetBack());
+		}
+	}
+	
+	cout << "sum=" << sumRayContribution << endl;
+	cout << "leaves=" << leaves << endl;
 	avgRayContribution = sumRayContribution/(float)leaves;
 }
@@ -1477,5 +1443,5 @@
 {
 	stack<VspKdTreeNode *> tstack;
-	tstack.push(root);
+	tstack.push(mRoot);
 	
 	while (!tstack.empty()) 
@@ -1494,8 +1460,8 @@
 			{
 				Vector3 origin = GetBBox(leaf).GetRandomPoint();
-				Vector3 dirVector = GetDirBBox(leaf).GetRandomPoint();
+				/*Vector3 dirVector = GetDirBBox(leaf).GetRandomPoint();
 				Vector3 direction = Vector3(sin(dirVector.x), sin(dirVector.y), cos(dirVector.x));
 				//cout<<"dir vector.x="<<dirVector.x<<"direction'.x="<<atan2(direction.x, direction.y)<<endl;
-				rays.push_back(SimpleRay(origin, direction));
+				rays.push_back(SimpleRay(origin, direction));*/
 			}
 			
@@ -1503,8 +1469,9 @@
 		else 
 		{
-			VspKdTreeInterior *in = (VspKdTreeInterior *)node;
+			VspKdTreeInterior *in = 
+				dynamic_cast<VspKdTreeInterior *>(node);
 			// both nodes for directional splits
-			tstack.push(in->front);
-			tstack.push(in->back);
+			tstack.push(in->GetFront());
+			tstack.push(in->GetBack());
 		}
 	}
@@ -1517,5 +1484,5 @@
 {
 	stack<VspKdTreeNode *> tstack;
-	tstack.push(root);
+	tstack.push(mRoot);
 
 	int sumPvs = 0;
@@ -1539,6 +1506,6 @@
 			VspKdTreeInterior *in = (VspKdTreeInterior *)node;
 			// both nodes for directional splits
-			tstack.push(in->front);
-			tstack.push(in->back);
+			tstack.push(in->GetFront());
+			tstack.push(in->GetBack());
 		}
 	}
@@ -1552,21 +1519,22 @@
 }
 
-AxisAlignedBox3 VspKdTree::GetBBox(const VspKdTreeNode *node) 
-{
-	if (node->parent == NULL)
-		return mBbox;
+AxisAlignedBox3 VspKdTree::GetBBox(VspKdTreeNode *node) const
+{
+	if (node->mParent == NULL)
+		return mBox;
 
 	if (!node->IsLeaf())
-		return ((VspKdTreeInterior *)node)->mBbox;
-
-	if (node->parent->axis >= 3)
-		return node->parent->mBbox;
+		return (dynamic_cast<VspKdTreeInterior *>(node))->mBox;
+
+	if (node->mParent->mAxis >= 3)
+		return node->mParent->mBox;
     
-	AxisAlignedBox3 box(node->parent->mBbox);
-	if (node->parent->front == node)
-		box.SetMin(node->parent->axis, node->parent->position);
+	AxisAlignedBox3 box(node->mParent->mBox);
+	if (node->mParent->mFront == node)
+		box.SetMin(node->mParent->mAxis, node->mParent->mPosition);
 	else
-		box.SetMax(node->parent->axis, node->parent->position);
-	return mBbox;
+		box.SetMax(node->mParent->mAxis, node->mParent->mPosition);
+
+	return box;
 }
 
@@ -1575,2 +1543,7 @@
 	return GetPvsSize(mRoot, mBox);
 }
+
+const VspKdStatistics &VspKdTree::GetStatistics() const 
+{
+	return mStat;
+}
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 384)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.cpp	(revision 419)
@@ -27,4 +27,9 @@
 		return NULL;
 	}
+}
+
+const ViewCellPvs &ViewCell::GetPvs() const
+{
+	return mPvs;
 }
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 414)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h	(revision 419)
@@ -770,5 +770,6 @@
 
 public:
-	/// Parses the environment and stores the global BSP tree parameters
+	/** Parses the environment and stores the global BSP tree parameters
+	*/
 	static void ParseEnvironment();
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 414)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Environment.cpp	(revision 419)
@@ -1315,9 +1315,4 @@
 	  "20");
 
-  RegisterOption("ViewCells.maxViewCells",
-	  optInt,
-	  "-view_cells_max_viewcells=",
-	  "0");
-  
   RegisterOption("BspTree.Visualization.samples",
 	  optInt,
Index: trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 411)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/ViewCell.h	(revision 419)
@@ -23,6 +23,7 @@
 	*/
 	ViewCell(Mesh *mesh);
-	/** Returns PvS. 
+	/** Returns Pvs. 
 	*/
+	const ViewCellPvs &GetPvs() const;
 	ViewCellPvs &GetPvs();
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp	(revision 418)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp	(revision 419)
@@ -183,5 +183,7 @@
     mStat.avgRtWithoutOverhead = renderTime;
 	mStat.avgRenderTime = renderTime + loadPvsOverhead;
-	
+	mStat.maxCost /= pCrossVcTotal;
+	mStat.minCost /= pCrossVcTotal;
+
 	mStat.Stop();
 
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 416)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp	(revision 419)
@@ -30,20 +30,8 @@
 {
 	X3dParser parser;
-	int maxViewCells = 0;
+	
 	environment->GetFloatValue("ViewCells.height", parser.mViewCellHeight);
-	environment->GetIntValue("ViewCells.maxViewCells", maxViewCells);
-
-	bool loaded = parser.ParseFile(filename, mViewCells);
-
-	if (maxViewCells > 0)
-	{
-		while (mViewCells.size() > maxViewCells)
-		{
-			ViewCell *vc = mViewCells.back();
-			DEL_PTR(vc);
-			mViewCells.pop_back();
-		}
-	}
-	return loaded;
+	
+	return parser.ParseFile(filename, mViewCells);
 }
 
@@ -121,23 +109,6 @@
 }
 
-bool
-Preprocessor::GenerateViewCells()
-{
-	// TODO
-	// HACK: derive view cells from the scene objects
-	ObjectContainer objects;
-
-	int maxViewCells = 0;
-	environment->GetIntValue("ViewCells.maxViewCells", maxViewCells);
-
-	mSceneGraph->CollectObjects(&objects);
-	ViewCell::DeriveViewCells(objects, mViewCells, maxViewCells);
-
-	return true;
-}
-
 int
-SplitFilenames(const string str,
-							 vector<string> &filenames)
+SplitFilenames(const string str, vector<string> &filenames)
 {
 	int pos = 0;
Index: trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 409)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/main.cpp	(revision 419)
@@ -24,4 +24,5 @@
   MeshKdTree::ParseEnvironment();
   BspTree::ParseEnvironment();
+  VspKdTree::ParseEnvironment();
 
   char buff[128];
@@ -66,14 +67,9 @@
 	  if (BspTree::sConstructionMethod == BspTree::FROM_INPUT_VIEW_CELLS)
 	  {
-		   // view cells input file name
+		  // view cells input file name
 		  environment->GetStringValue("ViewCells.filename", buff);
 		  string vcFilename(buff);
-
-		  if (vcFilename != "")
-			  p->LoadViewCells(vcFilename);
-		  else
-			  p->GenerateViewCells();
-
-		  Debug << "Viewcells loaded / generated. Number of view cells: " << (int)p->mViewCells.size() << endl;
+		  p->LoadViewCells(vcFilename);
+		  Debug << (int)p->mViewCells.size() << " view cells loaded" << endl;
 	  }
 	
Index: trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 418)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/X3dExporter.cpp	(revision 419)
@@ -585,8 +585,6 @@
 bool X3dExporter::ExportVspKdTree(const VspKdTree &tree)
 {
-	 if (mExportRayDensity) 
-	 {
-		 return ExportKdTreeRayDensity(tree);
-	 }
+	 /*if (mExportRayDensity) {	 
+	 return ExportKdTreeRayDensity(tree); }*/
      
 	 stack<VspKdTreeNode *> tStack;
@@ -626,6 +624,6 @@
 		 {
 			 VspKdTreeInterior *interior = dynamic_cast<VspKdTreeInterior *>(node);
-			 tStack.push(interior->mFront);
-			 tStack.push(interior->mBack);
+			 tStack.push(interior->GetFront());
+			 tStack.push(interior->GetBack());
 		 }
 	 }
Index: trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 411)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.h	(revision 419)
@@ -46,12 +46,4 @@
   */
   virtual bool LoadViewCells(const string filename);
-  
-  /** Generate the viewCells automatically. The particular algorithm to be used depends
-      on the environment setting. Initially the generated viewcells will cover the whole
-      bounding volume of the scene. They can be pruned later depending on the results
-      of visibility computations.
-      @return true on successful viewcell generation.
-  */
-  virtual bool GenerateViewCells();
   
   /** Export all preprocessed data in a XML format understandable by the
Index: trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h	(revision 418)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h	(revision 419)
@@ -115,4 +115,5 @@
 public:
 
+	friend class VspKdTree;
 #define USE_FIXEDPOINT_T 1
 
@@ -233,13 +234,13 @@
   
   // link to the parent
-  VspKdTreeInterior *parent;
+  VspKdTreeInterior *mParent;
 
   enum {SPLIT_X=0, SPLIT_Y, SPLIT_Z, SPLIT_DIRX, SPLIT_DIRY, SPLIT_DIRZ};
   
   // splitting axis
-  char axis;
+  char mAxis;
 	
   // depth
-  unsigned char depth;
+  unsigned char mDepth;
   
   //  short depth;
@@ -251,13 +252,14 @@
   
   virtual ~VspKdTreeNode() {};
-  virtual int Type() const  = 0;
-  
-
-  bool IsLeaf() const { return axis == -1; }
+  virtual int Type() const = 0;
+  
+
+  bool IsLeaf() const { return mAxis == -1; }
   
   virtual void Print(ostream &s) const = 0;
 
-  virtual int GetAccessTime() {
-    return 0x7FFFFFF;
+  virtual int GetAccessTime() 
+  {
+	  return 0x7FFFFFF;
   }
 
@@ -272,14 +274,18 @@
 {
 public:
-	
+	friend class VspKdTree;
+
 	VspKdTreeInterior(VspKdTreeInterior *p);
 			
 	virtual int GetAccessTime();
 	
-	virtual int Type();
+	virtual int Type() const;
   
 	virtual ~VspKdTreeInterior();
     
 	virtual void Print(ostream &s) const;
+
+	inline VspKdTreeNode *GetBack() const;
+	inline VspKdTreeNode *GetFront() const;
 
 protected:
@@ -299,5 +305,5 @@
 
 	// the bbox of the node
-	AxisAlignedBox3 mBbox;
+	AxisAlignedBox3 mBox;
 
 	// data for caching
@@ -310,9 +316,9 @@
 // KD-tree node - leaf node
 // --------------------------------------------------------------
-class VspKdTreeLeaf : public VspKdTreeNode
+class VspKdTreeLeaf: public VspKdTreeNode
 {
-private:
-	int mPvsSize;
 public:
+	friend class VspKdTree;
+
 	static int mailID;
 	int mailbox;
@@ -386,10 +392,11 @@
 		return sqr(GetPvsSize()/((float)rays.size() + Limits::Small));
 	}
-
+private:
+	int mPvsSize;
 };
 
 // Inline functions
 inline VspKdTreeNode::VspKdTreeNode(VspKdTreeInterior *p):
-parent(p), axis(-1), depth(p ? p->depth + 1 : 0) 
+mParent(p), mAxis(-1), mDepth(p ? p->mDepth + 1 : 0) 
 {}
 
@@ -430,17 +437,17 @@
 	struct TraversalData
 	{  
-		VspKdTreeNode *node;
-		AxisAlignedBox3 bbox;
-		int depth;
-		float priority;
+		VspKdTreeNode *mNode;
+		AxisAlignedBox3 mBox;
+		int mDepth;
+		float mPriority;
         
 		TraversalData() {}
 
 		TraversalData(VspKdTreeNode *n, const float p):
-		node(n), priority(p)
+		mNode(n), mPriority(p)
 		{}
 
 		TraversalData(VspKdTreeNode *n,	const AxisAlignedBox3 &b, const int d):
-		node(n), bbox(b), depth(d) {}
+		mNode(n), mBox(b), mDepth(d) {}
     
 		// comparator for the 
@@ -449,5 +456,5 @@
 			bool operator()(const TraversalData a, const TraversalData b) 
 			{
-				return a.priority < b.priority;
+				return a.mPriority < b.mPriority;
 			}
 		};
@@ -459,17 +466,17 @@
 		{
 			// return a.node->queries.size() < b.node->queries.size();
-			VspKdTreeLeaf *leafa = (VspKdTreeLeaf *) a.node;
-			VspKdTreeLeaf *leafb = (VspKdTreeLeaf *) b.node;
+			VspKdTreeLeaf *leafa = (VspKdTreeLeaf *) a.mNode;
+			VspKdTreeLeaf *leafb = (VspKdTreeLeaf *) b.mNode;
 #if 0
 			return
-				leafa->rays.size()*a.bbox.GetVolume()
+				leafa->rays.size()*a.mBox.GetVolume()
 				<
-				leafb->rays.size()*b.bbox.GetVolume();
+				leafb->rays.size()*b.mBox.GetVolume();
 #endif
 #if 1
 			return
-				leafa->GetPvsSize()*a.bbox.GetVolume()
+				leafa->GetPvsSize()*a.mBox.GetVolume()
 				<
-				leafb->GetPvsSize()*b.bbox.GetVolume();
+				leafb->GetPvsSize()*b.mBox.GetVolume();
 #endif
 #if 0
@@ -498,11 +505,11 @@
   struct RayTraversalData 
   {
-	  VspKdTreeNode::RayInfo rayData;
-	  VspKdTreeNode *node;
+	  VspKdTreeNode::RayInfo mRayData;
+	  VspKdTreeNode *mNode;
       
 	  RayTraversalData() {}
 	  
 	  RayTraversalData(VspKdTreeNode *n, const VspKdTreeNode::RayInfo &data):
-	  rayData(data), node(n) {}
+	  mRayData(data), mNode(n) {}
   };
 	
@@ -584,5 +591,5 @@
 						int &pvsFront);
 
-	AxisAlignedBox3 GetBBox(const VspKdTreeNode *node); 	
+	AxisAlignedBox3 GetBBox(VspKdTreeNode *node) const; 	
 
 	VspKdTreeNode * SubdivideLeaf(VspKdTreeLeaf *leaf,
@@ -620,29 +627,32 @@
 	int CollapseSubtree(VspKdTreeNode *sroot, const int time);
 
-	const VspKdStatistics &GetStatistics() const {
-		return mStat;
-	}
-	
-	
+	const VspKdStatistics &GetStatistics() const;
+	
+	int ReleaseMemory(const int time);
+
+	/** Parses the environment and stores the global BSP tree parameters
+	*/
+	static void ParseEnvironment();
+
 	/////////////////////////////
 	// Construction parameters
 
 	// max depth of the tree
-	int sTermMaxDepth;
+	static int sTermMaxDepth;
 
 	// minimal ratio of the volume of the cell and the query volume
-	float sTermMinSize;
+	static float sTermMinSize;
 
 	// minimal pvs per node to still get subdivided
-	int sTermMinPvs;
+	static int sTermMinPvs;
 
 	// minimal ray number per node to still get subdivided
-	int sTermMinRays;
+	static int sTermMinRays;
 	
 	// maximal cost ration to subdivide a node
-	float sTermMaxCostRatio;
+	static float sTermMaxCostRatio;
 	
 	// maximal contribution per ray to subdivide the node
-	float sTermMaxRayContribution;
+	static float sTermMaxRayContribution;
 
 protected:
Index: trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
===================================================================
--- trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 418)
+++ trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp	(revision 419)
@@ -573,5 +573,5 @@
 			if (exporter)
 			{
-				exporter->ExportBspLeaves(*mBspTree, 350/*stat.maxPvs*/);
+				exporter->ExportBspLeaves(*mBspTree, stat.maxPvs);
 				//exporter->ExportBspViewCellPartition(*mBspTree, 0);
 				delete exporter;
@@ -609,5 +609,5 @@
 			if (exporter)
 			{
-				exporter->ExportBspViewCellPartition(*mBspTree, 350/*stat.maxPvs*/);
+				exporter->ExportBspViewCellPartition(*mBspTree, stat.maxPvs);
 				//exporter->ExportBspViewCellPartition(*mBspTree, 0);
 				delete exporter;
