Index: GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/scripts/Preprocessor.vcproj	(revision 1006)
@@ -158,10 +158,4 @@
 			</File>
 			<File
-				RelativePath="..\src\FromPointVisibilityTree.cpp">
-			</File>
-			<File
-				RelativePath="..\src\FromPointVisibilityTree.h">
-			</File>
-			<File
 				RelativePath="..\src\glInterface.h">
 			</File>
@@ -176,5 +170,6 @@
 						Name="VCCustomBuildTool"
 						Description="Performing moc on $(InputName).h"
-						CommandLine="%qtdir%\bin\moc.exe $(InputDir)$(InputName).h -o $(InputDir)moc_$(InputName).cpp&#xA;"
+						CommandLine="%qtdir%\bin\moc.exe $(InputDir)$(InputName).h -o $(InputDir)moc_$(InputName).cpp
+"
 						Outputs="$(InputDir)moc_$(InputName).cpp"/>
 				</FileConfiguration>
@@ -307,5 +302,6 @@
 						Name="VCCustomBuildTool"
 						Description="Performing moc on $(InputName).h"
-						CommandLine="%qtdir%\bin\moc.exe $(InputDir)$(InputName).h -o $(InputDir)moc_$(InputName).cpp&#xA;"
+						CommandLine="%qtdir%\bin\moc.exe $(InputDir)$(InputName).h -o $(InputDir)moc_$(InputName).cpp
+"
 						Outputs="$(InputDir)moc_$(InputName).cpp"/>
 				</FileConfiguration>
@@ -321,5 +317,6 @@
 						Name="VCCustomBuildTool"
 						Description="Performing moc on $(InputName).h"
-						CommandLine="%qtdir%\bin\moc.exe $(InputDir)$(InputName).h -o $(InputDir)moc_$(InputName).cpp&#xA;"
+						CommandLine="%qtdir%\bin\moc.exe $(InputDir)$(InputName).h -o $(InputDir)moc_$(InputName).cpp
+"
 						Outputs="$(InputDir)moc_$(InputName).cpp"/>
 				</FileConfiguration>
@@ -461,8 +458,8 @@
 			</File>
 			<File
-				RelativePath="..\src\VspKdTree.cpp">
-			</File>
-			<File
-				RelativePath="..\src\VspKdTree.h">
+				RelativePath="..\src\VspOspTree.cpp">
+			</File>
+			<File
+				RelativePath="..\src\VspOspTree.h">
 			</File>
 			<File
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspKdTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspKdTree.cpp	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspKdTree.cpp	(revision 1006)
@@ -73,5 +73,5 @@
 
 /**************************************************************/
-/*                class VspKdNode implementation          */
+/*                class VspKdNode implementation              */
 /**************************************************************/
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.cpp	(revision 1006)
@@ -9,5 +9,4 @@
 #include "Polygon3.h"
 #include "VssRay.h"
-#include "VspKdTree.h"
 #include "VssTree.h"
 #include "VspBspTree.h"
@@ -590,6 +589,6 @@
 }
 
-
-bool VrmlExporter::ExportVspKdTree(const VspKdTree &tree, 
+#if 0
+bool VrmlExporter::ExportVspOspTree(const VspOspTree &tree, 
 								   const int maxPvs)
 {
@@ -662,5 +661,5 @@
 	return true;
 }
-
+#endif
 
 bool VrmlExporter::ExportKdTree(const KdTree &tree)
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 882)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 1006)
@@ -323,4 +323,5 @@
 };
 
+
 /** BSP interior node implementation 
 */
@@ -366,4 +367,5 @@
 	BspNode *mFront;
 };
+
 
 /** BSP leaf node implementation.
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1006)
@@ -124,5 +124,4 @@
 	Environment::GetSingleton()->GetIntValue("VspBspTree.nodePriorityQueueType", mNodePriorityQueueType);
 
-	Environment::GetSingleton()->GetBoolValue("ViewCells.PostProcess.emptyViewCellsMerge", mEmptyViewCellsMergeAllowed);
 	
 	char subdivisionStatsLog[100];
@@ -132,5 +131,5 @@
 	Environment::GetSingleton()->GetFloatValue("VspBspTree.Construction.minBand", mMinBand);
 	Environment::GetSingleton()->GetFloatValue("VspBspTree.Construction.maxBand", mMaxBand);
-	Environment::GetSingleton()->GetBoolValue("VspBspTree.Construction.useDrivingAxisForMaxCost", mUseDrivingAxisForMaxCost);
+	Environment::GetSingleton()->GetBoolValue("VspBspTree.Construction.useDrivingAxisForMaxCost", mUseDrivingAxisIfMaxCostViolated);
 
 	//-- debug output
@@ -161,9 +160,8 @@
 	Debug << "use random axis: " << mUseRandomAxis << endl;
 	Debug << "priority queue type: " << mNodePriorityQueueType << endl;
-	Debug << "empty view cells merge: " << mEmptyViewCellsMergeAllowed << endl;
 	Debug << "circulating axis: " << mCirculatingAxis << endl;
 	Debug << "minband: " << mMinBand << endl;
 	Debug << "maxband: " << mMaxBand << endl;
-	Debug << "use driving axis for max cost: " << mUseDrivingAxisForMaxCost << endl;
+	Debug << "use driving axis for max cost: " << mUseDrivingAxisIfMaxCostViolated << endl;
 
 	Debug << "Split plane strategy: ";
@@ -1194,5 +1192,6 @@
 		}
 	  
-		if (ray->mOriginObject) 
+		// only count termination objects?
+		if (1 && ray->mOriginObject) 
 		{
 			if (vc->AddPvsSample(ray->mOriginObject, ray->mPdf, contribution))
@@ -1482,5 +1481,5 @@
 	const float maxCostRatioForArbitraryAxis = 0.9f;
 
-	if (mUseDrivingAxisForMaxCost)
+	if (mUseDrivingAxisIfMaxCostViolated)
 		bestAxis = box.Size().DrivingAxis();
 	else
@@ -1523,12 +1522,5 @@
 											nPosition[axis]);			
 			}
-			
-			//-- split plane position is spatial median
-
-
-			// also use median split if cost ratio very low as
-			// there are not enough visibility cues
-			//if (!mUseCostHeuristics || (nCostRatio[axis] > maxCostRatioForHeur))
-			else 
+			else //-- split plane position is spatial median
 			{
 
@@ -1578,5 +1570,5 @@
 						
 			
-			if (mUseDrivingAxisForMaxCost)
+			if (mUseDrivingAxisIfMaxCostViolated)
 			{
 				// we take longest axis split if cost ratio exceeds threshold
@@ -1710,5 +1702,7 @@
 	}
 
+
 	//-- evaluate axis aligned splits
+	
 	int axis;
 	BspNodeGeometry *fGeom, *bGeom;
@@ -1717,5 +1711,6 @@
 	candidateCost = 99999999.0f;
 
-	// option: axis aligned split only if no polygon available
+	// as a variant, we take axis aligned split only if there is 
+	// more polygon available to guide the split
 	if (!mUsePolygonSplitIfAvailable || data.mPolygons->empty())
 	{
@@ -1932,8 +1927,8 @@
 
 #if 1
-	// take render cost of node into account
+	// take render cost of node into account to avoid being stuck in a local minimum
 	const float normalizedOldRenderCost = oldRenderCost / mBox.GetVolume();
+	
 	//Debug << "rendercostdecr: " << 0.99f * renderCostDecrease << " old render cost: " << 0.01f * normalizedOldRenderCost << endl;
-	//return 0.5f * renderCostDecrease + 0.5f * normalizedOldRenderCost;
 	return 0.99f * renderCostDecrease + 0.01f * normalizedOldRenderCost;
 #else
@@ -1956,6 +1951,8 @@
 	float pvsBack = 0;
 	
+	// overall probability is used as normalizer
+	float pOverall = 0;
+
 	// probability that view point lies in back / front node
-	float pOverall = 0;
 	pFront = 0;
 	pBack = 0;
@@ -3532,7 +3529,4 @@
 
 
-typedef pair<BspNode *, BspNodeGeometry *> bspNodePair;
-
-
 int VspBspTree::CastBeam(Beam &beam)
 {
@@ -3656,8 +3650,5 @@
 				MergeCandidate mc(leaf->GetViewCell(), (*nit)->GetViewCell());
 
-				// dont't merge view cells if they are empty and not front and back leaf of the same parent
-				// in the tree?
-				if (mEmptyViewCellsMergeAllowed ||
-					!leaf->GetViewCell()->GetPvs().Empty() || 
+				if (!leaf->GetViewCell()->GetPvs().Empty() || 
 					!(*nit)->GetViewCell()->GetPvs().Empty() ||
                     leaf->IsSibling(*nit))
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.h	(revision 1006)
@@ -19,9 +19,8 @@
 class BspTree;
 class KdTree;
-class VspKdTree;
+class VspOspTree;
 class VspBspTree;
 class KdNode;
 class KdLeaf;
-class VspKdTree;
 class AxisAlignedBox3;
 class BspLeaf;
@@ -813,71 +812,4 @@
 
 /**
-	Manages different higher order operations on the view cells 
-	for vsp kd tree view cells.
-*/
-class VspKdViewCellsManager: public ViewCellsManager
-{
-
-public:
-
-	VspKdViewCellsManager(VspKdTree *vspKdTree);
-
-	int ConstructSubdivision(const ObjectContainer &objects, 
-				  const VssRayContainer &rays);
-
-
-	int PostProcess(const ObjectContainer &objects, 
-					const VssRayContainer &rays);
-
-	void Visualize(const ObjectContainer &objects,
-				   const VssRayContainer &sampleRays);
-
-	int GetType() const;
-	
-	bool ViewCellsConstructed() const;
-
-	//virtual void PrintStatistics(ostream &s) const;
-
-	ViewCell *GenerateViewCell(Mesh *mesh) const;
-
-
-    int CastLineSegment(const Vector3 &origin,
-						const Vector3 &termination,
-						ViewCellContainer &viewcells);
-
-	ViewCell *GetViewCell(const Vector3 &point, const bool active = false) const { return NULL; }
-
-	float GetProbability(ViewCell *viewCell);
-
-
-	void CreateMesh(ViewCell *vc);
-
-	void ExportViewCellGeometry(Exporter *exporter, 
-								ViewCell *vc,
-								const Plane3 *clipPlane = NULL) const;
-
-	void CollectMergeCandidates(const VssRayContainer &rays, vector<MergeCandidate> &candidates);
-
-	virtual void UpdatePvsForEvaluation(ViewCell *root, ObjectPvs &pvs) {};
-
-
-protected:
-
-	void ExportLeaves(const ObjectContainer &objects,
-					  const VssRayContainer &sampleRays);
-
-	void CollectViewCells();
-
-	void ExportColor(Exporter *exporter, ViewCell *vc) const;
-
-
-
-	/// the BSP tree.
-	VspKdTree *mVspKdTree;
-};
-
-
-
-/**
 	Manages different higher order operations on the view cells.
 */
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1006)
@@ -1374,9 +1374,4 @@
 					"boxes.out");
 
-	RegisterOption("ViewCells.PostProcess.emptyViewCellsMerge",
-					optBool,
-					"view_cells_merge_empty=",
-					"true");
-
 	RegisterOption("ViewCells.evaluateViewCells",
 					optBool,
@@ -1739,127 +1734,4 @@
 
 
-	/**************************************************************************************/
-	/*                  View space partition KD tree related options                      */
-	/**************************************************************************************/
-
-	RegisterOption("VspKdTree.Construction.samples",
-					optInt,
-					"vsp_kd_construction_samples=",
-					"100000");
-
-	RegisterOption("VspKdTree.Termination.maxDepth", 
-		optInt, 
-		"vsp_term_maxdepth=", 
-		"30");
-
-	RegisterOption("VspKdTree.Termination.minPvs", 
-		optInt, 
-		"vsp_minpvs=", 
-		"1");
-
-	RegisterOption("VspKdTree.Termination.minRays", 
-		optInt, 
-		"vsp_term_minrays=", 
-		"10");
-
-	RegisterOption("VspKdTree.Termination.minSize", 
-		optFloat, 
-		"vsp_term_minsize=", 
-		"0.001");
-
-	RegisterOption("VspKdTree.Termination.maxCostRatio", 
-		optFloat, 
-		"vsp_term_maxcost=",
-		"0.95");
-
-	RegisterOption("VspKdTree.Termination.maxRayContribution", 
-		optFloat, 
-		"vsp_term_max_ray_contrib=", 
-		"0.5");
-
-	RegisterOption("VspKdTree.epsilon", 
-		optFloat, 
-		"kd_eps=", 
-		"1e-6");
-
-	RegisterOption("VspKdTree.ct_div_ci", 
-		optFloat, 
-		"vsp_ctdivci=", "1.0");
-
-	RegisterOption("VspKdTree.splitType", 
-		optString, 
-		"split=", 
-		"queries");
-
-	RegisterOption("VspKdTree.splitAxis", 
-		optString, 
-		"split=", 
-		"drivingAxis");
-
-	RegisterOption("VspKdTree.splitUseOnlyDrivingAxis", 
-		optBool, 
-		"vsp_kd_splitdriving=", 
-		"false");
-
-	RegisterOption("VspKdTree.numberOfEndPointDomains", 
-		optInt, 
-		"endpoints=", 
-		"10000");
-
-	RegisterOption("VspKdTree.maxTotalMemory", 
-		optFloat, 
-		"vsp_max_total_mem=", 
-		"60.0");
-
-	RegisterOption("VspKdTree.maxStaticMemory", 
-		optFloat, 
-		"vsp_max_static_mem=", 
-		"8.0");
-
-	RegisterOption("VspKdTree.queryType", 
-		optString, 
-		"qtype=", 
-		"static");
-
-	RegisterOption("VspKdTree.queryPosWeight", 
-		optFloat, 
-		"vsp_kd_qposweight=", 
-		"0.0");
-
-	RegisterOption("VspKdTree.accessTimeThreshold", 
-		optInt, 
-		"vsp_kd_accesstime=", 
-		"1000");
-
-	RegisterOption("VspKdTree.minCollapseDepth", 
-		optInt, 
-		"vsp_kd_min_colldepth=", 
-		"4");
-
-	RegisterOption("VspKdTree.PostProcess.maxCostRatio",
-			optFloat,
-			"vsp_kd_post_process_max_cost_ratio=",
-			"0.9");
-
-	RegisterOption("VspKdTree.PostProcess.minViewCells", 
-		optInt, 
-		"vsp_kd_term_post_process_min_view_cells=", 
-		"1000");
-
-	RegisterOption("VspKdTree.Termination.maxViewCells", 
-		optInt, 
-		"vsp_kd_term_post_process_min_view_cells=", 
-		"300");
-
-	RegisterOption("VspKdTree.PostProcess.maxPvsSize", 
-		optInt, 
-		"vsp_kd_term_post_process_max_pvs_size=", 
-		"100");
-
-	RegisterOption("VspKdTree.Termination.missTolerance",
-			optInt,
-			"vsp_kd_term_miss_tolerance=",
-			"4");
-
 	/************************************************************************************/
 	/*                   VSS Preprocessor cells related options                         */
Index: GTP/trunk/Lib/Vis/Preprocessing/src/FromPointVisibilityTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/FromPointVisibilityTree.h	(revision 1002)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/FromPointVisibilityTree.h	(revision 1006)
@@ -827,8 +827,8 @@
 	int mNodePriorityQueueType;
 
-	bool mEmptyViewCellsMergeAllowed;
-
 	// priority queue strategy
 	enum {BREATH_FIRST, DEPTH_FIRST, COST_BASED};
+
+
 private:
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 863)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Exporter.h	(revision 1006)
@@ -16,5 +16,4 @@
 class KdTree;
 class BspTree;
-class VspKdTree;
 class SceneGraphNode;
 class Ray;
@@ -64,7 +63,4 @@
 				 const Vector3 direction
 				 ) = 0;
-
-  virtual bool
-  ExportVspKdTree(const VspKdTree &tree, const int maxPvs = 0) = 0;
 
   virtual bool
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RenderSimulator.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RenderSimulator.cpp	(revision 863)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RenderSimulator.cpp	(revision 1006)
@@ -4,5 +4,4 @@
 #include "ViewCell.h"
 #include "VspBspTree.h"
-#include "VspKdTree.h"
 #include "ViewCellsManager.h"
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.cpp	(revision 1006)
@@ -9,5 +9,4 @@
 #include "ViewCellBsp.h"
 #include "VspBspTree.h"
-#include "VspKdTree.h"
 #include "RenderSimulator.h"
 #include "GlRenderer.h"
@@ -113,5 +112,4 @@
 mKdTree(NULL),
 mBspTree(NULL),
-mVspKdTree(NULL),
 mVspBspTree(NULL),
 mViewCellsManager(NULL),
@@ -158,8 +156,10 @@
   DEL_PTR(mKdTree);
   cout << "done.\n";
-  
-  cout << "Deleting vspkd tree...\n";
-  DEL_PTR(mVspKdTree);
+ 
+#if 0
+  cout << "Deleting vsp osp tree...\n";
+  DEL_PTR(mVspOspTree);
   cout << "done.\n";
+#endif
 
   cout << "Deleting vspbsp tree...\n";
@@ -424,10 +424,11 @@
 		mViewCellsManager = new VspBspViewCellsManager(mVspBspTree);
 	}
-	else if (strcmp(name, "vspKdTree") == 0)
-	{
-		mVspKdTree = new VspKdTree();		
-	
-		mViewCellsManager = new VspKdViewCellsManager(mVspKdTree);
-	}
+#if 0
+	else if (strcmp(name, "vspOspTree") == 0)
+	{
+		mVspOspTree = new VspOspTree();		
+		mViewCellsManager = new VspOspViewCellsManager(mVspOspTree);
+	}
+#endif
 	else if (strcmp(name, "sceneDependent") == 0)
 	{
Index: GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.h	(revision 1001)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.h	(revision 1006)
@@ -59,8 +59,8 @@
 				 const Vector3 direction
 				 );
-
+#if VSP_OPS
   bool
-  ExportVspKdTree(const VspKdTree &tree, const int maxPvs);
-
+  ExportVspOspTree(const VspOspTree &tree, const int maxPvs);
+#endif
   bool ExportBspTree(const BspTree &tree);
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/X3dExporter.cpp	(revision 1006)
@@ -9,5 +9,5 @@
 #include "Polygon3.h"
 #include "VssRay.h"
-#include "VspKdTree.h"
+//#include "VspOspTree.h"
 #include "VssTree.h"
 #include "VspBspTree.h"
@@ -33,53 +33,4 @@
   stream.close();
 }
-
-
-//  bool
-//  X3dExporter::ExportRays(const vector<Ray> &rays,
-//  												const float length,
-//  												const RgbColor &color)
-//  {
-//    vector<Ray>::const_iterator ri = rays.begin();
-//    stream<<"<Shape>"<<endl;
-//    stream<<"<Appearance>"<<endl;
-//    stream<<"<Material ambientColor=\""<<color.r<<" "<<color.g<<" "<<color.b<<
-//      "\" />"<<endl;
-//    stream<<"</Appearance>"<<endl;
-  
-//    stream<<"<IndexedLineSet coordIndex=\""<<endl;
-
-//    int index = 0;
-//    for (; ri != rays.end(); ri++) {
-//      stream<<index<<" "<<index+1<<" -1\n";
-//      index+=2;
-//    }
-  
-//    stream<<"\" >"<<endl;
-  
-//    stream<<"<Coordinate  point=\""<<endl;
-  
-//    ri = rays.begin();
-//    for (; ri != rays.end(); ri++) {
-//      Vector3 a = (*ri).GetLoc();
-    
-//      Vector3 b;
-//      if (length < 0)
-//        b = (*ri).GetLoc() - length*(*ri).GetDir();
-//      else
-//        if ((*ri).intersections.size()==0)
-//  	b = (*ri).GetLoc() + length*(*ri).GetDir();
-//        else
-//  	b = (*ri).Extrap((*ri).intersections[0].mT);
-    
-//      stream<<a.x<<" "<<a.y<<" "<<a.z<<" ,";
-//      stream<<b.x<<" "<<b.y<<" "<<b.z<<" ,\n";
-//    }
-  
-//    stream<<"\" >"<<endl;
-//    stream<<"</Coordinate>"<<endl;
-//    stream<<"</IndexedLineSet>"<<endl;
-//    stream<<"</Shape>"<<endl;
-//    return true;
-//  }
 
 
@@ -459,4 +410,5 @@
 
 
+
 void X3dExporter::ExportPolygons(const PolygonContainer &polys)
 {
@@ -535,4 +487,5 @@
 	stream << "</Shape>" << endl;
 }
+
 
 bool
@@ -561,4 +514,5 @@
 }
 
+
 bool
 X3dExporter::ExportBspTree(const BspTree &tree)
@@ -584,5 +538,6 @@
 }
 
-bool X3dExporter::ExportVspKdTree(const VspKdTree &tree, const int maxPvs)
+#if 0
+bool X3dExporter::ExportVspOspTree(const VspOspTree &tree, const int maxPvs)
 {
 	stack<VspKdNode *> tStack;
@@ -654,5 +609,5 @@
 	return true;
 }
-
+#endif
 
 bool X3dExporter::ExportKdTree(const KdTree &tree)
@@ -696,7 +651,6 @@
   ExportMesh(mesh);
   delete mesh;
+
   return true;
-	// TODO
-	return true;
 }
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 904)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Preprocessor.h	(revision 1006)
@@ -17,5 +17,5 @@
 class ViewCellsManager;
 class BspTree;
-class VspKdTree;
+class VspOspTree;
 class VspBspTree;
 class RenderSimulator;
@@ -151,8 +151,6 @@
   ViewCellsManager *mViewCellsManager;
 
-  /** Kd tree inducing a coarse partition of view space that are the building
-	  blocks for view cells.
-  */
-  VspKdTree *mVspKdTree;
+  /// greedy optimized hierarchy for both objects and view cells
+  VspOspTree *mVspOspTree;
 
   bool mUseGlRenderer;
@@ -183,6 +181,6 @@
   /// samples used for construction of the BSP view cells tree.
   int mBspConstructionSamples;
-   /// samples used for construction of the VSP KD tree.
-  int mVspKdConstructionSamples;
+  /// samples used for construction of the VSP OSP tree.
+  int mVspOspConstructionSamples;
   /** Simulates rendering of the scene.
   */
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1002)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp	(revision 1006)
@@ -4,5 +4,5 @@
 
 #include "Plane3.h"
-#include "VspBspTree.h"
+#include "VspOspTree.h"
 #include "Mesh.h"
 #include "common.h"
@@ -25,10 +25,8 @@
 //-- static members
 
-
-int VspBspTree::sFrontId = 0;
-int VspBspTree::sBackId = 0;
-int VspBspTree::sFrontAndBackId = 0;
-
-typedef pair<BspNode *, BspNodeGeometry *> bspNodePair;
+int VspOspTree::sFrontId = 0;
+int VspOspTree::sBackId = 0;
+int VspOspTree::sFrontAndBackId = 0;
+
 
 
@@ -51,86 +49,62 @@
 
 /******************************************************************************/
-/*                       class VspBspTree implementation                      */
+/*                       class VspOspTree implementation                      */
 /******************************************************************************/
 
 
-VspBspTree::VspBspTree(Environment *env):
+VspOspTree::VspOspTree():
 mRoot(NULL),
-mUseAreaForPvs(false),
-mCostNormalizer(Limits::Small),
-mViewCellsManager(NULL),
 mOutOfBoundsCell(NULL),
 mStoreRays(false),
-mRenderCostWeight(0.5),
 mUseRandomAxis(false),
 mTimeStamp(1)
 {
 	bool randomize = false;
-	env->GetBoolValue("VspBspTree.Construction.randomize", randomize);
+	Environment::GetSingleton()->GetBoolValue("VspOspTree.Construction.randomize", randomize);
 	if (randomize)
 		Randomize(); // initialise random generator for heuristics
 
 	//-- termination criteria for autopartition
-	env->GetIntValue("VspBspTree.Termination.maxDepth", mTermMaxDepth);
-	env->GetIntValue("VspBspTree.Termination.minPvs", mTermMinPvs);
-	env->GetIntValue("VspBspTree.Termination.minRays", mTermMinRays);
-	env->GetFloatValue("VspBspTree.Termination.minProbability", mTermMinProbability);
-	env->GetFloatValue("VspBspTree.Termination.maxRayContribution", mTermMaxRayContribution);
-	env->GetFloatValue("VspBspTree.Termination.minAccRayLenght", mTermMinAccRayLength);
-	env->GetFloatValue("VspBspTree.Termination.maxCostRatio", mTermMaxCostRatio);
-	env->GetIntValue("VspBspTree.Termination.missTolerance", mTermMissTolerance);
-	env->GetIntValue("VspBspTree.Termination.maxViewCells", mMaxViewCells);
+	Environment::GetSingleton()->GetIntValue("VspOspTree.Termination.maxDepth", mTermMaxDepth);
+	Environment::GetSingleton()->GetIntValue("VspOspTree.Termination.minPvs", mTermMinPvs);
+	Environment::GetSingleton()->GetIntValue("VspOspTree.Termination.minRays", mTermMinRays);
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.Termination.minProbability", mTermMinProbability);
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.Termination.maxRayContribution", mTermMaxRayContribution);
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.Termination.maxCostRatio", mTermMaxCostRatio);
+	Environment::GetSingleton()->GetIntValue("VspOspTree.Termination.missTolerance", mTermMissTolerance);
+	Environment::GetSingleton()->GetIntValue("VspOspTree.Termination.maxViewCells", mMaxViewCells);
 
 	//-- max cost ratio for early tree termination
-	env->GetFloatValue("VspBspTree.Termination.maxCostRatio", mTermMaxCostRatio);
-
-	env->GetFloatValue("VspBspTree.Termination.minGlobalCostRatio", mTermMinGlobalCostRatio);
-	env->GetIntValue("VspBspTree.Termination.globalCostMissTolerance", mTermGlobalCostMissTolerance);
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.Termination.maxCostRatio", mTermMaxCostRatio);
+
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.Termination.minGlobalCostRatio", mTermMinGlobalCostRatio);
+	Environment::GetSingleton()->GetIntValue("VspOspTree.Termination.globalCostMissTolerance", mTermGlobalCostMissTolerance);
 
 	// HACK//mTermMinPolygons = 25;
 
 	//-- factors for bsp tree split plane heuristics
-	env->GetFloatValue("VspBspTree.Factor.pvs", mPvsFactor);
-	env->GetFloatValue("VspBspTree.Termination.ct_div_ci", mCtDivCi);
-
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.Termination.ct_div_ci", mCtDivCi);
 
 	//-- partition criteria
-	env->GetIntValue("VspBspTree.maxPolyCandidates", mMaxPolyCandidates);
-	env->GetIntValue("VspBspTree.maxRayCandidates", mMaxRayCandidates);
-	env->GetIntValue("VspBspTree.splitPlaneStrategy", mSplitPlaneStrategy);
-
-	env->GetFloatValue("VspBspTree.Construction.epsilon", mEpsilon);
-	env->GetIntValue("VspBspTree.maxTests", mMaxTests);
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.Construction.epsilon", mEpsilon);
 
 	// if only the driving axis is used for axis aligned split
-	env->GetBoolValue("VspBspTree.splitUseOnlyDrivingAxis", mOnlyDrivingAxis);
-	
-	//-- termination criteria for axis aligned split
-	env->GetFloatValue("VspBspTree.Termination.AxisAligned.maxRayContribution", 
-								mTermMaxRayContriForAxisAligned);
-	env->GetIntValue("VspBspTree.Termination.AxisAligned.minRays",
-							 mTermMinRaysForAxisAligned);
-
-	//env->GetFloatValue("VspBspTree.maxTotalMemory", mMaxTotalMemory);
-	env->GetFloatValue("VspBspTree.maxStaticMemory", mMaxMemory);
-
-	env->GetFloatValue("VspBspTree.Construction.renderCostWeight", mRenderCostWeight);
-	env->GetBoolValue("VspBspTree.usePolygonSplitIfAvailable", mUsePolygonSplitIfAvailable);
-
-	env->GetBoolValue("VspBspTree.useCostHeuristics", mUseCostHeuristics);
-	env->GetBoolValue("VspBspTree.useSplitCostQueue", mUseSplitCostQueue);
-	env->GetBoolValue("VspBspTree.simulateOctree", mCirculatingAxis);
-	env->GetBoolValue("VspBspTree.useRandomAxis", mUseRandomAxis);
-	env->GetIntValue("VspBspTree.nodePriorityQueueType", mNodePriorityQueueType);
-
-	env->GetBoolValue("ViewCells.PostProcess.emptyViewCellsMerge", mEmptyViewCellsMergeAllowed);
+	Environment::GetSingleton()->GetBoolValue("VspOspTree.splitUseOnlyDrivingAxis", mOnlyDrivingAxis);
+	
+	//Environment::GetSingleton()->GetFloatValue("VspOspTree.maxTotalMemory", mMaxTotalMemory);
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.maxStaticMemory", mMaxMemory);
+
+	Environment::GetSingleton()->GetBoolValue("VspOspTree.useCostHeuristics", mUseCostHeuristics);
+	Environment::GetSingleton()->GetBoolValue("VspOspTree.simulateOctree", mCirculatingAxis);
+	Environment::GetSingleton()->GetBoolValue("VspOspTree.useRandomAxis", mUseRandomAxis);
+	Environment::GetSingleton()->GetIntValue("VspOspTree.nodePriorityQueueType", mNodePriorityQueueType);
 	
 	char subdivisionStatsLog[100];
-	env->GetStringValue("VspBspTree.subdivisionStats", subdivisionStatsLog);
+	Environment::GetSingleton()->GetStringValue("VspOspTree.subdivisionStats", subdivisionStatsLog);
 	mSubdivisionStats.open(subdivisionStatsLog);
 
-	env->GetFloatValue("VspBspTree.Construction.minBand", mMinBand);
-	env->GetFloatValue("VspBspTree.Construction.maxBand", mMaxBand);
-	env->GetBoolValue("VspBspTree.Construction.useDrivingAxisForMaxCost", mUseDrivingAxisForMaxCost);
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.Construction.minBand", mMinBand);
+	Environment::GetSingleton()->GetFloatValue("VspOspTree.Construction.maxBand", mMaxBand);
+	
 
 	//-- debug output
@@ -145,52 +119,18 @@
 	Debug << "miss tolerance: " << mTermMissTolerance << endl;
 	Debug << "max view cells: " << mMaxViewCells << endl;
-	Debug << "max polygon candidates: " << mMaxPolyCandidates << endl;
-	//Debug << "max plane candidates: " << mMaxRayCandidates << endl;
 	Debug << "randomize: " << randomize << endl;
 
-	Debug << "using area for pvs: " << mUseAreaForPvs << endl;
-	Debug << "render cost weight: " << mRenderCostWeight << endl;
 	Debug << "min global cost ratio: " << mTermMinGlobalCostRatio << endl;
 	Debug << "global cost miss tolerance: " << mTermGlobalCostMissTolerance << endl;
 	Debug << "only driving axis: " << mOnlyDrivingAxis << endl;
 	Debug << "max memory: " << mMaxMemory << endl;
-	Debug << "use poly split if available: " << mUsePolygonSplitIfAvailable << endl;
 	Debug << "use cost heuristics: " << mUseCostHeuristics << endl;
-	Debug << "use split cost queue: " << mUseSplitCostQueue << endl;
 	Debug << "subdivision stats log: " << subdivisionStatsLog << endl;
 	Debug << "use random axis: " << mUseRandomAxis << endl;
 	Debug << "priority queue type: " << mNodePriorityQueueType << endl;
-	Debug << "empty view cells merge: " << mEmptyViewCellsMergeAllowed << endl;
 	Debug << "circulating axis: " << mCirculatingAxis << endl;
 	Debug << "minband: " << mMinBand << endl;
 	Debug << "maxband: " << mMaxBand << endl;
-	Debug << "use driving axis for max cost: " << mUseDrivingAxisForMaxCost << endl;
-
-	Debug << "Split plane strategy: ";
-
-	if (mSplitPlaneStrategy & RANDOM_POLYGON)
-	{
-		Debug << "random polygon ";
-	}
-	if (mSplitPlaneStrategy & AXIS_ALIGNED)
-	{
-		Debug << "axis aligned ";
-	}
-	if (mSplitPlaneStrategy & LEAST_RAY_SPLITS)
-	{
-		mCostNormalizer += mLeastRaySplitsFactor;
-		Debug << "least ray splits ";
-	}
-	if (mSplitPlaneStrategy & BALANCED_RAYS)
-	{
-		mCostNormalizer += mBalancedRaysFactor;
-		Debug << "balanced rays ";
-	}
-	if (mSplitPlaneStrategy & PVS)
-	{
-		mCostNormalizer += mPvsFactor;
-		Debug << "pvs";
-	}
-
+	
 
 	mSplitCandidates = new vector<SortableEntry>;
@@ -199,19 +139,6 @@
 }
 
-VspBspTree::VspBspTree():
-mRoot(NULL),
-mUseAreaForPvs(false),
-mCostNormalizer(Limits::Small),
-mViewCellsManager(NULL),
-mOutOfBoundsCell(NULL),
-mStoreRays(false),
-mRenderCostWeight(0.5),
-mUseRandomAxis(false),
-mTimeStamp(1),
-mEpsilon(1e-6f)
-{
-}
-
-BspViewCell *VspBspTree::GetOutOfBoundsCell()
+
+BspViewCell *VspOspTree::GetOutOfBoundsCell()
 {
 	return mOutOfBoundsCell;
@@ -219,5 +146,5 @@
 
 
-BspViewCell *VspBspTree::GetOrCreateOutOfBoundsCell()
+BspViewCell *VspOspTree::GetOrCreateOutOfBoundsCell()
 {
 	if (!mOutOfBoundsCell)
@@ -232,5 +159,5 @@
 
 
-const BspTreeStatistics &VspBspTree::GetStatistics() const
+const BspTreeStatistics &VspOspTree::GetStatistics() const
 {
 	return mBspStats;
@@ -238,5 +165,5 @@
 
 
-VspBspTree::~VspBspTree()
+VspOspTree::~VspOspTree()
 {
 	DEL_PTR(mRoot);
@@ -244,110 +171,5 @@
 }
 
-
-int VspBspTree::AddMeshToPolygons(Mesh *mesh,
-								  PolygonContainer &polys,
-								  MeshInstance *parent)
-{
-	FaceContainer::const_iterator fi;
-
-	// copy the face data to polygons
-	for (fi = mesh->mFaces.begin(); fi != mesh->mFaces.end(); ++ fi)
-	{
-		Polygon3 *poly = new Polygon3((*fi), mesh);
-
-		if (poly->Valid(mEpsilon))
-		{
-			poly->mParent = parent; // set parent intersectable
-			polys.push_back(poly);
-		}
-		else
-			DEL_PTR(poly);
-	}
-	return (int)mesh->mFaces.size();
-}
-
-
-int VspBspTree::AddToPolygonSoup(const ViewCellContainer &viewCells,
-								 PolygonContainer &polys,
-								 int maxObjects)
-{
-	int limit = (maxObjects > 0) ?
-		Min((int)viewCells.size(), maxObjects) : (int)viewCells.size();
-
-	int polysSize = 0;
-
-	for (int i = 0; i < limit; ++ i)
-	{
-		if (viewCells[i]->GetMesh()) // copy the mesh data to polygons
-		{
-			mBox.Include(viewCells[i]->GetBox()); // add to BSP tree aabb
-			polysSize +=
-				AddMeshToPolygons(viewCells[i]->GetMesh(),
-								  polys,
-								  viewCells[i]);
-		}
-	}
-
-	return polysSize;
-}
-
-
-int VspBspTree::AddToPolygonSoup(const ObjectContainer &objects,
-								 PolygonContainer &polys,
-								 int maxObjects)
-{
-	int limit = (maxObjects > 0) ?
-		Min((int)objects.size(), maxObjects) : (int)objects.size();
-
-	for (int i = 0; i < limit; ++i)
-	{
-		Intersectable *object = objects[i];//*it;
-		Mesh *mesh = NULL;
-
-		switch (object->Type()) // extract the meshes
-		{
-		case Intersectable::MESH_INSTANCE:
-			mesh = dynamic_cast<MeshInstance *>(object)->GetMesh();
-			break;
-		case Intersectable::VIEW_CELL:
-			mesh = dynamic_cast<ViewCell *>(object)->GetMesh();
-			break;
-		case Intersectable::TRANSFORMED_MESH_INSTANCE:
-			{
-				TransformedMeshInstance *mi = dynamic_cast<TransformedMeshInstance *>(object);
-
-				if (!mi->GetMesh())
-					break;
-
-				mesh = new Mesh(*mi->GetMesh());
-
-				Matrix4x4 m;
-				mi->GetWorldTransform(m);
-
-				mesh->ApplyTransformation(m);
-
-                break;
-			}
-		default:
-			Debug << "intersectable type not supported" << endl;
-			break;
-		}
-
-        if (mesh) // copy the mesh data to polygons
-		{
-			mBox.Include(object->GetBox()); // add to BSP tree aabb
-			AddMeshToPolygons(mesh, polys, NULL);
-
-			// cleanup
-			if (object->Type() == Intersectable::TRANSFORMED_MESH_INSTANCE)
-				DEL_PTR(mesh);
-		}
-	}
-
-	return (int)polys.size();
-}
-
-
-void VspBspTree::Construct(const VssRayContainer &sampleRays,
+void VspOspTree::Construct(const VssRayContainer &sampleRays,
 						   AxisAlignedBox3 *forcedBoundingBox)
 {
@@ -371,41 +193,4 @@
 	int numObj = 0;
 
-	//-- extract polygons intersected by the rays
-	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
-	{
-		VssRay *ray = *rit;
-
-		if ((mBox.IsInside(ray->mTermination) || !forcedBoundingBox) &&
-			ray->mTerminationObject && 
-			!ray->mTerminationObject->Mailed())
-		{
-			ray->mTerminationObject->Mail();
-			MeshInstance *obj = dynamic_cast<MeshInstance *>(ray->mTerminationObject);
-			AddMeshToPolygons(obj->GetMesh(), polys, obj);
-			++ numObj;
-
-			//-- compute bounding box
-			if (!forcedBoundingBox)
-				mBox.Include(ray->mTermination);
-		}
-
-		if ((mBox.IsInside(ray->mOrigin) || !forcedBoundingBox) &&
-			ray->mOriginObject && 
-			!ray->mOriginObject->Mailed())
-		{
-			ray->mOriginObject->Mail();
-			MeshInstance *obj = dynamic_cast<MeshInstance *>(ray->mOriginObject);
-			AddMeshToPolygons(obj->GetMesh(), polys, obj);
-			++ numObj;
-
-			//-- compute bounding box
-			if (!forcedBoundingBox)
-				mBox.Include(ray->mOrigin);
-		}
-	}
-	
-	Debug << "maximal pvs (i.e., pvs still considered as valid) : " 
-		  << mViewCellsManager->GetMaxPvsSize() << endl;
-
 	//-- store rays
 	for (rit = sampleRays.begin(); rit != rit_end; ++ rit)
@@ -430,42 +215,20 @@
 	}
 
-	// normalize
-	if (mUseAreaForPvs)
-		mTermMinProbability *= mBox.SurfaceArea(); 
-	else 
-		mTermMinProbability *= mBox.GetVolume();
-
-	// throw out unnecessary polygons
-	PreprocessPolygons(polys);
-
-	mBspStats.polys = (int)polys.size();
+	mTermMinProbability *= mBox.GetVolume();
+
 	mGlobalCostMisses = 0;
 
 	cout << "finished" << endl;
 
-	Debug << "\nPolygon extraction: " << (int)polys.size() << " polys extracted from "
-		  << (int)sampleRays.size() << " rays in "
-		  << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl << endl;
-
 	// use split cost priority queue
-	if (mUseSplitCostQueue)
-	{
-		ConstructWithSplitQueue(polys, rays);
-	}
-	else
-	{
-		Construct(polys, rays);
-	}
-
-	// clean up polygons
-	CLEAR_CONTAINER(polys);
+	Construct(rays);
 }
 
 
 // TODO: return memory usage in MB
-float VspBspTree::GetMemUsage() const
+float VspOspTree::GetMemUsage() const
 {
 	return (float)
-		 (sizeof(VspBspTree) + 
+		 (sizeof(VspOspTree) + 
 		  mBspStats.Leaves() * sizeof(BspLeaf) + 
 		  mCreatedViewCells * sizeof(BspViewCell) +
@@ -476,137 +239,22 @@
 
 
-
-void VspBspTree::Construct(const PolygonContainer &polys, RayInfoContainer *rays)
-{
-	VspBspTraversalQueue tQueue;
+void VspOspTree::Construct(RayInfoContainer *rays)
+{
+	VspOspSplitQueue tQueue;
 
 	mRoot = new BspLeaf();
 
-	// constrruct root node geometry
-	BspNodeGeometry *geom = new BspNodeGeometry();
-	ConstructGeometry(mRoot, *geom);
-
-	const float prop = mUseAreaForPvs ? geom->GetArea() : geom->GetVolume();
-
-	VspBspTraversalData tData(mRoot,
-							  new PolygonContainer(polys),
+	const float prop = mBox.GetVolume();
+
+	VspOspTraversalData tData(mRoot,
 							  0,
 							  rays,
                               ComputePvsSize(*rays),
 							  prop,
-							  geom);
-
-	EvalPriority(tData);
-
-
-	// first node is kd node, i.e. an axis aligned box
-	if (1)
-        tData.mIsKdNode = true;
-	else
-		tData.mIsKdNode = false;
-
-	tQueue.push(tData);
-
-
-	mTotalCost = tData.mPvs * tData.mProbability / mBox.GetVolume();
-	mTotalPvsSize = tData.mPvs;
-	
-	mSubdivisionStats 
-			<< "#ViewCells\n1" <<  endl
-			<< "#RenderCostDecrease\n0" << endl 
-			<< "#TotalRenderCost\n" << mTotalCost << endl
-			<< "#AvgRenderCost\n" << mTotalPvsSize << endl;
-
-	Debug << "total cost: " << mTotalCost << endl;
-	
-	
-	mBspStats.Start();
-	cout << "Constructing vsp bsp tree ... \n";
-
-	long startTime = GetTime();	
-	int nLeaves = 500;
-	int nViewCells = 500;
-
-	// used for intermediate time measurements and progress
-	long interTime = GetTime();	
-
-	mOutOfMemory = false;
-
-	mCreatedViewCells = 0;
-	
-	while (!tQueue.empty())
-	{
-		tData = tQueue.top();
-	    tQueue.pop();		
-
-		if (0 && !mOutOfMemory)
-		{
-			float mem = GetMemUsage();
-
-			if (mem > mMaxMemory)
-			{
-				mOutOfMemory = true;
-				Debug << "memory limit reached: " << mem << endl;
-			}
-		}
-
-		// subdivide leaf node
-		BspNode *r = Subdivide(tQueue, tData);
-
-		if (r == mRoot)
-			Debug << "VSP BSP tree construction time spent at root: "
-				  << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
-
-		if (mBspStats.Leaves() >= nLeaves)
-		{
-			nLeaves += 500;
-
-			cout << "leaves=" << mBspStats.Leaves() << endl;
-			Debug << "needed "
-				  << TimeDiff(interTime, GetTime())*1e-3 
-				  << " secs to create 500 view cells" << endl;
-			interTime = GetTime();
-		}
-
-		if (mCreatedViewCells >= nViewCells)
-		{
-			nViewCells += 500;
-
-			cout << "generated " << mCreatedViewCells << " viewcells" << endl;
-		}
-	}
-
-	Debug << "Used Memory: " << GetMemUsage() << " MB" << endl << endl;
-	cout << "finished\n";
-
-	mBspStats.Stop();
-}
-
-
-
-void VspBspTree::ConstructWithSplitQueue(const PolygonContainer &polys, 
-											  RayInfoContainer *rays)
-{
-	VspBspSplitQueue tQueue;
-
-	mRoot = new BspLeaf();
-
-	// constrruct root node geometry
-	BspNodeGeometry *geom = new BspNodeGeometry();
-	ConstructGeometry(mRoot, *geom);
-
-	const float prop = mUseAreaForPvs ? geom->GetArea() : geom->GetVolume();
-
-	VspBspTraversalData tData(mRoot,
-							  new PolygonContainer(polys),
-							  0,
-							  rays,
-                              ComputePvsSize(*rays),
-							  prop,
-							  geom);
+							  mBox);
 
 
 	// compute first split candidate
-	VspBspSplitCandidate splitCandidate;
+	VspOspSplitCandidate splitCandidate;
 	EvalSplitCandidate(tData, splitCandidate);
 
@@ -697,5 +345,5 @@
 
 
-bool VspBspTree::LocalTerminationCriteriaMet(const VspBspTraversalData &data) const
+bool VspOspTree::LocalTerminationCriteriaMet(const VspOspTraversalData &data) const
 {
 	return
@@ -708,5 +356,5 @@
 
 
-bool VspBspTree::GlobalTerminationCriteriaMet(const VspBspTraversalData &data) const
+bool VspOspTree::GlobalTerminationCriteriaMet(const VspOspTraversalData &data) const
 {
 	return
@@ -718,152 +366,9 @@
 
 
-
-BspNode *VspBspTree::Subdivide(VspBspTraversalQueue &tQueue,
-							   VspBspTraversalData &tData)
-{
-	BspNode *newNode = tData.mNode;
-
-	if (!LocalTerminationCriteriaMet(tData) && !GlobalTerminationCriteriaMet(tData))
-	{
-		PolygonContainer coincident;
-
-		VspBspTraversalData tFrontData;
-		VspBspTraversalData tBackData;
-
-		// create new interior node and two leaf nodes
-		// or return leaf as it is (if maxCostRatio missed)
-		int splitAxis;
-		bool splitFurther = true;
-		int maxCostMisses = tData.mMaxCostMisses;
-		
-		Plane3 splitPlane;
-		BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode);
-		
-		// choose next split plane
-		if (!SelectPlane(splitPlane, leaf, tData, tFrontData, tBackData, splitAxis))
-		{
-			++ maxCostMisses;
-
-			if (maxCostMisses > mTermMissTolerance)
-			{
-				// terminate branch because of max cost
-				++ mBspStats.maxCostNodes;
-				splitFurther = false;
-			}
-		}
-	
-		// if this a valid split => subdivide this node further
-		if (splitFurther) //-- continue subdivision
-		{
-			newNode = SubdivideNode(splitPlane, tData, tFrontData, tBackData, coincident);
-
-			if (splitAxis < 3)
-				++ mBspStats.splits[splitAxis];
-			else
-				++ mBspStats.polySplits;
-
-			// if it was a kd node (i.e., a box) and the split axis is axis aligned, it is still a kd node
-			tFrontData.mIsKdNode = tBackData.mIsKdNode = (tData.mIsKdNode && (splitAxis < 3));
-			tFrontData.mAxis = tBackData.mAxis = splitAxis;
-
-			// how often was max cost ratio missed in this branch?
-			tFrontData.mMaxCostMisses = maxCostMisses;
-			tBackData.mMaxCostMisses = maxCostMisses;
-
-			EvalPriority(tFrontData);
-			EvalPriority(tBackData);
-
-			// evaluate subdivision stats
-			if (1)
-			{
-				float cFront = (float)tFrontData.mPvs * tFrontData.mProbability;
-				float cBack = (float)tBackData.mPvs * tBackData.mProbability;
-				float cData = (float)tData.mPvs * tData.mProbability;;
-
-                float costDecr = (cFront + cBack - cData) / mBox.GetVolume();
-
-				mTotalCost += costDecr;
-				mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs;
-
-				mSubdivisionStats 
-						<< "#ViewCells\n" << mBspStats.Leaves() << endl
-						<< "#RenderCostDecrease\n" << -costDecr << endl 
-						<< "#TotalRenderCost\n" << mTotalCost << endl
-						<< "#AvgRenderCost\n" << (float)mTotalPvsSize / (float)mBspStats.Leaves() << endl;
-			}
-
-			// push the children on the stack
-			tQueue.push(tFrontData);
-			tQueue.push(tBackData);
-
-			// delete old leaf node
-			DEL_PTR(tData.mNode);
-		}
-	}
-
-	//-- terminate traversal and create new view cell
-	if (newNode->IsLeaf())
-	{
-		BspLeaf *leaf = dynamic_cast<BspLeaf *>(newNode);
-		BspViewCell *viewCell = new BspViewCell();
-		
-		leaf->SetViewCell(viewCell);
-	
-		//-- update pvs
-		int conSamp = 0;
-		float sampCon = 0.0f;
-		AddToPvs(leaf, *tData.mRays, sampCon, conSamp);
-
-		// update scalar pvs size lookup
-		mViewCellsManager->SetScalarPvsSize(viewCell, viewCell->GetPvs().GetSize());
-	
-
-		mBspStats.contributingSamples += conSamp;
-		mBspStats.sampleContributions +=(int) sampCon;
-
-		//-- store additional info
-		if (mStoreRays)
-		{
-			RayInfoContainer::const_iterator it, it_end = tData.mRays->end();
-			for (it = tData.mRays->begin(); it != it_end; ++ it)
-			{
-				(*it).mRay->Ref();			
-				leaf->mVssRays.push_back((*it).mRay);
-			}
-		}
-
-		// should I check here?
-		if (0 && !mViewCellsManager->CheckValidity(viewCell, 0, mViewCellsManager->GetMaxPvsSize()))
-		{
-			viewCell->SetValid(false);
-			leaf->SetTreeValid(false);
-			PropagateUpValidity(leaf);
-
-			++ mBspStats.invalidLeaves;
-		}
-		
-        viewCell->mLeaf = leaf;
-
-		if (mUseAreaForPvs)
-			viewCell->SetArea(tData.mProbability);
-		else
-			viewCell->SetVolume(tData.mProbability);
-
-		leaf->mProbability = tData.mProbability;
-
-		EvaluateLeafStats(tData);		
-	}
-
-	//-- cleanup
-	tData.Clear();
-
-	return newNode;
-}
-
 // subdivide using a split plane queue
-BspNode *VspBspTree::Subdivide(VspBspSplitQueue &tQueue,
-							   VspBspSplitCandidate &splitCandidate)
-{
-	VspBspTraversalData &tData = splitCandidate.mParentData;
+BspNode *VspOspTree::Subdivide(VspOspSplitQueue &tQueue,
+							   VspOspSplitCandidate &splitCandidate)
+{
+	VspOspTraversalData &tData = splitCandidate.mParentData;
 
 	BspNode *newNode = tData.mNode;
@@ -871,26 +376,17 @@
 	if (!LocalTerminationCriteriaMet(tData) && !GlobalTerminationCriteriaMet(tData))
 	{	
-		PolygonContainer coincident;
-
-		VspBspTraversalData tFrontData;
-		VspBspTraversalData tBackData;
+		VspOspTraversalData tFrontData;
+		VspOspTraversalData tBackData;
 
 		//-- continue subdivision
 		
 		// create new interior node and two leaf node
-		const Plane3 splitPlane = splitCandidate.mSplitPlane;
+		//TODO
+		const Plane3 splitPlane;// = splitCandidate.mSplitPlane;
 				
-		newNode = SubdivideNode(splitPlane, tData, tFrontData, tBackData, coincident);
-	
-		const int splitAxis = splitCandidate.mSplitAxis;
+		newNode = SubdivideNode(splitPlane, tData, tFrontData, tBackData);
+	
 		const int maxCostMisses = splitCandidate.mMaxCostMisses;
 
-		if (splitAxis < 3)
-			++ mBspStats.splits[splitAxis];
-		else
-			++ mBspStats.polySplits;
-
-		tFrontData.mIsKdNode = tBackData.mIsKdNode = (tData.mIsKdNode && (splitAxis < 3));
-		tFrontData.mAxis = tBackData.mAxis = splitAxis;
 
 		// how often was max cost ratio missed in this branch?
@@ -922,6 +418,6 @@
 	
 		//-- push the new split candidates on the stack
-		VspBspSplitCandidate frontCandidate;
-		VspBspSplitCandidate backCandidate;
+		VspOspSplitCandidate frontCandidate;
+		VspOspSplitCandidate backCandidate;
 
 		EvalSplitCandidate(tFrontData, frontCandidate);
@@ -969,9 +465,5 @@
 		viewCell->mLeaf = leaf;
 
-		if (mUseAreaForPvs)
-			viewCell->SetArea(tData.mProbability);
-		else
-			viewCell->SetVolume(tData.mProbability);
-
+		viewCell->SetVolume(tData.mProbability);
         leaf->mProbability = tData.mProbability;
 
@@ -986,40 +478,19 @@
 
 
-void VspBspTree::EvalPriority(VspBspTraversalData &tData) const
-{
-    switch (mNodePriorityQueueType) 
-	{
-	case BREATH_FIRST:
-		tData.mPriority = (float)-tData.mDepth;
-		break;
-	case DEPTH_FIRST:
-		tData.mPriority = (float)tData.mDepth;
-		break;
-	default:
-		tData.mPriority = tData.mPvs * tData.mProbability;
-		//Debug << "priority: " << tData.mPriority << endl;
-		break;
-	}
-}
-
-
-void VspBspTree::EvalSplitCandidate(VspBspTraversalData &tData,
-									VspBspSplitCandidate &splitData)
-{
-	VspBspTraversalData frontData;
-	VspBspTraversalData backData;
+void VspOspTree::EvalSplitCandidate(VspOspTraversalData &tData,
+									VspOspSplitCandidate &splitData)
+{
+	VspOspTraversalData frontData;
+	VspOspTraversalData backData;
 
 	BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode);
 
 	// compute locally best split plane
-    bool success = SelectPlane(splitData.mSplitPlane, leaf, tData, 
-							   frontData, backData, splitData.mSplitAxis);
-
-	// TODO: reuse
-	DEL_PTR(frontData.mGeometry);
-	DEL_PTR(backData.mGeometry);
-	
+	// TODO
+    const bool success =0;/// SelectPlane(splitData.mSplitPlane, tData, 
+//									 frontData, backData);
+	//TODO
 	// compute global decrease in render cost
-	splitData.mRenderCost = EvalRenderCostDecrease(splitData.mSplitPlane, tData);
+	splitData.mRenderCost = 0;//EvalRenderCostDecrease(splitData.mSplitPlane, tData);
 	splitData.mParentData = tData;
 	splitData.mMaxCostMisses = success ? tData.mMaxCostMisses : tData.mMaxCostMisses + 1;
@@ -1027,9 +498,8 @@
 
 
-BspInterior *VspBspTree::SubdivideNode(const Plane3 &splitPlane,
-									   VspBspTraversalData &tData,
-									   VspBspTraversalData &frontData,
-									   VspBspTraversalData &backData,
-									   PolygonContainer &coincident)
+BspInterior *VspOspTree::SubdivideNode(const Plane3 &splitPlane,
+									   VspOspTraversalData &tData,
+									   VspOspTraversalData &frontData,
+									   VspOspTraversalData &backData)
 {
 	BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode);
@@ -1037,9 +507,7 @@
 	//-- the front and back traversal data is filled with the new values
 	frontData.mDepth = tData.mDepth + 1;
-	frontData.mPolygons = new PolygonContainer();
 	frontData.mRays = new RayInfoContainer();
 	
 	backData.mDepth = tData.mDepth + 1;
-	backData.mPolygons = new PolygonContainer();
 	backData.mRays = new RayInfoContainer();
 	
@@ -1059,52 +527,17 @@
 	
 	// if geometry was not already computed
-	if (!frontData.mGeometry && !backData.mGeometry)
-	{
-		frontData.mGeometry = new BspNodeGeometry();
-		backData.mGeometry = new BspNodeGeometry();
-
-		tData.mGeometry->SplitGeometry(*frontData.mGeometry,
-									   *backData.mGeometry,
-									   splitPlane,
-									   mBox,
-									   //0.0f);
-									   mEpsilon);
-		
-		if (mUseAreaForPvs)
-		{
-			frontData.mProbability = frontData.mGeometry->GetArea();
-			backData.mProbability = backData.mGeometry->GetArea();
-		}
-		else
-		{
-			frontData.mProbability = frontData.mGeometry->GetVolume();
-			backData.mProbability = tData.mProbability - frontData.mProbability;
-
-			// should never come here: wrong volume !!!
-			if (0)
-			{
-				if (frontData.mProbability < -0.00001)
-					Debug << "fatal error f: " << frontData.mProbability << endl;
-				if (backData.mProbability < -0.00001)
-					Debug << "fatal error b: " << backData.mProbability << endl;
-
-				// clamp because of precision issues
-				if (frontData.mProbability < 0)	frontData.mProbability = 0;
-				if (backData.mProbability < 0) backData.mProbability = 0;
-			}
-		}
-	}
-
-	
-    // subdivide polygons
-	SplitPolygons(splitPlane,
-				  *tData.mPolygons,
-	              *frontData.mPolygons,
-				  *backData.mPolygons,
-				  coincident);
-
-
-
-	///////////////////////////////////////
+	// TODO
+
+#if TODO
+	tData.mBoundingBox.Split(splitPlane.mAxis, splitPlane.mPosition, 
+							 frontData.mBoundingBox, backData.mBoundingBox);
+
+#endif
+
+	frontData.mProbability = frontData.mBoundingBox.GetVolume();
+	backData.mProbability = tData.mProbability - frontData.mProbability;
+
+	
+    ///////////////////////////////////////////
 	// subdivide further
 
@@ -1149,11 +582,9 @@
 	interior->mTimeStamp = mTimeStamp ++;
 	
-
-	//DEL_PTR(leaf);
 	return interior;
 }
 
 
-void VspBspTree::AddToPvs(BspLeaf *leaf,
+void VspOspTree::AddToPvs(BspLeaf *leaf,
 						  const RayInfoContainer &rays,
 						  float &sampleContributions,
@@ -1200,5 +631,5 @@
 
 
-void VspBspTree::SortSplitCandidates(const RayInfoContainer &rays, 
+void VspOspTree::SortSplitCandidates(const RayInfoContainer &rays, 
 									 const int axis, 
 									 float minBand, 
@@ -1251,5 +682,5 @@
 
 
-float VspBspTree::BestCostRatioHeuristics(const RayInfoContainer &rays,
+float VspOspTree::BestCostRatioHeuristics(const RayInfoContainer &rays,
 										  const AxisAlignedBox3 &box,
 										  const int pvsSize,
@@ -1413,5 +844,5 @@
 	if (splitPlaneFound)
 	{
-		ratio = mPvsFactor * newRenderCost / (oldRenderCost + Limits::Small);
+		ratio = newRenderCost / (oldRenderCost + Limits::Small);
 	}
 	//if (axis != 1)
@@ -1423,12 +854,8 @@
 
 
-float VspBspTree::SelectAxisAlignedPlane(Plane3 &plane,
-										 const VspBspTraversalData &tData,
-										 int &axis,
-										 BspNodeGeometry **frontGeom,
-										 BspNodeGeometry **backGeom,
-										 float &pFront,
-										 float &pBack,
-										 const bool isKdNode)
+float VspOspTree::SelectPlane(const VspOspTraversalData &tData,
+							  AxisAlignedPlane &plane,
+							  float &pFront,
+							  float &pBack)
 {
 	float nPosition[3];
@@ -1437,42 +864,9 @@
 	float nProbBack[3];
 
-	BspNodeGeometry *nFrontGeom[3];
-	BspNodeGeometry *nBackGeom[3];
-
-	// set to NULL, so I can find out which gemetry was stored
-	for (int i = 0; i < 3; ++ i)
-	{
-		nFrontGeom[i] = NULL;
-		nBackGeom[i] = NULL;
-	}
-
 	// create bounding box of node geometry
-	AxisAlignedBox3 box;
-		
-	//TODO: for kd split geometry already is box => only take minmax vertices
-	if (1)
-	{
-		// get bounding box from geometry
-		tData.mGeometry->GetBoundingBox(box);
-	}
-	else
-	{
-		box.Initialize();
-		RayInfoContainer::const_iterator ri, ri_end = tData.mRays->end();
-
-		for(ri = tData.mRays->begin(); ri < ri_end; ++ ri)
-			box.Include((*ri).ExtrapTermination());
-	}
-
+	AxisAlignedBox3 box = tData.mBoundingBox;
+		
 	int sAxis = 0;
-	int bestAxis;
-
-	// if max cost ratio is exceeded, take split along longest axis instead
-	const float maxCostRatioForArbitraryAxis = 0.9f;
-
-	if (mUseDrivingAxisForMaxCost)
-		bestAxis = box.Size().DrivingAxis();
-	else
-		bestAxis = -1;
+	int bestAxis = -1;
 
 #if 0
@@ -1493,9 +887,6 @@
 		sAxis = box.Size().DrivingAxis();
 
-		
-	//Debug << "use special axis: " << useSpecialAxis << endl;
-	//Debug << "axis: " << sAxis << " drivingaxis: " << box.Size().DrivingAxis();
-
-	for (axis = 0; axis < 3 ; ++ axis)
+
+	for (int axis = 0; axis < 3 ; ++ axis)
 	{
 		if (!useSpecialAxis || (axis == sAxis))
@@ -1512,80 +903,23 @@
 											nPosition[axis]);			
 			}
-			
-			//-- split plane position is spatial median
-
-
-			// also use median split if cost ratio very low as
-			// there are not enough visibility cues
-			//if (!mUseCostHeuristics || (nCostRatio[axis] > maxCostRatioForHeur))
-			else 
-			{
-
+			else //-- split plane position is spatial median
+			{
 				nPosition[axis] = (box.Min()[axis] + box.Max()[axis]) * 0.5f;
-				Vector3 normal(0,0,0); normal[axis] = 1.0f;
-
-				// allows faster split because we have axis aligned kd tree boxes
-				if (isKdNode)
-				{
-					nCostRatio[axis] = EvalAxisAlignedSplitCost(tData,
-																box,
-																axis,
-																nPosition[axis],
-																nProbFront[axis], 
-																nProbBack[axis]);
-					
-					Vector3 pos;
-					
-					// create back geometry from box
-					// NOTE: the geometry is saved when possible
-					pos = box.Max(); pos[axis] = nPosition[axis];
-					AxisAlignedBox3 bBox(box.Min(), pos);
-					PolygonContainer fPolys;
-					bBox.ExtractPolys(fPolys);
-
-					nBackGeom[axis] = new BspNodeGeometry(fPolys);
-	
-					//-- create front geometry from box
-					pos = box.Min(); pos[axis] = nPosition[axis];
-					AxisAlignedBox3 fBox(pos, box.Max());
-
-					PolygonContainer bPolys;
-					fBox.ExtractPolys(bPolys);
-					nFrontGeom[axis] = new BspNodeGeometry(bPolys);
-				}
-				else
-				{
-					nFrontGeom[axis] = new BspNodeGeometry();
-					nBackGeom[axis] = new BspNodeGeometry();
-
-					nCostRatio[axis] = 
-						EvalSplitPlaneCost(Plane3(normal, nPosition[axis]), 
-										   tData, *nFrontGeom[axis], *nBackGeom[axis],
-										   nProbFront[axis], nProbBack[axis]);
-				}
+
+				nCostRatio[axis] = EvalSplitCost(tData,
+												 box,
+												 axis,
+												 nPosition[axis],
+												 nProbFront[axis], 
+												 nProbBack[axis]);
 			}
 						
-			
-			if (mUseDrivingAxisForMaxCost)
-			{
-				// we take longest axis split if cost ratio exceeds threshold
-				if (nCostRatio[axis] < min(maxCostRatioForArbitraryAxis, nCostRatio[bestAxis]))
-				{
-					bestAxis = axis;
-				}
-				else if (nCostRatio[axis] < nCostRatio[bestAxis])
-					Debug << "taking split along longest axis (" << bestAxis << ") instead of  (" << axis << ")" << endl;
-				
-			}
-			else
-			{
-				if (bestAxis == -1)
-				{
-					bestAxis = axis;
-				}
-				else if (nCostRatio[axis] < nCostRatio[bestAxis])
-				{
-					bestAxis = axis;
-				}
+			if (bestAxis == -1)
+			{
+				bestAxis = axis;
+			}
+			else if (nCostRatio[axis] < nCostRatio[bestAxis])
+			{
+				bestAxis = axis;
 			} 
 		}
@@ -1593,246 +927,16 @@
 
 	//-- assign values
-	axis = bestAxis;
+	plane.mAxis = bestAxis;
 	pFront = nProbFront[bestAxis];
 	pBack = nProbBack[bestAxis];
 
-	// assign best split nodes geometry 
-	*frontGeom = nFrontGeom[bestAxis];
-	*backGeom = nBackGeom[bestAxis];
-
-	// and delete other geometry
-	DEL_PTR(nFrontGeom[(bestAxis + 1) % 3]);
-	DEL_PTR(nBackGeom[(bestAxis + 2) % 3]);
-
-	//-- split plane
-    Vector3 normal(0,0,0); normal[bestAxis] = 1;
-	plane = Plane3(normal, nPosition[bestAxis]);
-
-	//Debug << "best axis: " << bestAxis << " pos " << nPosition[bestAxis] << endl;
-	//Debug << "!!!!!!!!!!!!!!" << endl;
+	//-- split plane position
+    plane.mPosition = nPosition[bestAxis];
+
 	return nCostRatio[bestAxis];
 }
 
 
-bool VspBspTree::SelectPlane(Plane3 &bestPlane,
-							 BspLeaf *leaf,
-							 VspBspTraversalData &data,							 
-							 VspBspTraversalData &frontData,
-							 VspBspTraversalData &backData,
-							 int &splitAxis)
-{
-	// HACK matt: subdivide regularily to certain depth
-	if (data.mDepth < 0)  	
-	{
-		cout << "d: " << data.mDepth << endl;
-		// return axis aligned split
-		AxisAlignedBox3 box;
-		box.Initialize();
-	
-		// create bounding box of region
-		data.mGeometry->GetBoundingBox(box);
-	
-		const int axis = box.Size().DrivingAxis();
-		const Vector3 position = (box.Min()[axis] + box.Max()[axis]) * 0.5f;
-
-		Vector3 norm(0,0,0); norm[axis] = 1.0f;
-		bestPlane = Plane3(norm, position);
-		splitAxis = axis;
-		return true;
-	}
-
-	// simplest strategy: just take next polygon
-	if (mSplitPlaneStrategy & RANDOM_POLYGON)
-	{
-        if (!data.mPolygons->empty())
-		{
-			const int randIdx = 
-				(int)RandomValue(0, (Real)((int)data.mPolygons->size() - 1));
-			Polygon3 *nextPoly = (*data.mPolygons)[randIdx];
-
-			bestPlane = nextPoly->GetSupportingPlane();
-			return true;
-		}
-	}
-
-	//-- use heuristics to find appropriate plane
-
-	// intermediate plane
-	Plane3 plane;
-	float lowestCost = MAX_FLOAT;
-	
-	// decides if the first few splits should be only axisAligned
-	const bool onlyAxisAligned  = 
-		(mSplitPlaneStrategy & AXIS_ALIGNED) &&
-		((int)data.mRays->size() > mTermMinRaysForAxisAligned) &&
-		((int)data.GetAvgRayContribution() < mTermMaxRayContriForAxisAligned);
-	
-	const int limit = onlyAxisAligned ? 0 : 
-		Min((int)data.mPolygons->size(), mMaxPolyCandidates);
-
-	float candidateCost;
-
-	int maxIdx = (int)data.mPolygons->size();
-
-	for (int i = 0; i < limit; ++ i)
-	{
-		// the already taken candidates are stored behind maxIdx
-		// => assure that no index is taken twice
-		const int candidateIdx = (int)RandomValue(0, (Real)(-- maxIdx));
-		Polygon3 *poly = (*data.mPolygons)[candidateIdx];
-
-		// swap candidate to the end to avoid testing same plane
-		std::swap((*data.mPolygons)[maxIdx], (*data.mPolygons)[candidateIdx]);
-		//Polygon3 *poly = (*data.mPolygons)[(int)RandomValue(0, (int)polys.size() - 1)];
-
-		// evaluate current candidate
-		BspNodeGeometry fGeom, bGeom;
-		float fArea, bArea;
-		plane = poly->GetSupportingPlane();
-		candidateCost = EvalSplitPlaneCost(plane, data, fGeom, bGeom, fArea, bArea);
-		
-		if (candidateCost < lowestCost)
-		{
-			bestPlane = plane;
-			lowestCost = candidateCost;
-		}
-	}
-
-	//-- evaluate axis aligned splits
-	int axis;
-	BspNodeGeometry *fGeom, *bGeom;
-	float pFront, pBack;
-
-	candidateCost = 99999999.0f;
-
-	// option: axis aligned split only if no polygon available
-	if (!mUsePolygonSplitIfAvailable || data.mPolygons->empty())
-	{
-		candidateCost = SelectAxisAlignedPlane(plane, 
-											   data, 
-											   axis,
-											   &fGeom, 
-											   &bGeom, 
-											   pFront, 
-											   pBack,
-											   data.mIsKdNode);	 
-	}
-
-	splitAxis = 3;
-
-	if (candidateCost < lowestCost)
-	{	
-		bestPlane = plane;
-		lowestCost = candidateCost;
-		splitAxis = axis;
-	
-		// assign already computed values
-		// we can do this because we always save the
-		// computed values from the axis aligned splits		
-
-		if (fGeom && bGeom)
-		{
-			frontData.mGeometry = fGeom;
-			backData.mGeometry = bGeom;
-	
-			frontData.mProbability = pFront;
-			backData.mProbability = pBack;
-		}
-	}
-	else
-	{
-		DEL_PTR(fGeom);
-		DEL_PTR(bGeom);
-	}
-    
-#ifdef _DEBUG
-	Debug << "plane lowest cost: " << lowestCost << endl;
-#endif
-
-	// exeeded relative max cost ratio
-	if (lowestCost > mTermMaxCostRatio)
-	{
-		return false;
-	}
-
-	return true;
-}
-
-
-Plane3 VspBspTree::ChooseCandidatePlane(const RayInfoContainer &rays) const
-{
-	const int candidateIdx = (int)RandomValue(0, (Real)((int)rays.size() - 1));
-
-	const Vector3 minPt = rays[candidateIdx].ExtrapOrigin();
-	const Vector3 maxPt = rays[candidateIdx].ExtrapTermination();
-
-	const Vector3 pt = (maxPt + minPt) * 0.5;
-	const Vector3 normal = Normalize(rays[candidateIdx].mRay->GetDir());
-
-	return Plane3(normal, pt);
-}
-
-
-Plane3 VspBspTree::ChooseCandidatePlane2(const RayInfoContainer &rays) const
-{
-	Vector3 pt[3];
-
-	int idx[3];
-	int cmaxT = 0;
-	int cminT = 0;
-	bool chooseMin = false;
-
-	for (int j = 0; j < 3; ++ j)
-	{
-		idx[j] = (int)RandomValue(0, (Real)((int)rays.size() * 2 - 1));
-
-		if (idx[j] >= (int)rays.size())
-		{
-			idx[j] -= (int)rays.size();
-
-			chooseMin = (cminT < 2);
-		}
-		else
-			chooseMin = (cmaxT < 2);
-
-		RayInfo rayInf = rays[idx[j]];
-		pt[j] = chooseMin ? rayInf.ExtrapOrigin() : rayInf.ExtrapTermination();
-	}
-
-	return Plane3(pt[0], pt[1], pt[2]);
-}
-
-
-Plane3 VspBspTree::ChooseCandidatePlane3(const RayInfoContainer &rays) const
-{
-	Vector3 pt[3];
-
-	int idx1 = (int)RandomValue(0, (Real)((int)rays.size() - 1));
-	int idx2 = (int)RandomValue(0, (Real)((int)rays.size() - 1));
-
-	// check if rays different
-	if (idx1 == idx2)
-		idx2 = (idx2 + 1) % (int)rays.size();
-
-	const RayInfo ray1 = rays[idx1];
-	const RayInfo ray2 = rays[idx2];
-
-	// normal vector of the plane parallel to both lines
-	const Vector3 norm = Normalize(CrossProd(ray1.mRay->GetDir(), ray2.mRay->GetDir()));
-
-	// vector from line 1 to line 2
-	const Vector3 vd = ray2.ExtrapOrigin() - ray1.ExtrapOrigin();
-
-	// project vector on normal to get distance
-	const float dist = DotProd(vd, norm);
-
-	// point on plane lies halfway between the two planes
-	const Vector3 planePt = ray1.ExtrapOrigin() + norm * dist * 0.5;
-
-	return Plane3(norm, planePt);
-}
-
-
-inline void VspBspTree::GenerateUniqueIdsForPvs()
+inline void VspOspTree::GenerateUniqueIdsForPvs()
 {
 	Intersectable::NewMail(); sBackId = Intersectable::sMailId;
@@ -1842,6 +946,6 @@
 
 
-float VspBspTree::EvalRenderCostDecrease(const Plane3 &candidatePlane,
-										 const VspBspTraversalData &data) const
+float VspOspTree::EvalRenderCostDecrease(const Plane3 &candidatePlane,
+										 const VspOspTraversalData &data) const
 {
 	float pvsFront = 0;
@@ -1874,33 +978,9 @@
 	BspNodeGeometry geomFront;
 	BspNodeGeometry geomBack;
-
-	// construct child geometry with regard to the candidate split plane
-	data.mGeometry->SplitGeometry(geomFront,
-								  geomBack,
-								  candidatePlane,
-								  mBox,
-								  //0.0f);
-								  mEpsilon);
-
-	if (!mUseAreaForPvs) // use front and back cell areas to approximate volume
-	{
-		pFront = geomFront.GetVolume();
-		pBack = pOverall - pFront;
-
-		// something is wrong with the volume
-		if ((pFront < 0.0) || (pBack < 0.0))
-		{
-			Debug << "ERROR in volume:\n"
-				  << "volume f :" << pFront << " b: " << pBack << " p: " << pOverall 
-				  << ", real volume f: " << pFront << " b: " << geomBack.GetVolume()
-				  << ", #polygons f: " << geomFront.Size() << " b: " << geomBack.Size() << " p: " << data.mGeometry->Size() << endl;
-		}
-	}
-	else
-	{
-		pFront = geomFront.GetArea();
-		pBack = geomBack.GetArea();
-	}
-	
+	
+	pFront = geomFront.GetVolume();
+	pBack = pOverall - pFront;
+
+		
 
 	// -- pvs rendering heuristics
@@ -1921,8 +1001,6 @@
 
 #if 1
-	// take render cost of node into account
+	// take render cost of node into account to avoid being stuck in a local minimum
 	const float normalizedOldRenderCost = oldRenderCost / mBox.GetVolume();
-	//Debug << "rendercostdecr: " << 0.99f * renderCostDecrease << " old render cost: " << 0.01f * normalizedOldRenderCost << endl;
-	//return 0.5f * renderCostDecrease + 0.5f * normalizedOldRenderCost;
 	return 0.99f * renderCostDecrease + 0.01f * normalizedOldRenderCost;
 #else
@@ -1932,215 +1010,11 @@
 
 
-float VspBspTree::EvalSplitPlaneCost(const Plane3 &candidatePlane,
-									 const VspBspTraversalData &data,
-									 BspNodeGeometry &geomFront,
-									 BspNodeGeometry &geomBack,
-									 float &pFront,
-									 float &pBack) const
-{
-	float cost = 0;
-
-	float totalPvs = 0;
-	float pvsFront = 0;
-	float pvsBack = 0;
-	
-	// probability that view point lies in back / front node
-	float pOverall = 0;
-	pFront = 0;
-	pBack = 0;
-
-
-	int limit;
-	bool useRand;
-
-	// create unique ids for pvs heuristics
-	GenerateUniqueIdsForPvs();
-
-	// choose test rays randomly if too much
-	if ((int)data.mRays->size() > mMaxTests)
-	{
-		useRand = true;
-		limit = mMaxTests;
-	}
-	else
-	{
-		useRand = false;
-		limit = (int)data.mRays->size();
-	}
-	
-	for (int i = 0; i < limit; ++ i)
-	{
-		const int testIdx = useRand ? 
-			(int)RandomValue(0, (Real)((int)data.mRays->size() - 1)) : i;
-		RayInfo rayInf = (*data.mRays)[testIdx];
-
-		float t;
-		VssRay *ray = rayInf.mRay;
-		const int cf = rayInf.ComputeRayIntersection(candidatePlane, t);
-
-		// find front and back pvs for origing and termination object
-		AddObjToPvs(ray->mTerminationObject, cf, pvsFront, pvsBack, totalPvs);
-		AddObjToPvs(ray->mOriginObject, cf, pvsFront, pvsBack, totalPvs);
-	}
-
-	// construct child geometry with regard to the candidate split plane
-	bool splitSuccessFull = data.mGeometry->SplitGeometry(geomFront,
-														  geomBack,
-														  candidatePlane,
-														  mBox,
-														  //0.0f);
-														  mEpsilon);
-
-	pOverall = data.mProbability;
-
-	if (!mUseAreaForPvs) // use front and back cell areas to approximate volume
-	{
-		pFront = geomFront.GetVolume();
-		pBack = pOverall - pFront;
-		
-		// HACK: precision issues possible for unbalanced split => don't take this split!
-		if (1 && 
-			(!splitSuccessFull || (pFront <= 0) || (pBack <= 0) || 
-			!geomFront.Valid() || !geomBack.Valid()))
-		{
-			//Debug << "error f: " << pFront << " b: " << pBack << endl;
-			// high penalty for this split
-			return 99999.9f;
-		}
-	}
-	else
-	{
-		pFront = geomFront.GetArea();
-		pBack = geomBack.GetArea();
-	}
-	
-
-	// -- pvs rendering heuristics
-	const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize();
-	const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize();
-
-	// only render cost heuristics or combined with standard deviation
-	const float penaltyOld = EvalPvsPenalty((int)totalPvs, lowerPvsLimit, upperPvsLimit);
-    const float penaltyFront = EvalPvsPenalty((int)pvsFront, lowerPvsLimit, upperPvsLimit);
-	const float penaltyBack = EvalPvsPenalty((int)pvsBack, lowerPvsLimit, upperPvsLimit);
-			
-	const float oldRenderCost = pOverall * penaltyOld;
-	const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack;
-
-	float oldCost, newCost;
-
-	// only render cost
-	if (1)
-	{
-		oldCost = oldRenderCost;
-		newCost = newRenderCost;
-	}
-	else // also considering standard deviation
-	{
-		// standard deviation is difference of back and front pvs
-		const float expectedCost = 0.5f * (penaltyFront + penaltyBack);
-
-		const float newDeviation = 0.5f * 
-			fabs(penaltyFront - expectedCost) + fabs(penaltyBack - expectedCost);
-
-		const float oldDeviation = penaltyOld;
-
-		newCost = mRenderCostWeight * newRenderCost + (1.0f - mRenderCostWeight) * newDeviation;
-		oldCost = mRenderCostWeight * oldRenderCost + (1.0f - mRenderCostWeight) * oldDeviation;
-	}
-
-	cost += mPvsFactor * newCost / (oldCost + Limits::Small);
-		
-
-#ifdef _DEBUG
-  	Debug << "totalpvs: " << data.mPvs << " ptotal: " << pOverall
-  		  << " frontpvs: " << pvsFront << " pFront: " << pFront
-  		  << " backpvs: " << pvsBack << " pBack: " << pBack << endl << endl;
-	Debug << "cost: " << cost << endl;
-#endif
-
-	return cost;
-}
-
-
-int VspBspTree::ComputeBoxIntersections(const AxisAlignedBox3 &box, 
-										ViewCellContainer &viewCells) const
-{
-	stack<bspNodePair> nodeStack;
-	BspNodeGeometry *rgeom = new BspNodeGeometry();
-
-	ConstructGeometry(mRoot, *rgeom);
-
-	nodeStack.push(bspNodePair(mRoot, rgeom));
-  
-	ViewCell::NewMail();
-
-	while (!nodeStack.empty()) 
-	{
-		BspNode *node = nodeStack.top().first;
-		BspNodeGeometry *geom = nodeStack.top().second;
-		nodeStack.pop();
-
-		const int side = geom->ComputeIntersection(box);
-		
-		switch (side)
-		{
-		case -1:
-			// node geometry is contained in box
-			CollectViewCells(node, true, viewCells, true);
-			break;
-
-		case 0:
-			if (node->IsLeaf())
-			{
-				BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
-			
-				if (!leaf->GetViewCell()->Mailed() && leaf->TreeValid())
-				{
-					leaf->GetViewCell()->Mail();
-					viewCells.push_back(leaf->GetViewCell());
-				}
-			}
-			else 
-			{
-				BspInterior *interior = dynamic_cast<BspInterior *>(node);
-			
-				BspNode *first = interior->GetFront();
-				BspNode *second = interior->GetBack();
-            
-				BspNodeGeometry *firstGeom = new BspNodeGeometry();
-				BspNodeGeometry *secondGeom = new BspNodeGeometry();
-
-				geom->SplitGeometry(*firstGeom,
-									*secondGeom,
-									interior->GetPlane(),
-									mBox,
-									//0.0000001f);
-									mEpsilon);
-
-				nodeStack.push(bspNodePair(first, firstGeom));
-				nodeStack.push(bspNodePair(second, secondGeom));
-			}
-			
-			break;
-		default:
-			// default: cull
-			break;
-		}
-		
-		DEL_PTR(geom);
-		
-	}
-
-	return (int)viewCells.size();
-}
-
-
-float VspBspTree::EvalAxisAlignedSplitCost(const VspBspTraversalData &data,
-										   const AxisAlignedBox3 &box,
-										   const int axis,
-										   const float &position,										  
-										   float &pFront,
-										   float &pBack) const
+
+float VspOspTree::EvalSplitCost(const VspOspTraversalData &data,
+								const AxisAlignedBox3 &box,
+								const int axis,
+								const float &position,										  
+								float &pFront,
+								float &pBack) const
 {
 	float pvsTotal = 0;
@@ -2158,6 +1032,4 @@
 	for(rit = data.mRays->begin(); rit != rit_end; ++ rit)
 	{
-		//if (!(*rit).mRay->IsActive())	continue;
-
 		// determine the side of this ray with respect to the plane
 		float t;
@@ -2175,31 +1047,7 @@
 		
 	pOverall = data.mProbability;
-
-	if (!mUseAreaForPvs)
-	{   // volume
-		pBack = pFront = pOverall * 0.5f;
-		
-#if 0
-		// box length substitute for probability
-		const float minBox = box.Min(axis);
-		const float maxBox = box.Max(axis);
-
-		pBack = position - minBox;
-		pFront = maxBox - position;
-		pOverall = maxBox - minBox;
-#endif
-	}
-	else //-- area substitute for probability
-	{
-		const int axis2 = (axis + 1) % 3;
-		const int axis3 = (axis + 2) % 3;
-
-		const float faceArea = 
-			(box.Max(axis2) - box.Min(axis2)) *
-			(box.Max(axis3) - box.Min(axis3));
-
-		pBack = pFront = pOverall * 0.5f + faceArea;
-	}
-
+	pBack = pFront = pOverall * 0.5f;
+	
+	
 #ifdef _DEBUG
 	Debug << axis << " " << pvsSize << " " << pvsBack << " " << pvsFront << endl;
@@ -2215,5 +1063,5 @@
 
 
-void VspBspTree::AddObjToPvs(Intersectable *obj,
+void VspOspTree::AddObjToPvs(Intersectable *obj,
 							 const int cf,
 							 float &frontPvs,
@@ -2268,5 +1116,5 @@
 
 
-void VspBspTree::CollectLeaves(vector<BspLeaf *> &leaves, 
+void VspOspTree::CollectLeaves(vector<BspLeaf *> &leaves, 
 							   const bool onlyUnmailed,
 							   const int maxPvsSize) const
@@ -2302,5 +1150,5 @@
 
 
-AxisAlignedBox3 VspBspTree::GetBoundingBox() const
+AxisAlignedBox3 VspOspTree::GetBoundingBox() const
 {
 	return mBox;
@@ -2308,5 +1156,5 @@
 
 
-BspNode *VspBspTree::GetRoot() const
+BspNode *VspOspTree::GetRoot() const
 {
 	return mRoot;
@@ -2314,5 +1162,5 @@
 
 
-void VspBspTree::EvaluateLeafStats(const VspBspTraversalData &data)
+void VspOspTree::EvaluateLeafStats(const VspOspTraversalData &data)
 {
 	// the node became a leaf -> evaluate stats for leafs
@@ -2370,5 +1218,5 @@
 
 
-int VspBspTree::CastRay(Ray &ray)
+int VspOspTree::CastRay(Ray &ray)
 {
 	int hits = 0;
@@ -2439,5 +1287,5 @@
 			if (!leaf->GetViewCell()->Mailed())
 			{
-				//ray.bspIntersections.push_back(Ray::VspBspIntersection(maxt, leaf));
+				//ray.bspIntersections.push_back(Ray::VspOspIntersection(maxt, leaf));
 				leaf->GetViewCell()->Mail();
 				++ hits;
@@ -2468,5 +1316,5 @@
 
 
-void VspBspTree::CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const
+void VspOspTree::CollectViewCells(ViewCellContainer &viewCells, bool onlyValid) const
 {
 	ViewCell::NewMail();
@@ -2476,5 +1324,5 @@
 
 
-void VspBspTree::CollapseViewCells()
+void VspOspTree::CollapseViewCells()
 {
 // TODO
@@ -2531,5 +1379,5 @@
 
 
-void VspBspTree::CollectRays(VssRayContainer &rays)
+void VspOspTree::CollectRays(VssRayContainer &rays)
 {
 	vector<BspLeaf *> leaves;
@@ -2548,5 +1396,5 @@
 
 
-void VspBspTree::ValidateTree()
+void VspOspTree::ValidateTree()
 {
 	stack<BspNode *> nodeStack;
@@ -2591,5 +1439,5 @@
 
 
-void VspBspTree::CollectViewCells(BspNode *root,
+void VspOspTree::CollectViewCells(BspNode *root,
 								  bool onlyValid,
 								  ViewCellContainer &viewCells,
@@ -2635,65 +1483,5 @@
 
 
-void VspBspTree::PreprocessPolygons(PolygonContainer &polys)
-{
-	// preprocess: throw out polygons coincident to the view space box (not needed)
-	PolygonContainer boxPolys;
-	mBox.ExtractPolys(boxPolys);
-	vector<Plane3> boxPlanes;
-
-	PolygonContainer::iterator pit, pit_end = boxPolys.end();
-
-	// extract planes of box
-	// TODO: can be done more elegantly than first extracting polygons
-	// and take their planes
-	for (pit = boxPolys.begin(); pit != pit_end; ++ pit)
-	{
-		boxPlanes.push_back((*pit)->GetSupportingPlane());
-	}
-
-	pit_end = polys.end();
-
-	for (pit = polys.begin(); pit != pit_end; ++ pit)
-	{
-		vector<Plane3>::const_iterator bit, bit_end = boxPlanes.end();
-		
-		for (bit = boxPlanes.begin(); (bit != bit_end) && (*pit); ++ bit)
-		{
-			const int cf = (*pit)->ClassifyPlane(*bit, mEpsilon);
-
-			if (cf == Polygon3::COINCIDENT)
-			{
-				DEL_PTR(*pit);
-				//Debug << "coincident!!" << endl;
-			}
-		}
-	}
-
-	// remove deleted entries
-	for (int i = 0; i < (int)polys.size(); ++ i)
-	{
-		while (!polys[i] && (i < (int)polys.size()))
-		{
-			swap(polys[i], polys.back());
-			polys.pop_back();
-		}
-	}
-}
-
-
-float VspBspTree::AccumulatedRayLength(const RayInfoContainer &rays) const
-{
-	float len = 0;
-
-	RayInfoContainer::const_iterator it, it_end = rays.end();
-
-	for (it = rays.begin(); it != it_end; ++ it)
-		len += (*it).SegmentLength();
-
-	return len;
-}
-
-
-int VspBspTree::SplitRays(const Plane3 &plane,
+int VspOspTree::SplitRays(const Plane3 &plane,
 						  RayInfoContainer &rays,
 						  RayInfoContainer &frontRays,
@@ -2725,5 +1513,5 @@
 			{
 				//-- split ray
-				//   test if start point behind or in front of plane
+				//-- test if start point behind or in front of plane
 				const int side = plane.Side(bRay.ExtrapOrigin());
 
@@ -2750,367 +1538,15 @@
 
 
-void VspBspTree::ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const
-{
-	BspNode *lastNode;
-
-	do
-	{
-		lastNode = n;
-
-		// want to get planes defining geometry of this node => don't take
-		// split plane of node itself
-		n = n->GetParent();
-
-		if (n)
-		{
-			BspInterior *interior = dynamic_cast<BspInterior *>(n);
-			Plane3 halfSpace = dynamic_cast<BspInterior *>(interior)->GetPlane();
-
-            if (interior->GetBack() != lastNode)
-				halfSpace.ReverseOrientation();
-
-			halfSpaces.push_back(halfSpace);
-		}
-	}
-	while (n);
-}
-
-
-void VspBspTree::ConstructGeometry(BspNode *n,
-								   BspNodeGeometry &geom) const
-{
-	vector<Plane3> halfSpaces;
-	ExtractHalfSpaces(n, halfSpaces);
-
-	PolygonContainer candidatePolys;
-	vector<Plane3> candidatePlanes;
-
-	vector<Plane3>::const_iterator pit, pit_end = halfSpaces.end();
-
-	// bounded planes are added to the polygons
-	for (pit = halfSpaces.begin(); pit != pit_end; ++ pit)
-	{
-		Polygon3 *p = GetBoundingBox().CrossSection(*pit);
-
-		if (p->Valid(mEpsilon))
-		{
-			candidatePolys.push_back(p);
-			candidatePlanes.push_back(*pit);
-		}
-	}
-
-	// add faces of bounding box (also could be faces of the cell)
-	for (int i = 0; i < 6; ++ i)
-	{
-		VertexContainer vertices;
-
-		for (int j = 0; j < 4; ++ j)
-			vertices.push_back(mBox.GetFace(i).mVertices[j]);
-
-		Polygon3 *poly = new Polygon3(vertices);
-
-		candidatePolys.push_back(poly);
-		candidatePlanes.push_back(poly->GetSupportingPlane());
-	}
-
-	for (int i = 0; i < (int)candidatePolys.size(); ++ i)
-	{
-		// polygon is split by all other planes
-		for (int j = 0; (j < (int)halfSpaces.size()) && candidatePolys[i]; ++ j)
-		{
-			if (i == j) // polygon and plane are coincident
-				continue;
-
-			VertexContainer splitPts;
-			Polygon3 *frontPoly, *backPoly;
-
-			const int cf =
-				candidatePolys[i]->ClassifyPlane(halfSpaces[j],
-												 mEpsilon);
-
-			switch (cf)
-			{
-				case Polygon3::SPLIT:
-					frontPoly = new Polygon3();
-					backPoly = new Polygon3();
-
-					candidatePolys[i]->Split(halfSpaces[j],
-											 *frontPoly,
-											 *backPoly,
-											 mEpsilon);
-
-					DEL_PTR(candidatePolys[i]);
-
-					if (backPoly->Valid(mEpsilon))
-						candidatePolys[i] = backPoly;
-					else
-						DEL_PTR(backPoly);
-
-					// outside, don't need this
-					DEL_PTR(frontPoly);
-					break;
-				// polygon outside of halfspace
-				case Polygon3::FRONT_SIDE:
-					DEL_PTR(candidatePolys[i]);
-					break;
-				// just take polygon as it is
-				case Polygon3::BACK_SIDE:
-				case Polygon3::COINCIDENT:
-				default:
-					break;
-			}
-		}
-
-		if (candidatePolys[i])
-		{
-			geom.Add(candidatePolys[i], candidatePlanes[i]);
-			//	geom.mPolys.push_back(candidates[i]);
-		}
-	}
-}
-
-
-void VspBspTree::ConstructGeometry(ViewCell *vc, 
-								   BspNodeGeometry &vcGeom) const
-{
-	ViewCellContainer leaves;
-	
-	mViewCellsTree->CollectLeaves(vc, leaves);
-
-	ViewCellContainer::const_iterator it, it_end = leaves.end();
-
-	for (it = leaves.begin(); it != it_end; ++ it)
-	{
-		BspLeaf *l = dynamic_cast<BspViewCell *>(*it)->mLeaf;
-		
-		ConstructGeometry(l, vcGeom);
-	}
-}
-
-
-int VspBspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,
+int VspOspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors,
 							  const bool onlyUnmailed) const
 {
-	stack<bspNodePair> nodeStack;
-	
-	BspNodeGeometry nodeGeom;
-	ConstructGeometry(n, nodeGeom);
-//	const float eps = 0.5f;
-	const float eps = 0.01f;
-	// split planes from the root to this node
-	// needed to verify that we found neighbor leaf
-	// TODO: really needed?
-	vector<Plane3> halfSpaces;
-	ExtractHalfSpaces(n, halfSpaces);
-
-
-	BspNodeGeometry *rgeom = new BspNodeGeometry();
-	ConstructGeometry(mRoot, *rgeom);
-
-	nodeStack.push(bspNodePair(mRoot, rgeom));
-
-	while (!nodeStack.empty())
-	{
-		BspNode *node = nodeStack.top().first;
-		BspNodeGeometry *geom = nodeStack.top().second;
-	
-		nodeStack.pop();
-
-		if (node->IsLeaf())
-		{
-			// test if this leaf is in valid view space
-			if (node->TreeValid() &&
-				(node != n) && 
-				(!onlyUnmailed || !node->Mailed()))
-			{
-				bool isAdjacent = true;
-
-				if (1)
-				{
-					// test all planes of current node if still adjacent
-					for (int i = 0; (i < halfSpaces.size()) && isAdjacent; ++ i)
-					{
-						const int cf =
-							Polygon3::ClassifyPlane(geom->GetPolys(),
-													halfSpaces[i],
-													eps);
-
-						if (cf == Polygon3::FRONT_SIDE)
-						{
-							isAdjacent = false;
-						}
-					}
-				}
-				else
-				{
-					// TODO: why is this wrong??
-					// test all planes of current node if still adjacent
-					for (int i = 0; (i < nodeGeom.Size()) && isAdjacent; ++ i)
-					{
-						Polygon3 *poly = nodeGeom.GetPolys()[i];
-
-						const int cf =
-							Polygon3::ClassifyPlane(geom->GetPolys(),
-													poly->GetSupportingPlane(),
-													eps);
-
-						if (cf == Polygon3::FRONT_SIDE)
-						{
-							isAdjacent = false;
-						}
-					}
-				}
-				// neighbor was found
-				if (isAdjacent)
-				{	
-					neighbors.push_back(dynamic_cast<BspLeaf *>(node));
-				}
-			}
-		}
-		else
-		{
-			BspInterior *interior = dynamic_cast<BspInterior *>(node);
-
-			const int cf = Polygon3::ClassifyPlane(nodeGeom.GetPolys(),
-												   interior->GetPlane(),
-												   eps);
-			
-			BspNode *front = interior->GetFront();
-			BspNode *back = interior->GetBack();
-            
-			BspNodeGeometry *fGeom = new BspNodeGeometry();
-			BspNodeGeometry *bGeom = new BspNodeGeometry();
-
-			geom->SplitGeometry(*fGeom,
-								*bGeom,
-								interior->GetPlane(),
-								mBox,
-								//0.0000001f);
-								eps);
-		
-			if (cf == Polygon3::BACK_SIDE)
-			{
-				nodeStack.push(bspNodePair(interior->GetBack(), bGeom));
-				DEL_PTR(fGeom);
-			}
-			else
-			{
-				if (cf == Polygon3::FRONT_SIDE)
-				{
-					nodeStack.push(bspNodePair(interior->GetFront(), fGeom));
-					DEL_PTR(bGeom);
-				}
-				else
-				{	// random decision
-					nodeStack.push(bspNodePair(front, fGeom));
-					nodeStack.push(bspNodePair(back, bGeom));
-				}
-			}
-		}
-	
-		DEL_PTR(geom);
-	}
-
-	return (int)neighbors.size();
-}
-
-
-
-int VspBspTree::FindApproximateNeighbors(BspNode *n, 
-										 vector<BspLeaf *> &neighbors,
-										 const bool onlyUnmailed) const
-{
-	stack<bspNodePair> nodeStack;
-	
-	BspNodeGeometry nodeGeom;
-	ConstructGeometry(n, nodeGeom);
-	
-	float eps = 0.01f;
-	// split planes from the root to this node
-	// needed to verify that we found neighbor leaf
-	// TODO: really needed?
-	vector<Plane3> halfSpaces;
-	ExtractHalfSpaces(n, halfSpaces);
-
-
-	BspNodeGeometry *rgeom = new BspNodeGeometry();
-	ConstructGeometry(mRoot, *rgeom);
-
-	nodeStack.push(bspNodePair(mRoot, rgeom));
-
-	while (!nodeStack.empty())
-	{
-		BspNode *node = nodeStack.top().first;
-		BspNodeGeometry *geom = nodeStack.top().second;
-	
-		nodeStack.pop();
-
-		if (node->IsLeaf())
-		{
-			// test if this leaf is in valid view space
-			if (node->TreeValid() &&
-				(node != n) && 
-				(!onlyUnmailed || !node->Mailed()))
-			{
-				bool isAdjacent = true;
-
-				// neighbor was found
-				if (isAdjacent)
-				{	
-					neighbors.push_back(dynamic_cast<BspLeaf *>(node));
-				}
-			}
-		}
-		else
-		{
-			BspInterior *interior = dynamic_cast<BspInterior *>(node);
-
-			const int cf = Polygon3::ClassifyPlane(nodeGeom.GetPolys(),
-												   interior->GetPlane(),
-												   eps);
-			
-			BspNode *front = interior->GetFront();
-			BspNode *back = interior->GetBack();
-            
-			BspNodeGeometry *fGeom = new BspNodeGeometry();
-			BspNodeGeometry *bGeom = new BspNodeGeometry();
-
-			geom->SplitGeometry(*fGeom,
-								*bGeom,
-								interior->GetPlane(),
-								mBox,
-								//0.0000001f);
-								eps);
-		
-			if (cf == Polygon3::BACK_SIDE)
-			{
-				nodeStack.push(bspNodePair(interior->GetBack(), bGeom));
-				DEL_PTR(fGeom);
-				}
-			else
-			{
-				if (cf == Polygon3::FRONT_SIDE)
-				{
-					nodeStack.push(bspNodePair(interior->GetFront(), fGeom));
-					DEL_PTR(bGeom);
-				}
-				else
-				{	// random decision
-					nodeStack.push(bspNodePair(front, fGeom));
-					nodeStack.push(bspNodePair(back, bGeom));
-				}
-			}
-		}
-	
-		DEL_PTR(geom);
-	}
-
-	return (int)neighbors.size();
-}
-
-
-
-BspLeaf *VspBspTree::GetRandomLeaf(const Plane3 &halfspace)
-{
+	// TODO
+	return 0;
+}
+
+
+BspLeaf *VspOspTree::GetRandomLeaf(const Plane3 &halfspace)
+{
+#if TODO
     stack<BspNode *> nodeStack;
   	nodeStack.push(mRoot);
@@ -3157,10 +1593,10 @@
 		}
 	}
-
+#endif
 	return NULL;
 }
 
 
-BspLeaf *VspBspTree::GetRandomLeaf(const bool onlyUnmailed)
+BspLeaf *VspOspTree::GetRandomLeaf(const bool onlyUnmailed)
 {
 	stack<BspNode *> nodeStack;
@@ -3198,5 +1634,5 @@
 
 
-int VspBspTree::ComputePvsSize(const RayInfoContainer &rays) const
+int VspOspTree::ComputePvsSize(const RayInfoContainer &rays) const
 {
 	int pvsSize = 0;
@@ -3232,5 +1668,5 @@
 
 
-float VspBspTree::GetEpsilon() const
+float VspOspTree::GetEpsilon() const
 {
 	return mEpsilon;
@@ -3238,48 +1674,6 @@
 
 
-int VspBspTree::SplitPolygons(const Plane3 &plane,
-							  PolygonContainer &polys,
-							  PolygonContainer &frontPolys,
-							  PolygonContainer &backPolys,
-							  PolygonContainer &coincident) const
-{
-	int splits = 0;
-
-	PolygonContainer::const_iterator it, it_end = polys.end();
-
-	for (it = polys.begin(); it != polys.end(); ++ it)	
-	{
-		Polygon3 *poly = *it;
-
-		// classify polygon
-		const int cf = poly->ClassifyPlane(plane, mEpsilon);
-
-		switch (cf)
-		{
-			case Polygon3::COINCIDENT:
-				coincident.push_back(poly);
-				break;
-			case Polygon3::FRONT_SIDE:
-				frontPolys.push_back(poly);
-				break;
-			case Polygon3::BACK_SIDE:
-				backPolys.push_back(poly);
-				break;
-			case Polygon3::SPLIT:
-				backPolys.push_back(poly);
-				frontPolys.push_back(poly);
-				++ splits;
-				break;
-			default:
-                Debug << "SHOULD NEVER COME HERE\n";
-				break;
-		}
-	}
-
-	return splits;
-}
-
-
-int VspBspTree::CastLineSegment(const Vector3 &origin,
+
+int VspOspTree::CastLineSegment(const Vector3 &origin,
 								const Vector3 &termination,
 								ViewCellContainer &viewcells)
@@ -3387,40 +1781,5 @@
 
 
-
-int VspBspTree::TreeDistance(BspNode *n1, BspNode *n2) const
-{
-	std::deque<BspNode *> path1;
-	BspNode *p1 = n1;
-
-	// create path from node 1 to root
-	while (p1)
-	{
-		if (p1 == n2) // second node on path
-			return (int)path1.size();
-
-		path1.push_front(p1);
-		p1 = p1->GetParent();
-	}
-
-	int depth = n2->GetDepth();
-	int d = depth;
-
-	BspNode *p2 = n2;
-
-	// compare with same depth
-	while (1)
-	{
-		if ((d < (int)path1.size()) && (p2 == path1[d]))
-			return (depth - d) + ((int)path1.size() - 1 - d);
-
-		-- d;
-		p2 = p2->GetParent();
-	}
-
-	return 0; // never come here
-}
-
-
-BspNode *VspBspTree::CollapseTree(BspNode *node, int &collapsed)
+BspNode *VspOspTree::CollapseTree(BspNode *node, int &collapsed)
 {
 // TODO
@@ -3464,5 +1823,5 @@
 
 
-int VspBspTree::CollapseTree()
+int VspOspTree::CollapseTree()
 {
 	int collapsed = 0;
@@ -3478,5 +1837,5 @@
 
 
-void VspBspTree::RepairViewCellsLeafLists()
+void VspOspTree::RepairViewCellsLeafLists()
 {
 // TODO
@@ -3521,254 +1880,6 @@
 
 
-typedef pair<BspNode *, BspNodeGeometry *> bspNodePair;
-
-
-int VspBspTree::CastBeam(Beam &beam)
-{
-    stack<bspNodePair> nodeStack;
-	BspNodeGeometry *rgeom = new BspNodeGeometry();
-	ConstructGeometry(mRoot, *rgeom);
-
-	nodeStack.push(bspNodePair(mRoot, rgeom));
-  
-	ViewCell::NewMail();
-
-	while (!nodeStack.empty()) 
-	{
-		BspNode *node = nodeStack.top().first;
-		BspNodeGeometry *geom = nodeStack.top().second;
-		nodeStack.pop();
-		
-		AxisAlignedBox3 box;
-		geom->GetBoundingBox(box);
-
-		const int side = beam.ComputeIntersection(box);
-		
-		switch (side) 
-		{
-		case -1:
-			CollectViewCells(node, true, beam.mViewCells, true);
-			break;
-		case 0:
-			
-			if (node->IsLeaf())
-			{
-				BspLeaf *leaf = dynamic_cast<BspLeaf *>(node);
-			
-				if (!leaf->GetViewCell()->Mailed() && leaf->TreeValid())
-				{
-					leaf->GetViewCell()->Mail();
-					beam.mViewCells.push_back(leaf->GetViewCell());
-				}
-			}
-			else 
-			{
-				BspInterior *interior = dynamic_cast<BspInterior *>(node);
-			
-				BspNode *first = interior->GetFront();
-				BspNode *second = interior->GetBack();
-            
-				BspNodeGeometry *firstGeom = new BspNodeGeometry();
-				BspNodeGeometry *secondGeom = new BspNodeGeometry();
-
-				geom->SplitGeometry(*firstGeom,
-									*secondGeom,
-									interior->GetPlane(),
-									mBox,
-									//0.0000001f);
-									mEpsilon);
-
-				// decide on the order of the nodes
-				if (DotProd(beam.mPlanes[0].mNormal, 
-					interior->GetPlane().mNormal) > 0)
-				{
-					swap(first, second);
-					swap(firstGeom, secondGeom);
-				}
-
-				nodeStack.push(bspNodePair(first, firstGeom));
-				nodeStack.push(bspNodePair(second, secondGeom));
-			}
-			
-			break;
-		default:
-			// default: cull
-			break;
-		}
-		
-		DEL_PTR(geom);
-		
-	}
-
-	return (int)beam.mViewCells.size();
-}
-
-
-void VspBspTree::SetViewCellsManager(ViewCellsManager *vcm)
-{
-	mViewCellsManager = vcm;
-}
-
-
-int VspBspTree::CollectMergeCandidates(const vector<BspLeaf *> leaves,
-									   vector<MergeCandidate> &candidates)
-{
-	BspLeaf::NewMail();
-	
-	vector<BspLeaf *>::const_iterator it, it_end = leaves.end();
-
-	int numCandidates = 0;
-
-	// find merge candidates and push them into queue
-	for (it = leaves.begin(); it != it_end; ++ it)
-	{
-		BspLeaf *leaf = *it;
-		
-		// the same leaves must not be part of two merge candidates
-		leaf->Mail();
-		
-		vector<BspLeaf *> neighbors;
-		
-		// appoximate neighbor search has slightl relaxed constraints
-		if (1)
-			FindNeighbors(leaf, neighbors, true);
-		else
-			FindApproximateNeighbors(leaf, neighbors, true);
-
-		vector<BspLeaf *>::const_iterator nit, nit_end = neighbors.end();
-
-		// TODO: test if at least one ray goes from one leaf to the other
-		for (nit = neighbors.begin(); nit != nit_end; ++ nit)
-		{
-			if ((*nit)->GetViewCell() != leaf->GetViewCell())
-			{
-				MergeCandidate mc(leaf->GetViewCell(), (*nit)->GetViewCell());
-
-				// dont't merge view cells if they are empty and not front and back leaf of the same parent
-				// in the tree?
-				if (mEmptyViewCellsMergeAllowed ||
-					!leaf->GetViewCell()->GetPvs().Empty() || 
-					!(*nit)->GetViewCell()->GetPvs().Empty() ||
-                    leaf->IsSibling(*nit))
-				{
-					candidates.push_back(mc);
-				}
-
-				++ numCandidates;
-				if ((numCandidates % 1000) == 0)
-				{
-					cout << "collected " << numCandidates << " merge candidates" << endl;
-				}
-			}
-		}
-	}
-
-	Debug << "merge queue: " << (int)candidates.size() << endl;
-	Debug << "leaves in queue: " << numCandidates << endl;
-	
-
-	return (int)leaves.size();
-}
-
-
-int VspBspTree::CollectMergeCandidates(const VssRayContainer &rays, 
-									   vector<MergeCandidate> &candidates)
-{
-	ViewCell::NewMail();
-	long startTime = GetTime();
-	
-	map<BspLeaf *, vector<BspLeaf*> > neighborMap;
-	ViewCellContainer::const_iterator iit;
-
-	int numLeaves = 0;
-	
-	BspLeaf::NewMail();
-
-	for (int i = 0; i < (int)rays.size(); ++ i)
-	{  
-		VssRay *ray = rays[i];
-	
-		// traverse leaves stored in the rays and compare and 
-		// merge consecutive leaves (i.e., the neighbors in the tree)
-		if (ray->mViewCells.size() < 2)
-			continue;
-//TODO viewcellhierarchy
-		iit = ray->mViewCells.begin();
-		BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*(iit ++));
-		BspLeaf *leaf = bspVc->mLeaf;
-		
-		// traverse intersections 
-		// consecutive leaves are neighbors => add them to queue
-		for (; iit != ray->mViewCells.end(); ++ iit)
-		{
-			// next pair
-			BspLeaf *prevLeaf = leaf;
-			bspVc = dynamic_cast<BspViewCell *>(*iit);
-            leaf = bspVc->mLeaf;
-
-			// view space not valid or same view cell
-			if (!leaf->TreeValid() || !prevLeaf->TreeValid() ||
-				(leaf->GetViewCell() == prevLeaf->GetViewCell()))
-				continue;
-
-           	vector<BspLeaf *> &neighbors = neighborMap[leaf];
-			
-			bool found = false;
-
-			// both leaves inserted in queue already =>
-			// look if double pair already exists
-			if (leaf->Mailed() && prevLeaf->Mailed())
-			{
-				vector<BspLeaf *>::const_iterator it, it_end = neighbors.end();
-				
-                for (it = neighbors.begin(); !found && (it != it_end); ++ it)
-					if (*it == prevLeaf)
-						found = true; // already in queue
-			}
-		
-			if (!found)
-			{
-				// this pair is not in map yet
-				// => insert into the neighbor map and the queue
-				neighbors.push_back(prevLeaf);
-				neighborMap[prevLeaf].push_back(leaf);
-
-				leaf->Mail();
-				prevLeaf->Mail();
-		
-				MergeCandidate mc(leaf->GetViewCell(), prevLeaf->GetViewCell());
-				
-				candidates.push_back(mc);
-
-				if (((int)candidates.size() % 1000) == 0)
-				{
-					cout << "collected " << (int)candidates.size() << " merge candidates" << endl;
-				}
-			}
-        }
-	}
-
-	Debug << "neighbormap size: " << (int)neighborMap.size() << endl;
-	Debug << "merge queue: " << (int)candidates.size() << endl;
-	Debug << "leaves in queue: " << numLeaves << endl;
-
-
-	//-- collect the leaves which haven't been found by ray casting
-	if (0)
-	{
-		cout << "finding additional merge candidates using geometry" << endl;
-		vector<BspLeaf *> leaves;
-		CollectLeaves(leaves, true);
-		Debug << "found " << (int)leaves.size() << " new leaves" << endl << endl;
-		CollectMergeCandidates(leaves, candidates);
-	}
-
-	return numLeaves;
-}
-
-
-
-
-ViewCell *VspBspTree::GetViewCell(const Vector3 &point, const bool active)
+
+ViewCell *VspOspTree::GetViewCell(const Vector3 &point, const bool active)
 {
 	if (mRoot == NULL)
@@ -3809,5 +1920,5 @@
 
 
-bool VspBspTree::ViewPointValid(const Vector3 &viewPoint) const
+bool VspOspTree::ViewPointValid(const Vector3 &viewPoint) const
 {
 	BspNode *node = mRoot;
@@ -3839,5 +1950,5 @@
 
 
-void VspBspTree::PropagateUpValidity(BspNode *node)
+void VspOspTree::PropagateUpValidity(BspNode *node)
 {
 	const bool isValid = node->TreeValid();
@@ -3868,7 +1979,7 @@
 
 #if ZIPPED_VIEWCELLS
-bool VspBspTree::Export(ogzstream &stream)
+bool VspOspTree::Export(ogzstream &stream)
 #else
-bool VspBspTree::Export(ofstream &stream)
+bool VspOspTree::Export(ofstream &stream)
 #endif
 {
@@ -3878,8 +1989,9 @@
 }
 
+
 #if ZIPPED_VIEWCELLS
-void VspBspTree::ExportNode(BspNode *node, ogzstream &stream)
+void VspOspTree::ExportNode(BspNode *node, ogzstream &stream)
 #else
-void VspBspTree::ExportNode(BspNode *node, ofstream &stream)
+void VspOspTree::ExportNode(BspNode *node, ofstream &stream)
 #endif
 {
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.h	(revision 1001)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VrmlExporter.h	(revision 1006)
@@ -59,8 +59,8 @@
 				 const Vector3 direction
 				 );
-
+#if 0
   bool
-  ExportVspKdTree(const VspKdTree &tree, const int maxPvs);
-
+  ExportVspOspTree(const VspKdTree &tree, const int maxPvs);
+#endif
   bool ExportBspTree(const BspTree &tree);
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1006)
@@ -8,5 +8,5 @@
 #include "ViewCellBsp.h"
 #include "KdTree.h"
-#include "VspKdTree.h"
+//#include "VspOspTree.h"
 #include "Exporter.h"
 #include "VspBspTree.h"
@@ -1828,11 +1828,12 @@
 	Vector3 termination = hray.Extrap(tmax);
 
+	// traverse the view space subdivision
 	CastLineSegment(origin, termination, viewcells);
 
-	// copy viewcells memory efficiently
 	//const bool storeViewcells = !addRays;
-
+//return 0;
 	if (storeViewCells)
 	{
+		// copy viewcells memory efficiently
 		ray.mViewCells.reserve(viewcells.size());
 		ray.mViewCells = viewcells;
@@ -2090,5 +2091,4 @@
 	}
 
-
 	return true;
 }
@@ -2173,5 +2173,6 @@
 
 
-void ViewCellsManager::SetScalarPvsSize(ViewCell *vc, const int pvsSize) const
+void ViewCellsManager::SetScalarPvsSize(ViewCell *vc, 
+										const int pvsSize) const
 {
 	vc->mPvsSize = pvsSize;
@@ -3346,366 +3347,4 @@
 }
 
-
-/**********************************************************************/
-/*                   VspKdViewCellsManager implementation             */
-/**********************************************************************/
-
-
-VspKdViewCellsManager::VspKdViewCellsManager(VspKdTree *vspKdTree):
-ViewCellsManager(), mVspKdTree(vspKdTree)
-{
-	Environment::GetSingleton()->GetIntValue("VspKdTree.Construction.samples", mInitialSamples);
-	mVspKdTree->SetViewCellsManager(this);
-}
-
-float VspKdViewCellsManager::GetProbability(ViewCell *viewCell)
-{
-	// compute view cell area / volume as subsititute for probability
-	if (0)
-		return GetArea(viewCell) / GetViewSpaceBox().SurfaceArea();
-	else
-		return GetVolume(viewCell) / GetViewSpaceBox().GetVolume();
-}
-
-
-
-
-void VspKdViewCellsManager::CollectViewCells()
-{
-	mVspKdTree->CollectViewCells(mViewCells);
-}
-
-
-int VspKdViewCellsManager::ConstructSubdivision(const ObjectContainer &objects,
-												const VssRayContainer &rays)
-{
-	// if view cells already constructed
-	if (ViewCellsConstructed())
-		return 0;
-
-	VssRayContainer constructionRays;
-	VssRayContainer savedRays;
-
-	GetRaySets(rays,
-			   mInitialSamples,
-			   constructionRays,
-			   &savedRays);
-
-	Debug << "constructing vsp kd tree using "
-		  << (int)constructionRays.size() << " samples" << endl;
-
-	mVspKdTree->Construct(constructionRays, &mViewSpaceBox);
-	Debug << mVspKdTree->GetStatistics() << endl;
-
-	// export leaf building blocks
-	ExportLeaves(objects, rays);
-
-	// finally merge kd leaf building blocks to view cells
-	const int merged = mVspKdTree->MergeViewCells(rays);
-
-	// collapse siblings belonging to the same view cell
-	mVspKdTree->RefineViewCells(rays);
-
-	// collapse siblings belonging to the same view cell
-	mVspKdTree->CollapseTree();
-
-	// evaluale view cell stats
-	ResetViewCells();
-
-	Debug << "\nView cells after construction:\n" << mCurrentViewCellsStats << endl;
-
-	long startTime = GetTime();
-
-	// recast rest of rays
-	ComputeSampleContributions(savedRays, true, false);
-
-	Debug << "Computed remaining ray contribution in " << TimeDiff(startTime, GetTime()) * 1e-3
-		  << " secs" << endl;
-
-	return merged;
-}
-
-bool VspKdViewCellsManager::ViewCellsConstructed() const
-{
-	return mVspKdTree->GetRoot() != NULL;
-}
-
-
-ViewCell *VspKdViewCellsManager::GenerateViewCell(Mesh *mesh) const
-{
-	return new VspKdViewCell(mesh);
-}
-
-int VspKdViewCellsManager::PostProcess(const ObjectContainer &objects,
-									   const VssRayContainer &rays)
-{
-	if (!ViewCellsConstructed())
-		return 0;
-
-	// recalculate stats
-	EvaluateViewCellsStats();
-
-	return 0;
-}
-
-
-void VspKdViewCellsManager::ExportLeaves(const ObjectContainer &objects,
-										 const VssRayContainer &sampleRays)
-{
-	if (!ViewCellsConstructed())
-		return;
-
-	//-- export leaf building blocks
-	Exporter *exporter = Exporter::GetExporter("vspkdtree.x3d");
-	if (!exporter)
-		return;
-
-	if (mExportGeometry)
-		exporter->ExportGeometry(objects);
-	
-	//exporter->SetWireframe();
-	//exporter->ExportVspKdTree(*mVspKdTree, mVspKdTree->GetStatistics().maxPvsSize);
-	exporter->ExportVspKdTree(*mVspKdTree);
-
-	if (mExportRays)
-	{
-		const float prob = (float)mVisualizationSamples
-			/ ((float)sampleRays.size() + Limits::Small);
-
-		exporter->SetWireframe();
-
-		//-- collect uniformly distributed rays
-		VssRayContainer rays;
-
-		for (int i = 0; i < sampleRays.size(); ++ i)
-		{
-			if (RandomValue(0,1) < prob)
-				rays.push_back(sampleRays[i]);
-		}
-		exporter->ExportRays(rays, RgbColor(1, 0, 0));
-	}
-
-	delete exporter;
-}
-
-
-void VspKdViewCellsManager::Visualize(const ObjectContainer &objects,
-									  const VssRayContainer &sampleRays)
-{
-	if (!ViewCellsConstructed())
-		return;
-
-	//-- export single view cells
-	for (int i = 0; i < 10; ++ i)
-	{
-		char s[64];
-		sprintf(s, "vsp_viewcell%04d.x3d", i);
-		Exporter *exporter = Exporter::GetExporter(s);
-		const int idx =
-			(int)RandomValue(0.0, (Real)((int)mViewCells.size() - 1));
-
-		VspKdViewCell *vc = dynamic_cast<VspKdViewCell *>(mViewCells[idx]);
-
-		//-- export geometry
-		Material m;
-		m.mDiffuseColor = RgbColor(0, 1, 1);
-
-		exporter->SetForcedMaterial(m);
-		exporter->SetWireframe();
-
-		ExportViewCellGeometry(exporter, vc);
-
-		//-- export stored rays
-		
-		if (mExportRays)
-		{
-			ViewCellContainer leaves;
-			mViewCellsTree->CollectLeaves(vc, leaves);
-
-			ViewCellContainer::const_iterator it,
-				it_end = leaves.end();
-
-			for (it = leaves.begin(); it != it_end; ++ it)
-			{
-				VspKdViewCell *vspKdVc = dynamic_cast<VspKdViewCell *>(*it);
-				VspKdLeaf *leaf = vspKdVc->mLeaf;
-				AxisAlignedBox3 box = mVspKdTree->GetBBox(leaf);
-
-				VssRayContainer vssRays;
-
-				VssRayContainer castRays;
-				VssRayContainer initRays;
-
-				leaf->GetRays(vssRays);
-
-				VssRayContainer::const_iterator it, it_end = vssRays.end();
-				const float prop = 200.0f / (float)vssRays.size();
-
-				for (it = vssRays.begin(); it != it_end; ++ it)
-				{
-					if (Random(1) < prop)
-						if ((*it)->mTerminationObject == NULL)
-							castRays.push_back(*it);
-						else
-							initRays.push_back(*it);
-				}
-
-				exporter->ExportRays(castRays, RgbColor(1, 0, 0));
-				exporter->ExportRays(initRays, RgbColor(0, 1, 0));
-			}
-		}
-	
-		//-- output PVS of view cell
-		m.mDiffuseColor = RgbColor(1, 0, 0);
-		exporter->SetForcedMaterial(m);
-
-		Intersectable::NewMail();
-
-		ObjectPvsMap::const_iterator it,
-			it_end = vc->GetPvs().mEntries.end();
-
-		exporter->SetFilled();
-
-		for (it = vc->GetPvs().mEntries.begin(); it != it_end; ++ it)
-		{
-			Intersectable *intersect = (*it).first;
-
-			if (!intersect->Mailed())
-			{
-				Material m = RandomMaterial();
-				exporter->SetForcedMaterial(m);
-
-				exporter->ExportIntersectable(intersect);
-				intersect->Mail();
-			}
-		}
-
-		delete exporter;
-	}
-
-	//-- export final view cells
-	Exporter *exporter = Exporter::GetExporter("vspkdtree_merged.x3d");
-
-
-	ExportViewCellsForViz(exporter);
-
-	if (mExportGeometry)
-	{
-		exporter->SetFilled();
-		exporter->ExportGeometry(objects);
-	}
-
-	if (mExportRays)
-	{
-		const float prob = (float)mVisualizationSamples
-			/ ((float)sampleRays.size() + Limits::Small);
-
-		exporter->SetWireframe();
-
-		VssRayContainer rays;
-
-		for (int i = 0; i < sampleRays.size(); ++ i)
-		{
-		  if (RandomValue(0,1) < prob)
-			rays.push_back(sampleRays[i]);
-		}
-		exporter->ExportRays(rays, RgbColor(1, 0, 0));
-	}
-
-	delete exporter;
-}
-
-int VspKdViewCellsManager::GetType() const
-{
-	return VSP_KD;
-}
-
-
-int VspKdViewCellsManager::CastLineSegment(const Vector3 &origin,
-										   const Vector3 &termination,
-										   ViewCellContainer &viewcells)
-{
-	return mVspKdTree->CastLineSegment(origin, termination, viewcells);
-}
-
-
-void VspKdViewCellsManager::ExportColor(Exporter *exporter,
-										ViewCell *vc) const
-{
-	if (mColorCode == 0) // Random color
-		return;
-
-	float importance = 0;
-
-	switch (mColorCode)
-	{
-	case 1: // pvs
-		{
-			importance = (float)mViewCellsTree->GetPvsSize(vc) /
-				(float)mCurrentViewCellsStats.maxPvs;
-		}
-		break;
-	case 2: // merged leaves
-		{
-        	const int lSize = mViewCellsTree->GetNumInitialViewCells(vc);
-			importance = (float)lSize /
-				(float)mCurrentViewCellsStats.maxLeaves;
-		}
-		break;
-	case 3: // merged tree depth difference
-		{
-			//importance = (float)GetMaxTreeDiff(vc) /
-			//	(float)(mVspBspTree->GetStatistics().maxDepth * 2);
-		}
-		break;
-	default:
-		break;
-	}
-
-	Material m;
-	m.mDiffuseColor.b = 1.0f;
-	m.mDiffuseColor.r = importance;
-	m.mDiffuseColor.g = 1.0f - m.mDiffuseColor.r;
-	//Debug << "importance: " << importance << endl;
-	exporter->SetForcedMaterial(m);
-}
-
-
-void VspKdViewCellsManager::ExportViewCellGeometry(Exporter *exporter,
-												   ViewCell *vc,
-												   const Plane3 *clipPlane) const
-{
-	VspKdViewCell *kdVc = dynamic_cast<VspKdViewCell *>(vc);
-
-	Mesh m;
-
-	ViewCellContainer leaves;
-	mViewCellsTree->CollectLeaves(vc, leaves);
-
-	ViewCellContainer::const_iterator it, it_end = leaves.end();
-
-	for (it = leaves.begin(); it != it_end; ++ it)
-	{
-		VspKdLeaf *l = dynamic_cast<VspKdViewCell *>(*it)->mLeaf;
-		IncludeBoxInMesh(mVspKdTree->GetBBox(l), m);
-	}
-
-	exporter->ExportMesh(&m);
-}
-
-
-void VspKdViewCellsManager::CreateMesh(ViewCell *vc)
-{
-	//TODO
-}
-
-
-void VspKdViewCellsManager::CollectMergeCandidates(const VssRayContainer &rays, 
-												   vector<MergeCandidate> &candidates)
-{
-	// TODO
-}
-
-
 /**************************************************************************/
 /*                   VspBspViewCellsManager implementation                */
@@ -4343,5 +3982,6 @@
 
 			//exporter->SetFilled();
-			bool b = mUseClipPlaneForViz;
+			// HACK: export without clip plane
+			const bool b = mUseClipPlaneForViz;
 			mUseClipPlaneForViz = false;
 			ExportViewCellsForViz(exporter);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h	(revision 1006)
@@ -158,5 +158,5 @@
 	struct VspBspSplitCandidate
 	{  
-		/// the current node
+		/// the current split plane
 		Plane3 mSplitPlane;
 		/// split axis of this plane (0, 1, 2, or 3 if non-axis-aligned)
@@ -467,7 +467,11 @@
 		@param plane returns the split plane
 		@param leaf the leaf to be split
-		@param polys the polygon list on which the split decition is based
-		@param rays ray container on which selection may be based
+		@param data the traversal data holding the polygons and rays which the split decision is based
+		@param frontData the front node traversal data (which may be updated to avoid repcomputations
+		@param backData the front node traversal data (which may be updated to avoid repcomputations
+		@param splitAxis 0 - 2 if axis aligned split, 3 if polygon-aligned split
+
 		@note the polygons can be reordered in the process
+		
 		@returns true if the cost of the split is under maxCostRatio
 
@@ -567,9 +571,4 @@
 								  float &position);
 
-	/** Selects an axis aligned split plane.
-		@Returns true if split is valied
-	*/
-	bool SelectAxisAlignedPlane(Plane3 &plane, const PolygonContainer &polys) const;
-
 	/** Subdivides the rays into front and back rays according to the split plane.
 		
@@ -649,8 +648,4 @@
 				  int &contributingSamples);
 
-
-
-
-
 	
 	/** Take 3 ray endpoints, where two are minimum and one a maximum
@@ -701,27 +696,32 @@
 	/** Returns estimated memory usage of tree.
 	*/
+	float GetMemUsage() const;
 	//float GetMemUsage(const VspBspTraversalQueue &tstack) const;
-	float GetMemUsage() const;
-
-
-
+
+
+
+	///////////////////////////////////////////////////////////
+protected:
+	
 	/// Pointer to the root of the tree
 	BspNode *mRoot;
-		
+	
+	/// the pointer to the view cells manager
+	ViewCellsManager *mViewCellsManager;
+	
+	/// View cell corresponding to the space outside the valid view space
+	BspViewCell *mOutOfBoundsCell;
+
+	/// the bsp tree statistics
 	BspTreeStatistics mBspStats;
 
-	/// Strategies for choosing next split plane.
-	enum {NO_STRATEGY = 0,
-		  RANDOM_POLYGON = 1, 
-		  AXIS_ALIGNED = 2,
-		  LEAST_RAY_SPLITS = 256,
-		  BALANCED_RAYS = 512,
-		  PVS = 1024
-		};
+	/// sorted split candidates used for sweep-heuristics
+	vector<SortableEntry> *mSplitCandidates;
 
 	/// box around the whole view domain
 	AxisAlignedBox3 mBox;
 
-	bool mUseCostHeuristics;
+	
+	//-- termination critera
 
 	/// minimal number of rays before subdivision termination
@@ -737,45 +737,94 @@
 	/// minimal accumulated ray length
 	float mTermMinAccRayLength;
-
-	//HACK
-	int mTermMinPolygons;
+	/// maximal acceptable cost ratio
+	float mTermMaxCostRatio;
+	/// tolerance value indicating how often the max cost ratio can be failed
+	int mTermMissTolerance;
+
+
+	//-- termination criteria for
+	//-- hybrid stategy where only axis aligned split are used until 
+	//-- a certain point and then also polygon aligned split are taken
+	 
+	/// minimal number of rays where axis aligned split is taken
+	int mTermMinRaysForAxisAligned;
+	/// max ray contribution
+	float mTermMaxRayContriForAxisAligned;
+	/// weight for heuristics evaluation
+	float mAxisAlignedCtDivCi;
+	/// spezifies the split border of the axis aligned split
+	float mAxisAlignedSplitBorder;
+
+
+	//-- global terminatino criteria
 
 	float mTermMinGlobalCostRatio;
 	int mTermGlobalCostMissTolerance;
-
 	int mGlobalCostMisses;
 
-	bool mUseSplitCostQueue;
-	//-- termination criteria for axis aligned split
-
-	/// minimal number of rays for axis aligned split
-	int mTermMinRaysForAxisAligned;
-	// max ray contribution
-	float mTermMaxRayContriForAxisAligned;
-
-	/// strategy to get the best split plane
-	int mSplitPlaneStrategy;
+	/// maximal number of view cells
+	int mMaxViewCells;
+	/// maximal tree memory
+	float mMaxMemory;
+	/// the tree is out of memory
+	bool mOutOfMemory;
+
+
 	/// number of candidates evaluated for the next split plane
 	int mMaxPolyCandidates;
 	/// number of candidates for split planes evaluated using the rays
 	int mMaxRayCandidates;
+	
+
+
+	//-- axis aligned split criteria
+
+	/// if only driving axis should be used for choosing the axis-aligned split
+	bool mOnlyDrivingAxis;
+	/// if heuristics should be used to place the split plane of an axis-aligned split
+	bool mUseCostHeuristics;
+	/// if driving axis should taken if max cost is exceeded for
+	/// all evaluated axis aligned split plane candidates
+	bool mUseDrivingAxisIfMaxCostViolated;
+	/// minimal relative position where the split axis can be placed
+	float mMinBand;
+	/// maximal relative position where the split axis can be placed
+	float mMaxBand;
 	/// balancing factor for PVS criterium
 	float mCtDivCi;
-
-	bool mUseDrivingAxisForMaxCost;
-	//-- axis aligned split criteria
-	float mAxisAlignedCtDivCi;
-	/// spezifies the split border of the axis aligned split
-	float mAxisAlignedSplitBorder;
-
-	/// maximal acceptable cost ratio
-	float mTermMaxCostRatio;
-	/// tolerance value indicating how often the max cost ratio can be failed
-	int mTermMissTolerance;
+	/// if random split axis should be used
+	bool mUseRandomAxis;
+	/// if vsp bsp tree should simulate octree
+	bool mCirculatingAxis;
+
+
+	
+	/// priority queue strategy
+	enum {BREATH_FIRST, DEPTH_FIRST, COST_BASED};
+	/// if we should use breath first priority for the splits
+	int mNodePriorityQueueType;
+	/// if split cost queue should be used to compute next best split
+	bool mUseSplitCostQueue;
+	
+
+	
+	/// Strategies for choosing next split plane.
+	enum {NO_STRATEGY = 0,
+		  RANDOM_POLYGON = 1, 
+		  AXIS_ALIGNED = 2,
+		  LEAST_RAY_SPLITS = 256,
+		  BALANCED_RAYS = 512,
+		  PVS = 1024
+		};
+
+	/// strategy to get the best split plane
+	int mSplitPlaneStrategy;
 
 	//-- factors guiding the split plane heuristics
+
 	float mLeastRaySplitsFactor;
 	float mBalancedRaysFactor;
 	float mPvsFactor;
+
 
 	/// if area or volume should be used for PVS heuristics
@@ -787,40 +836,18 @@
 	/// normalizes different bsp split plane criteria
 	float mCostNormalizer;
-	/// maximal number of view cells
-	int mMaxViewCells;
-	
-	ofstream  mSubdivisionStats;
-
 	// if rays should be stored in leaves
 	bool mStoreRays;
-	
-	/// if only driving axis should be used for split
-	bool mOnlyDrivingAxis;
-
-	ViewCellsManager *mViewCellsManager;
-
-	vector<SortableEntry> *mSplitCandidates;
-
-	
+	/// render cost weight between expected value and variance
 	float mRenderCostWeight;
-	/// View cell corresponding to the space outside the valid view space
-	BspViewCell *mOutOfBoundsCell;
-
-	/// maximal tree memory
-	float mMaxMemory;
-	/// the tree is out of memory
-	bool mOutOfMemory;
-	
+	
+
+	//-- subdivision statistics
+
+	/// subdivision stats output file
+	ofstream mSubdivisionStats;
 	float mTotalCost;
 	int mTotalPvsSize;
 
-	float mMinBand;
-	float mMaxBand;
-
-	//int mSplits;
-	/// subdivision stats output file
-	ofstream mSubdivsionStats;
-	/// if random split axis should be used
-	bool mUseRandomAxis;
+
 	/// use polygon split whenever there are polys left
 	bool mUsePolygonSplitIfAvailable;
@@ -829,14 +856,6 @@
 	/// number of currenly generated view cells
 	int mCreatedViewCells;
-	/// if vsp bsp tree should simulate octree
-	bool mCirculatingAxis;
-
-	/// if we should use breath first priority for the splits
-	int mNodePriorityQueueType;
-
-	bool mEmptyViewCellsMergeAllowed;
-
-	// priority queue strategy
-	enum {BREATH_FIRST, DEPTH_FIRST, COST_BASED};
+
+
 private:
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BoundingBoxConverter.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BoundingBoxConverter.h	(revision 939)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BoundingBoxConverter.h	(revision 1006)
@@ -6,5 +6,5 @@
 namespace GtpVisibilityPreprocessor {
 
-/** helper struct used for identifying objects with similar bounding boxes.
+/** helper struct used to identify objects with similar bounding boxes.
 */
 struct IndexedBoundingBox: public std::pair<int, AxisAlignedBox3>
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1002)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.h	(revision 1006)
@@ -1,4 +1,4 @@
-#ifndef _VspBspTree_H__
-#define _VspBspTree_H__
+#ifndef _VspOspTree_H__
+#define _VspOspTree_H__
 
 #include "Mesh.h"
@@ -31,25 +31,50 @@
 
 /**
-	This is a view space partitioning specialised BSPtree.  
-	There are no polygon splits, but we split the sample rays. 
-	The candidates for the next split plane are evaluated only 
-	by checking the sampled	visibility information. 
-	The polygons are employed merely as candidates for the next split planes.
+	This class implements a structure holding two different hierarchies,
+	one for object space partitioning and one for view space partitioning.
+
+	The object space and the view space are subdivided using a cost heuristics.
+	If an object space split or a view space split is chosen is also evaluated
+	based on the heuristics. 
+	
+	The view space heuristics is evaluated by weighting and adding the pvss of the back and
+	front node of each specific split. unlike for the standalone method vspbsp tree,
+	the pvs of an object would not be the pvs of single object but that of all objects
+	which are contained in the same leaf of the object subdivision. This could be done
+	by storing the pointer to the object space partition parent, which would allow access to all children.
+	Another possibility is to include traced kd-cells in the ray casing process.
+
+	Accordingly, the object space heuristics is evaluated by storing a pvs of view cells with each object.
+	the contribution to an object to the pvs is the number of view cells it can be seen from.
+
+
+	There is a potential efficiency problem involved in a sense that once a certain type
+	of split is chosen for view space / object space, the candidates for the next split of 
+	object space / view space must be reevaluated.
+	
 */
-class VspBspTree 
+class VspOspTree 
 {
 	friend class ViewCellsParseHandlers;
 	friend class VspBspViewCellsManager;
+
 public:
 	
+	/** A definition for an axis aligned plane.
+	*/
+	struct AxisAlignedPlane
+	{
+	public:
+		int mAxis;
+		float mPosition;
+	};
+
 	/** Additional data which is passed down the BSP tree during traversal.
 	*/
-	class VspBspTraversalData
+	class VspOspTraversalData
 	{  
 	public:
 		/// the current node
 		BspNode *mNode;
-		/// polygonal data for splitting
-		PolygonContainer *mPolygons;
 		/// current depth
 		int mDepth;
@@ -58,12 +83,10 @@
 		/// the probability that this node contains view point
 		float mProbability;
-		/// geometry of node as induced by planes
-		BspNodeGeometry *mGeometry;
+		/// the bounding box of the node
+		AxisAlignedBox3 mBoundingBox;
 		/// pvs size
 		int mPvs;
 		/// how often this branch has missed the max-cost ratio
 		int mMaxCostMisses;
-		/// if this node is a kd-node (i.e., boundaries are axis aligned
-		bool mIsKdNode;
 		// current axis
 		int mAxis;
@@ -80,52 +103,44 @@
 
 
-		VspBspTraversalData():
+		VspOspTraversalData():
 		mNode(NULL),
-		mPolygons(NULL),
 		mDepth(0),
 		mRays(NULL),
 		mPvs(0),
 		mProbability(0.0),
-		mGeometry(NULL),
 		mMaxCostMisses(0), 
-		mIsKdNode(false),
 		mPriority(0),
 		mAxis(0)
 		{}
 		
-		VspBspTraversalData(BspNode *node, 
-							PolygonContainer *polys, 
+		VspOspTraversalData(BspNode *node, 
 							const int depth, 
 							RayInfoContainer *rays,
 							const int pvs,
 							const float p,
-							BspNodeGeometry *geom): 
+							const AxisAlignedBox3 &box): 
 		mNode(node), 
-		mPolygons(polys), 
 		mDepth(depth), 
 		mRays(rays),
 		mPvs(pvs),
 		mProbability(p),
-		mGeometry(geom),
+		mBoundingBox(box),
 		mMaxCostMisses(0),
-		mIsKdNode(false),
 		mPriority(0),
 		mAxis(0)
 		{}
 
-		VspBspTraversalData(PolygonContainer *polys, 
+		VspOspTraversalData(PolygonContainer *polys, 
 							const int depth, 
 							RayInfoContainer *rays,
-							BspNodeGeometry *geom): 
+							const AxisAlignedBox3 &box): 
 		mNode(NULL), 
-		mPolygons(polys), 
 		mDepth(depth), 
 		mRays(rays),
 		mPvs(0),
 		mProbability(0),
-		mGeometry(geom),
 		mMaxCostMisses(0),
-		mIsKdNode(false),
-		mAxis(0)
+		mAxis(0),
+		mBoundingBox(box)
 		{}
 
@@ -141,10 +156,8 @@
 		void Clear()
 		{
-			DEL_PTR(mPolygons);
 			DEL_PTR(mRays);
-			DEL_PTR(mGeometry);
-		}
-
-		friend bool operator<(const VspBspTraversalData &a, const VspBspTraversalData &b)
+		}
+
+		friend bool operator<(const VspOspTraversalData &a, const VspOspTraversalData &b)
 		{
 			return a.GetCost() < b.GetCost();
@@ -153,25 +166,22 @@
 	
 
-	typedef std::priority_queue<VspBspTraversalData> VspBspTraversalQueue;
-	
-	
-	struct VspBspSplitCandidate
+	typedef std::priority_queue<VspOspTraversalData> VspOspTraversalQueue;
+	
+	
+	struct VspOspSplitCandidate
 	{  
-		/// the current node
-		Plane3 mSplitPlane;
-		/// split axis of this plane (0, 1, 2, or 3 if non-axis-aligned)
-		int mSplitAxis;
+		/// the current plane
+		AxisAlignedPlane mSplitPlane;
 		/// the number of misses of max cost ratio until this split
 		int mMaxCostMisses;
-
-		// parent data
-		VspBspTraversalData mParentData;
-		// cost of applying this split
+		/// parent data
+		VspOspTraversalData mParentData;
+		/// cost of applying this split
 		float mRenderCost;
 
-		VspBspSplitCandidate(): mRenderCost(0) 
+		VspOspSplitCandidate(): mRenderCost(0) 
 		{};
 
-		VspBspSplitCandidate(const Plane3 &plane, const VspBspTraversalData &tData): 
+		VspOspSplitCandidate(const AxisAlignedPlane &plane, const VspOspTraversalData &tData): 
 		mSplitPlane(plane), mParentData(tData), mRenderCost(0)
 		{}
@@ -189,5 +199,5 @@
 		}
 
-		friend bool operator<(const VspBspSplitCandidate &a, const VspBspSplitCandidate &b)
+		friend bool operator<(const VspOspSplitCandidate &a, const VspOspSplitCandidate &b)
 		{
 			return a.GetCost() < b.GetCost();
@@ -195,19 +205,13 @@
     };
 
-	typedef std::priority_queue<VspBspSplitCandidate> VspBspSplitQueue;
+	typedef std::priority_queue<VspOspSplitCandidate> VspOspSplitQueue;
 
 	/** Default constructor creating an empty tree.
 	*/ 
-	VspBspTree();
-
-	
-	/** Constructor creating an empty tree. Loads parameters 
-		from an environment file.
-	*/ 
-	VspBspTree(Environment *env);
+	VspOspTree();
 
 	/** Default destructor.
 	*/
-	~VspBspTree();
+	~VspOspTree();
 
 	/** Returns BSP Tree statistics.
@@ -252,6 +256,4 @@
 	int CastRay(Ray &ray);
 
-	/// bsp tree construction types
-	enum {FROM_INPUT_VIEW_CELLS, FROM_SCENE_GEOMETRY, FROM_SAMPLES};
 
 	/** finds neighbouring leaves of this tree node.
@@ -260,13 +262,4 @@
 					  vector<BspLeaf *> &neighbors, 
 					  const bool onlyUnmailed) const;
-
-	/** Constructs geometry associated with the half space intersections 
-		leading to this node.
-	*/
-	void ConstructGeometry(BspNode *n, BspNodeGeometry &geom) const;
-	
-	/** Construct geometry of view cell.
-	*/
-	void ConstructGeometry(ViewCell *vc, BspNodeGeometry &geom) const;
 
 	/** Returns random leaf of BSP tree.
@@ -400,27 +393,27 @@
 	/** faster evaluation of split plane cost for kd axis aligned cells.
 	*/
-	float EvalAxisAlignedSplitCost(const VspBspTraversalData &data,
-								   const AxisAlignedBox3 &box,
-								   const int axis,
-								   const float &position,
-								   float &pFront,
-								   float &pBack) const;
+	float EvalSplitCost(const VspOspTraversalData &data,
+						const AxisAlignedBox3 &box,
+						const int axis,
+						const float &position,
+						float &pFront,
+						float &pBack) const;
 
 	/** Evaluates candidate for splitting.
 	*/
-	void EvalSplitCandidate(VspBspTraversalData &tData, VspBspSplitCandidate &splitData);
+	void EvalSplitCandidate(VspOspTraversalData &tData, VspOspSplitCandidate &splitData);
 
 	/** Computes priority of the traversal data and stores it in tData.
 	*/
-	void EvalPriority(VspBspTraversalData &tData) const;
+	void EvalPriority(VspOspTraversalData &tData) const;
 
 	/** Evaluates render cost decrease of next split.
 	*/
 	float EvalRenderCostDecrease(const Plane3 &candidatePlane,
-								 const VspBspTraversalData &data) const;
+								 const VspOspTraversalData &data) const;
 
 	/** Constructs tree using the split priority queue.
 	*/
-	void ConstructWithSplitQueue(const PolygonContainer &polys, RayInfoContainer *rays);
+	void Construct(RayInfoContainer *rays);
 
 	/** Collects view cells in the subtree under root.
@@ -451,5 +444,5 @@
 	/** Evaluates tree stats in the BSP tree leafs.
 	*/
-	void EvaluateLeafStats(const VspBspTraversalData &data);
+	void EvaluateLeafStats(const VspOspTraversalData &data);
 
 	/** Subdivides node with respect to the traversal data.
@@ -458,44 +451,8 @@
 		@returns new root of the subtree
 	*/
-	BspNode *Subdivide(VspBspTraversalQueue &tStack, 
-					   VspBspTraversalData &tData);
-
-	BspNode *Subdivide(VspBspSplitQueue &tQueue,
-					   VspBspSplitCandidate &splitCandidate);
-
-	/** Constructs the tree from the given traversal data.
-		@param polys stores set of polygons on which subdivision may be based
-		@param rays storesset of rays on which subdivision may be based
-	*/
-	void Construct(const PolygonContainer &polys, RayInfoContainer *rays);
-
-	/** Selects the best possible splitting plane. 
-		@param plane returns the split plane
-		@param leaf the leaf to be split
-		@param polys the polygon list on which the split decition is based
-		@param rays ray container on which selection may be based
-		@note the polygons can be reordered in the process
-		@returns true if the cost of the split is under maxCostRatio
-
-	*/
-	bool SelectPlane(Plane3 &plane, 
-					 BspLeaf *leaf, 
-					 VspBspTraversalData &data,
-					 VspBspTraversalData &frontData,
-					 VspBspTraversalData &backData,
-					 int &splitAxis);
-	
-	/** Strategies where the effect of the split plane is tested
-	    on all input rays.
-
-		@returns the cost of the candidate split plane
-	*/
-	float EvalSplitPlaneCost(const Plane3 &candidatePlane, 
-							 const VspBspTraversalData &data,
-							 BspNodeGeometry &geomFront,
-							 BspNodeGeometry &geomBack,
-							 float &pFront,
-							 float &pBack) const;
-
+	BspNode *Subdivide(VspOspSplitQueue &tQueue,
+					   VspOspSplitCandidate &splitCandidate);
+
+	
 	/** Subdivides leaf.
 		@param leaf the leaf to be subdivided
@@ -513,45 +470,15 @@
 
 	BspInterior *SubdivideNode(const Plane3 &splitPlane,
-							   VspBspTraversalData &tData,
-							   VspBspTraversalData &frontData,
-                               VspBspTraversalData &backData,
-							   PolygonContainer &coincident);
-
-	/** Extracts the meshes of the objects and adds them to polygons. 
-		Adds object aabb to the aabb of the tree.
-		@param maxPolys the maximal number of objects to be stored as polygons
-		@returns the number of polygons
-	*/
-	int AddToPolygonSoup(const ObjectContainer &objects, 
-						 PolygonContainer &polys, 
-						 int maxObjects = 0);
-
-	/** Extracts the meshes of the view cells and and adds them to polygons.
-		Adds view cell aabb to the aabb of the tree.
-		@param maxPolys the maximal number of objects to be stored as polygons
-		@returns the number of polygons
-	*/
-	int AddToPolygonSoup(const ViewCellContainer &viewCells, 
-						 PolygonContainer &polys, 
-						 int maxObjects = 0);
-
-	/** Extract polygons of this mesh and add to polygon container.
-		@param mesh the mesh that drives the polygon construction
-		@param parent the parent intersectable this polygon is constructed from
-		@returns number of polygons
-	*/
-	int AddMeshToPolygons(Mesh *mesh, PolygonContainer &polys, MeshInstance *parent);
+							   VspOspTraversalData &tData,
+							   VspOspTraversalData &frontData,
+                               VspOspTraversalData &backData);
 
 	/** Selects an axis aligned for the next split.
 		@returns cost for this split
 	*/
-	float SelectAxisAlignedPlane(Plane3 &plane, 
-								 const VspBspTraversalData &tData,
-								 int &axis,
-								 BspNodeGeometry **frontGeom,
-								 BspNodeGeometry **backGeom,
-								 float &pFront,
-								 float &pBack,
-								 const bool useKdSplit);
+	float SelectPlane(const VspOspTraversalData &tData,
+					  AxisAlignedPlane &plane,
+					  float &pFront,
+					  float &pBack);
 
 	/** Sorts split candidates for surface area heuristics for axis aligned splits.
@@ -573,9 +500,4 @@
 								  float &position);
 
-	/** Selects an axis aligned split plane.
-		@Returns true if split is valied
-	*/
-	bool SelectAxisAlignedPlane(Plane3 &plane, const PolygonContainer &polys) const;
-
 	/** Subdivides the rays into front and back rays according to the split plane.
 		
@@ -593,9 +515,4 @@
 				  RayInfoContainer &backRays) const;
 
-
-	/** Extracts the split planes representing the space bounded by node n.
-	*/
-	void ExtractHalfSpaces(BspNode *n, vector<Plane3> &halfSpaces) const;
-
 	/** Adds the object to the pvs of the front and back leaf with a given classification.
 
@@ -618,30 +535,9 @@
 	/** Returns true if tree can be terminated.
 	*/
-	inline bool LocalTerminationCriteriaMet(const VspBspTraversalData &data) const;
+	inline bool LocalTerminationCriteriaMet(const VspOspTraversalData &data) const;
 
 	/** Returns true if global tree can be terminated.
 	*/
-	inline bool GlobalTerminationCriteriaMet(const VspBspTraversalData &data) const;
-
-	/** Computes accumulated ray lenght of this rays.
-	*/
-	float AccumulatedRayLength(const RayInfoContainer &rays) const;
-
-	/** Splits polygons with respect to the split plane.
-
-		@param plane the split plane
-		@param polys the polygons to be split. the polygons are consumed and
-			   distributed to the containers frontPolys, backPolys, coincident.
-		@param frontPolys returns the polygons in the front of the split plane
-		@param backPolys returns the polygons in the back of the split plane
-		@param coincident returns the polygons coincident to the split plane
-
-		@returns the number of splits	
-	*/
-	int SplitPolygons(const Plane3 &plane,
-					  PolygonContainer &polys, 
-					  PolygonContainer &frontPolys, 
-					  PolygonContainer &backPolys, 
-					  PolygonContainer &coincident) const;
+	inline bool GlobalTerminationCriteriaMet(const VspOspTraversalData &data) const;
 
 	/** Adds ray sample contributions to the PVS.
@@ -655,41 +551,4 @@
 				  int &contributingSamples);
 
-
-
-
-
-	
-	/** Take 3 ray endpoints, where two are minimum and one a maximum
-		point or the other way round.
-	*/
-	Plane3 ChooseCandidatePlane(const RayInfoContainer &rays) const;
-
-	/** Take plane normal as plane normal and the midpoint of the ray.
-		PROBLEM: does not resemble any point where visibility is 
-		likely to change
-	*/
-	Plane3 ChooseCandidatePlane2(const RayInfoContainer &rays) const;
-
-	/** Fit the plane between the two lines so that the plane 
-		has equal shortest distance to both lines.
-	*/
-	Plane3 ChooseCandidatePlane3(const RayInfoContainer &rays) const;
-  
-	/** Collects candidates for merging.
-		@param leaves the leaves to be merged
-		@returns number of leaves in queue
-	*/
-	int CollectMergeCandidates(const vector<BspLeaf *> leaves, vector<MergeCandidate> &candidates);
-
-	/** Collects candidates for the merge in the merge queue.
-		@returns number of leaves in queue
-	*/
-	int CollectMergeCandidates(const VssRayContainer &rays, vector<MergeCandidate> &candidates);
-	
-	/** Preprocesses polygons and throws out all polygons which are coincident to
-		the view space box faces (they can be problematic).
-	*/
-	void PreprocessPolygons(PolygonContainer &polys);
-	
 	/** Propagates valid flag up the tree.
 	*/
@@ -707,8 +566,11 @@
 	/** Returns estimated memory usage of tree.
 	*/
-	//float GetMemUsage(const VspBspTraversalQueue &tstack) const;
 	float GetMemUsage() const;
 
 
+protected:
+
+	ViewCellsManager *mViewCellsManager;
+	vector<SortableEntry> *mSplitCandidates;
 
 	/// Pointer to the root of the tree
@@ -716,18 +578,14 @@
 		
 	BspTreeStatistics mBspStats;
-
-	/// Strategies for choosing next split plane.
-	enum {NO_STRATEGY = 0,
-		  RANDOM_POLYGON = 1, 
-		  AXIS_ALIGNED = 2,
-		  LEAST_RAY_SPLITS = 256,
-		  BALANCED_RAYS = 512,
-		  PVS = 1024
-		};
+	
+	/// View cell corresponding to the space outside the valid view space
+	BspViewCell *mOutOfBoundsCell;
 
 	/// box around the whole view domain
 	AxisAlignedBox3 mBox;
 
-	bool mUseCostHeuristics;
+
+
+	//-- local termination
 
 	/// minimal number of rays before subdivision termination
@@ -741,38 +599,4 @@
 	/// maximal contribution per ray
 	float mTermMaxRayContribution;
-	/// minimal accumulated ray length
-	float mTermMinAccRayLength;
-
-	//HACK
-	int mTermMinPolygons;
-
-	float mTermMinGlobalCostRatio;
-	int mTermGlobalCostMissTolerance;
-
-	int mGlobalCostMisses;
-
-	bool mUseSplitCostQueue;
-	//-- termination criteria for axis aligned split
-
-	/// minimal number of rays for axis aligned split
-	int mTermMinRaysForAxisAligned;
-	// max ray contribution
-	float mTermMaxRayContriForAxisAligned;
-
-	/// strategy to get the best split plane
-	int mSplitPlaneStrategy;
-	/// number of candidates evaluated for the next split plane
-	int mMaxPolyCandidates;
-	/// number of candidates for split planes evaluated using the rays
-	int mMaxRayCandidates;
-	/// balancing factor for PVS criterium
-	float mCtDivCi;
-
-	bool mUseDrivingAxisForMaxCost;
-	//-- axis aligned split criteria
-	float mAxisAlignedCtDivCi;
-	/// spezifies the split border of the axis aligned split
-	float mAxisAlignedSplitBorder;
-
 	/// maximal acceptable cost ratio
 	float mTermMaxCostRatio;
@@ -780,69 +604,60 @@
 	int mTermMissTolerance;
 
-	//-- factors guiding the split plane heuristics
-	float mLeastRaySplitsFactor;
-	float mBalancedRaysFactor;
-	float mPvsFactor;
-
-	/// if area or volume should be used for PVS heuristics
-	bool mUseAreaForPvs;
-	/// tolerance for polygon split
-	float mEpsilon;
-	/// maximal number of test rays used to evaluate candidate split plane
-	int mMaxTests;
-	/// normalizes different bsp split plane criteria
-	float mCostNormalizer;
+
+	//-- global criteria
+	float mTermMinGlobalCostRatio;
+	int mTermGlobalCostMissTolerance;
+	int mGlobalCostMisses;
+
 	/// maximal number of view cells
 	int mMaxViewCells;
-	
-	ofstream  mSubdivisionStats;
-
-	// if rays should be stored in leaves
-	bool mStoreRays;
-	
-	/// if only driving axis should be used for split
-	bool mOnlyDrivingAxis;
-
-	ViewCellsManager *mViewCellsManager;
-
-	vector<SortableEntry> *mSplitCandidates;
-
-	
-	float mRenderCostWeight;
-	/// View cell corresponding to the space outside the valid view space
-	BspViewCell *mOutOfBoundsCell;
-
 	/// maximal tree memory
 	float mMaxMemory;
 	/// the tree is out of memory
 	bool mOutOfMemory;
-	
-	float mTotalCost;
-	int mTotalPvsSize;
-
-	float mMinBand;
-	float mMaxBand;
-
-	//int mSplits;
-	/// subdivision stats output file
-	ofstream mSubdivsionStats;
+
+
+
+	//-- split heuristics based parameters
+	
+	bool mUseCostHeuristics;
+	/// balancing factor for PVS criterium
+	float mCtDivCi;	
+	/// if only driving axis should be used for split
+	bool mOnlyDrivingAxis;
 	/// if random split axis should be used
 	bool mUseRandomAxis;
-	/// use polygon split whenever there are polys left
-	bool mUsePolygonSplitIfAvailable;
+	/// if vsp bsp tree should simulate octree
+	bool mCirculatingAxis;
+	/// minimal relative position where the split axis can be placed
+	float mMinBand;
+	/// maximal relative position where the split axis can be placed
+	float mMaxBand;
+
+
 	/// current time stamp (used for keeping split history)
 	int mTimeStamp;
+	// if rays should be stored in leaves
+	bool mStoreRays;
+
+	/// epsilon for geometric comparisons
+	float mEpsilon;
+
+	/// if we should use breath first priority for the splits
+	int mNodePriorityQueueType;
+
+	// priority queue strategy
+	enum {BREATH_FIRST, DEPTH_FIRST, COST_BASED};
+
+
+	/// subdivision stats output file
+	ofstream  mSubdivisionStats;
+	/// keeps track of cost during subdivision
+	float mTotalCost;
+	/// keeps track of overall pvs size during subdivision
+	int mTotalPvsSize;
 	/// number of currenly generated view cells
 	int mCreatedViewCells;
-	/// if vsp bsp tree should simulate octree
-	bool mCirculatingAxis;
-
-	/// if we should use breath first priority for the splits
-	int mNodePriorityQueueType;
-
-	bool mEmptyViewCellsMergeAllowed;
-
-	// priority queue strategy
-	enum {BREATH_FIRST, DEPTH_FIRST, COST_BASED};
+
 private:
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 870)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.h	(revision 1006)
@@ -101,5 +101,7 @@
         mMax[axis] = value;
   }
-	
+
+  
+
   // the size of the box along all the axes
   Vector3 Size() const { return mMax - mMin; }
@@ -389,4 +391,8 @@
   void ExtractPolys(PolygonContainer &polys) const;
 
+  /** Splits the box into two separate boxes according to the split plane
+  */
+  void Split(const int axis, const float value, AxisAlignedBox3 &left, AxisAlignedBox3 &right);
+
 #define __EXTENT_HACK
   // get the extent of face
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCell.h	(revision 1006)
@@ -17,5 +17,4 @@
 class BspPvs;
 class BspLeaf;
-class VspKdTree;
 class VspKdLeaf;
 class KdLeaf;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/FromPointVisibilityTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/FromPointVisibilityTree.cpp	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/FromPointVisibilityTree.cpp	(revision 1006)
@@ -124,5 +124,4 @@
 	Environment::GetSingleton()->GetIntValue("FromPointVisibilityTree.nodePriorityQueueType", mNodePriorityQueueType);
 
-	Environment::GetSingleton()->GetBoolValue("ViewCells.PostProcess.emptyViewCellsMerge", mEmptyViewCellsMergeAllowed);
 	
 	char subdivisionStatsLog[100];
@@ -160,5 +159,5 @@
 	Debug << "use random axis: " << mUseRandomAxis << endl;
 	Debug << "priority queue type: " << mNodePriorityQueueType << endl;
-	Debug << "empty view cells merge: " << mEmptyViewCellsMergeAllowed << endl;
+	
 	Debug << "octree: " << mCirculatingAxis << endl;
 	Debug << "minband: " << mMinBand << endl;
@@ -3707,8 +3706,5 @@
 				MergeCandidate mc(leaf->GetViewCell(), (*nit)->GetViewCell());
 
-				// dont't merge view cells if they are empty and not front and back leaf of the same parent
-				// in the tree?
-				if (mEmptyViewCellsMergeAllowed ||
-					!leaf->GetViewCell()->GetPvs().Empty() || 
+				if (!leaf->GetViewCell()->GetPvs().Empty() || 
 					!(*nit)->GetViewCell()->GetPvs().Empty() ||
                     leaf->IsSibling(*nit))
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h	(revision 1006)
@@ -18,5 +18,4 @@
 
 class VspBspTree;
-class VspKdTree;
 class BspTree;
 class ViewCellsManager;
@@ -70,5 +69,4 @@
 
   VspBspTree *mVspBspTree;
-  VspKdTree *mVspKdTree;
   BspTree *mBspTree;
   ViewCellsTree *mViewCellsTree;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/GlRenderer.h	(revision 1006)
@@ -281,20 +281,20 @@
   signals:
   
-  SetViewCellGranularity(int);
-  SetSceneCut(int);
-  SetTopDistance(int);
-  SetVisibilityFilterSize(int);
-  SetSpatialFilterSize(int);
-
-  SetRenderFilter(bool);
-  SetUseFilter(bool);
-  SetUseSpatialFilter(bool);
-  SetRenderErrors(bool);
-  SetShowViewCells(bool);
-  SetShowRenderCost(bool);
-  SetShowPvsSizes(bool);
-  SetTopView(bool);
-  SetCutViewCells(bool);
-  SetCutScene(bool);
+  void SetViewCellGranularity(int);
+  void SetSceneCut(int);
+  void SetTopDistance(int);
+  void SetVisibilityFilterSize(int);
+  void SetSpatialFilterSize(int);
+
+  void SetRenderFilter(bool);
+  void SetUseFilter(bool);
+  void SetUseSpatialFilter(bool);
+  void SetRenderErrors(bool);
+  void SetShowViewCells(bool);
+  void SetShowRenderCost(bool);
+  void SetShowPvsSizes(bool);
+  void SetTopView(bool);
+  void SetCutViewCells(bool);
+  void SetCutScene(bool);
 
   
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 1004)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp	(revision 1006)
@@ -28,5 +28,4 @@
 #include "VspBspTree.h"
 #include "ViewCellBsp.h"
-#include "VspKdTree.h"
 #include "ViewCellsManager.h"
 #include "GzFileInputSource.h"
@@ -621,12 +620,4 @@
 
 		mViewCellsManager = new BspViewCellsManager(mBspTree);
-	}
-	
-	else if (strcmp(name, "vspKdTree") == 0)
-	{
-		// TODO
-		Debug << "view cell type: VspKd" << endl;
-		mVspKdTree = new VspKdTree();	
-		mViewCellsManager = new VspKdViewCellsManager(mVspKdTree);
 	}
 	else // vspBspTree
Index: GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 863)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/AxisAlignedBox3.cpp	(revision 1006)
@@ -2123,3 +2123,18 @@
 }
 
-}
+void AxisAlignedBox3::Split(const int axis, 
+							const float value, 
+							AxisAlignedBox3 &left, 
+							AxisAlignedBox3 &right)
+{
+	if ( (value >= mMin[axis]) && (value <= mMax[axis]) )
+	{
+		left.mMin = mMin; left.mMax = mMax;
+		right.mMin = mMin; right.mMax = mMax;
+
+		left.mMax[axis] = value;
+		right.mMin[axis] = value;
+
+	}
+}
+}
