Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 1291)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellBsp.h	(revision 1449)
@@ -207,4 +207,6 @@
 	int accumRays;
 	int pvs;
+	// global cost ratio violations
+	int mGlobalCostMisses;
 
 	// Constructor
@@ -227,5 +229,6 @@
 		for (int i = 0; i < 3; ++ i)
 			splits[i] = 0;
-		
+	
+		mGlobalCostMisses = 0;
 		maxDepth = 0;
 		minDepth = 99999;
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1418)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.cpp	(revision 1449)
@@ -474,5 +474,5 @@
 	mBspStats.nodes = 1;
 	mBspStats.polys = (int)polys.size();
-	mGlobalCostMisses = 0;
+	mBspStats.mGlobalCostMisses = 0;
 
 
@@ -676,10 +676,11 @@
 		//Debug << "cost ratio: " << costRatio << endl;
 		if (costRatio < mTermMinGlobalCostRatio)
-			++ mGlobalCostMisses;
-		
+		{
+			++ mBspStats.mGlobalCostMisses;
+		}
+
 		if (0 && !mOutOfMemory)
 		{
 			float mem = GetMemUsage();
-
 			if (mem > mMaxMemory)
 			{
@@ -693,6 +694,8 @@
 
 		if (r == mRoot)
+		{
 			Debug << "VSP BSP tree construction time spent at root: "
 				  << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;
+		}
 
 		if (mBspStats.Leaves() >= nLeaves)
@@ -753,5 +756,5 @@
 		|| mOutOfMemory 
 		|| (mBspStats.Leaves() >= mMaxViewCells) 
-		|| (mGlobalCostMisses >= mTermGlobalCostMissTolerance)
+		|| (mBspStats.mGlobalCostMisses >= mTermGlobalCostMissTolerance)
 		 );
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1444)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Environment.cpp	(revision 1449)
@@ -2464,4 +2464,9 @@
 					"-1");
 
+	RegisterOption("Hierarchy.Construction.useMultiLevelConstruction",
+					optBool,
+					"hierarchy_construction_use_multilevel_construction=",
+					"false");
+
 	//////////////////////////////////////////////////////////////////////////////////
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1415)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/RssPreprocessor.cpp	(revision 1449)
@@ -690,5 +690,5 @@
 	  t1 = GetTime();
 	  
-	  GenerateRays(mRssSamplesPerPass*ratios[0], RSS_BASED_DISTRIBUTION, rays);
+	  GenerateRays(int(mRssSamplesPerPass*ratios[0]), RSS_BASED_DISTRIBUTION, rays);
 
 	  rays.NormalizePdf((float)rays.size());
@@ -711,5 +711,5 @@
 	  if (ratios[1]!=0.0f) {
 		t1 = GetTime();
-		GenerateRays(mRssSamplesPerPass*ratios[1], SPATIAL_BOX_BASED_DISTRIBUTION, rays);
+		GenerateRays(int(mRssSamplesPerPass*ratios[1]), SPATIAL_BOX_BASED_DISTRIBUTION, rays);
 		CastRays(rays, tmpVssRays);
 		castRays += (int)rays.size();
@@ -733,5 +733,5 @@
 	  if (ratios[2]!=0.0f) {
 		t1 = GetTime();
-		GenerateRays(mRssSamplesPerPass*ratios[2], DIRECTION_BASED_DISTRIBUTION, rays);
+		GenerateRays(int(mRssSamplesPerPass*ratios[2]), DIRECTION_BASED_DISTRIBUTION, rays);
 		CastRays(rays, tmpVssRays);
 		castRays += (int)rays.size();
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1421)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.h	(revision 1449)
@@ -72,6 +72,8 @@
 	/// accumulated depth
 	int accumDepth;
-
+	/// time spent for queue repair
 	float repairTime;
+	// global cost ratio violations
+	int mGlobalCostMisses;
 
 	// Constructor
@@ -88,6 +90,7 @@
 	double AvgDepth() const { return accumDepth / (double)Leaves();}
 
-	void Reset() 
-	{
+	void Reset()
+	{
+		mGlobalCostMisses = 0;
 		nodes = 0;
 		maxDepth = 0;
@@ -247,8 +250,11 @@
 
 	void RunConstruction(
+		const bool repairQueue,
 		const VssRayContainer &sampleRays,
 		const ObjectContainer &objects,
 		AxisAlignedBox3 *forcedViewSpace);
-
+	
+	void RunConstruction(const bool repairQueue);
+		
 	bool ApplySubdivisionCandidate(SubdivisionCandidate *sc);
 
@@ -306,4 +312,16 @@
 	int GetObjectSpaceSubdivisionDepth() const;
 
+	void ConstructInterleaved(
+		const VssRayContainer &sampleRays,
+		const ObjectContainer &objects,
+		AxisAlignedBox3 *forcedViewSpace);
+
+	void ConstructMultiLevel(
+		const VssRayContainer &sampleRays,
+		const ObjectContainer &objects,
+		AxisAlignedBox3 *forcedViewSpace);
+
+	void ResetObjectSpaceSubdivision(const ObjectContainer &objects);
+
 protected:
 
@@ -329,9 +347,9 @@
 	SubdivisionCandidate *mCurrentCandidate;
 
+	////////
 	//-- global criteria
 	float mTermMinGlobalCostRatio;
 	int mTermGlobalCostMissTolerance;
-	int mGlobalCostMisses;
-
+	
 	/// keeps track of cost during subdivision
 	float mTotalCost;
@@ -348,4 +366,6 @@
 
 	bool mStartWithObjectSpace;
+
+	bool mUseMultiLevelConstruction;
 };
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.h	(revision 1379)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/OspTree.h	(revision 1449)
@@ -79,9 +79,11 @@
 	/// accumulated number of rays refs
 	int accumRays;
-	/// potentially visible objects from this leaf
+	/// overall potentially visible objects
 	int pvs;
-
 	// accumulated depth (used to compute average)
 	int accumDepth;
+	// global cost ratio violations
+	int mGlobalCostMisses;
+
 
 	// Constructor
@@ -111,16 +113,13 @@
 		maxDepthNodes = 0;
 		minPvsNodes = 0;
-	
 		minProbabilityNodes = 0;
 		maxCostNodes = 0;
-
 		contributingSamples = 0;
 		sampleContributions = 0;
-
 		maxPvs = 0;
 		invalidLeaves = 0;
 		objectRefs = 0;
-
 		maxObjectRefs = 0;
+		mGlobalCostMisses = 0;
 	}
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 1379)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.h	(revision 1449)
@@ -82,7 +82,10 @@
 	/// accumulated number of rays refs
 	int accumRays;
+	/// overall pvs size
 	int pvs;
 	// accumulated depth (used to compute average)
 	int accumDepth;
+	// global cost ratio violations
+	int mGlobalCostMisses;
 
 	// Constructor
@@ -124,4 +127,5 @@
 		accumRays = 0;
 		maxObjectRefs = 0;
+		mGlobalCostMisses = 0;
 	}
 
@@ -1002,5 +1006,5 @@
 	float mTermMinGlobalCostRatio;
 	int mTermGlobalCostMissTolerance;
-	int mGlobalCostMisses;
+	
 
 	/// maximal number of view cells
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1444)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp	(revision 1449)
@@ -525,5 +525,5 @@
 		(0
 		|| (mBvhStats.Leaves() >= mTermMaxLeaves)
-		|| (mGlobalCostMisses >= mTermGlobalCostMissTolerance)
+		|| (mBvhStats.mGlobalCostMisses >= mTermGlobalCostMissTolerance)
 		//|| mOutOfMemory 
 		);
@@ -532,5 +532,5 @@
 	{
 		Debug << "bvh global termination criteria met:" << endl;
-		Debug << "cost misses: " << mGlobalCostMisses << " " << mTermGlobalCostMissTolerance << endl;
+		Debug << "cost misses: " << mBvhStats.mGlobalCostMisses << " " << mTermGlobalCostMissTolerance << endl;
 		Debug << "leaves: " << mBvhStats.Leaves() << " " << mTermMaxLeaves << endl;
 	}
@@ -1623,5 +1623,7 @@
 void BvHierarchy::CreateRoot(const ObjectContainer &objects)
 {
+	///////
 	//-- create new root
+
 	AxisAlignedBox3 box = EvalBoundingBox(objects);
 	BvhLeaf *bvhleaf = new BvhLeaf(box, NULL, (int)objects.size());
@@ -1661,5 +1663,5 @@
 
 	mBvhStats.nodes = 1;
-	mGlobalCostMisses = 0;
+	
 	
 	// store pointer to this tree
@@ -1699,5 +1701,5 @@
 	
 
-	////////////////////////////////////////////////////
+	///////////////////
 	//-- add first candidate for object space partition	
 
@@ -1847,4 +1849,6 @@
 		maxRayContriNodes * 100 / (double)Leaves() << endl;
 
+	app << "#N_PGLOBALCOSTMISSES ( Global cost misses )\n" << mGlobalCostMisses << endl;
+
 	app << "========== END OF BvHierarchy statistics ==========\n";
 }
Index: GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1444)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp	(revision 1449)
@@ -4924,5 +4924,4 @@
 	if (0 && mExportViewCells)
 	{
-		cout << "here5" << endl;
 		char filename[100];
 		Environment::GetSingleton()->GetStringValue("ViewCells.filename", filename);
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h	(revision 1288)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspBspTree.h	(revision 1449)
@@ -774,11 +774,9 @@
 	float mAxisAlignedSplitBorder;
 
-
+	///////////
 	//-- global terminatino criteria
-
 	float mTermMinGlobalCostRatio;
 	int mTermGlobalCostMissTolerance;
-	int mGlobalCostMisses;
-
+	
 	/// maximal number of view cells
 	int mMaxViewCells;
@@ -795,5 +793,5 @@
 	
 
-
+	//////////
 	//-- axis aligned split criteria
 
Index: GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1408)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h	(revision 1449)
@@ -88,4 +88,5 @@
 		rayRefs = 0;
 		maxRayContriNodes = 0;
+		mGlobalCostMisses = 0;
 	}
 
@@ -109,6 +110,8 @@
 	/// nodes termination because of max cost ratio;
 	int maxCostNodes;
-
-	///////////////////////////
+	// global cost ratio violations
+	int mGlobalCostMisses;
+
+	//////////////////
 	// nodes with minimum objects
 	int minObjectsNodes;
@@ -799,5 +802,5 @@
 
 
-	////////////////////////////////
+	////////////////////
 	//-- local termination criteria
 
@@ -816,10 +819,10 @@
 
 
-	////////////////////////////////////
+	////////////////////
 	//-- global termination criteria
 
 	float mTermMinGlobalCostRatio;
 	int mTermGlobalCostMissTolerance;
-	int mGlobalCostMisses;
+	
 
 	/// maximal number of view cells
Index: GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1444)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp	(revision 1449)
@@ -127,6 +127,7 @@
 	app << "#N_INVALIDLEAVES (number of invalid leaves )\n" << invalidLeaves << endl;
 
-	app << "#N_RAYS (number of rays / leaf)\n" << AvgRays() << endl;
-	
+	app << "#AVGRAYS (number of rays / leaf)\n" << AvgRays() << endl;
+	
+	app << "#N_GLOBALCOSTMISSES ( Global cost misses )\n" << mGlobalCostMisses << endl;
 
 	app << "========== END OF VspTree statistics ==========\n";
@@ -561,5 +562,5 @@
 		// || mOutOfMemory
 		|| (mVspStats.Leaves() >= mMaxViewCells)
-        || (mGlobalCostMisses >= mTermGlobalCostMissTolerance) 
+        || (mVspStats.mGlobalCostMisses >= mTermGlobalCostMissTolerance) 
 		);
 
@@ -567,5 +568,5 @@
 	{
 		Debug << "vsp global termination criteria met:" << endl;
-		Debug << "cost misses: " << mGlobalCostMisses << " " << mTermGlobalCostMissTolerance << endl;
+		Debug << "cost misses: " << mVspStats.mGlobalCostMisses << " " << mTermGlobalCostMissTolerance << endl;
 		Debug << "leaves: " << mVspStats.Leaves() << " " <<  mMaxViewCells << endl;
 	}
@@ -2677,9 +2678,8 @@
 	// initialise termination criteria
 	mTermMinProbability *= mBoundingBox.GetVolume();
-	mGlobalCostMisses = 0;
-
 	// get clipped rays
 	PreprocessRays(sampleRays, rays);
 
+	/// collect pvs from rays
 	const int pvsSize = EvalPvsSize(rays);
 	
Index: GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1444)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp	(revision 1449)
@@ -106,4 +106,8 @@
 		"Hierarchy.Construction.repairQueue", mRepairQueue);
 
+	Environment::GetSingleton()->GetBoolValue(
+		"Hierarchy.Construction.useMultiLevelConstruction", mUseMultiLevelConstruction);
+
+	 mUseMultiLevelConstruction;
 	Debug << "******** Hierachy Manager Parameters ***********" << endl;
 	Debug << "max leaves: " << mTermMaxLeaves << endl;
@@ -113,4 +117,5 @@
 	Debug << "min depth for object space subdivision: " << mMinDepthForObjectSpaceSubdivion << endl;
 	Debug << "repair queue: " << mRepairQueue << endl;
+	Debug << endl;
 }
 
@@ -234,6 +239,6 @@
 		(0
 		|| (mHierarchyStats.Leaves() >= mTermMaxLeaves) 
-		|| (mGlobalCostMisses >= mTermGlobalCostMissTolerance)
-		||(candidate->GlobalTerminationCriteriaMet())
+		|| (mHierarchyStats.mGlobalCostMisses >= mTermGlobalCostMissTolerance)
+		|| (candidate->GlobalTerminationCriteriaMet())
 		);
 
@@ -242,5 +247,5 @@
 		Debug << "hierarchy global termination criteria met:" << endl;
 		Debug << "leaves: " << mHierarchyStats.Leaves() << " " << mTermMaxLeaves << endl;
-		Debug << "cost misses: " << mGlobalCostMisses << " " << mTermGlobalCostMissTolerance << endl;
+		Debug << "cost misses: " << mHierarchyStats.mGlobalCostMisses << " " << mTermGlobalCostMissTolerance << endl;
 	}
 	return terminationCriteriaMet;
@@ -252,7 +257,23 @@
 								 AxisAlignedBox3 *forcedViewSpace)
 {
+	if (mUseMultiLevelConstruction)
+	{
+		ConstructMultiLevel(sampleRays, objects, forcedViewSpace);
+	}
+	else
+	{
+		ConstructInterleaved(sampleRays, objects, forcedViewSpace);
+	}
+}
+
+
+void HierarchyManager::ConstructInterleaved(const VssRayContainer &sampleRays,
+											const ObjectContainer &objects,
+											AxisAlignedBox3 *forcedViewSpace)
+{
 	mHierarchyStats.Reset();
 	mHierarchyStats.Start();
-	
+	mHierarchyStats.nodes = 2; // two nodes for view space and object space
+
 	mTotalCost = (float)objects.size();
 	Debug << "setting total cost to " << mTotalCost << endl;
@@ -287,5 +308,5 @@
 
 	// process object space candidates
-	RunConstruction(sampleRays, objects, forcedViewSpace);
+	RunConstruction(mRepairQueue, sampleRays, objects, forcedViewSpace);
 	
 	cout << "\nfinished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
@@ -342,5 +363,5 @@
 
 	cout << "preparing bv hierarchy construction ... " << endl;
-	mBvHierarchy->CreateRoot(objects);
+		mBvHierarchy->CreateRoot(objects);
 
 	// compute first candidate
@@ -390,5 +411,5 @@
 		if (costRatio < mTermMinGlobalCostRatio)
 		{
-			++ mGlobalCostMisses;
+			++ mHierarchyStats.mGlobalCostMisses;
 		}
 
@@ -484,11 +505,9 @@
 
 
-void HierarchyManager::RunConstruction(const VssRayContainer &sampleRays,
+void HierarchyManager::RunConstruction(const bool repairQueue,
+									   const VssRayContainer &sampleRays,
 									   const ObjectContainer &objects,
 									   AxisAlignedBox3 *forcedViewSpace)
 {
-	mHierarchyStats.nodes = 0;
-	mGlobalCostMisses = 0;
-
 	int i = 0;
 	while (!FinishedConstruction())
@@ -511,5 +530,5 @@
 			// reevaluate candidates affected by the split for view space splits, 
 			// this would be object space splits and other way round
-			if (mRepairQueue) RepairQueue();
+			if (repairQueue) RepairQueue();
 		}
 
@@ -548,4 +567,103 @@
 		DEL_PTR(mCurrentCandidate);
 	}
+}
+
+
+
+void HierarchyManager::RunConstruction(const bool repairQueue)
+{
+	int i = 0;
+	while (!FinishedConstruction())
+	{
+		mCurrentCandidate = NextSubdivisionCandidate();    
+			
+		///////////////////
+		//-- subdivide leaf node
+
+		if (ApplySubdivisionCandidate(mCurrentCandidate))
+		{
+			cout << mCurrentCandidate->Type() << " ";
+			if (0) cout << "subdividing candidate " << ++ i << " of type " 
+						<< mCurrentCandidate->Type() << endl;
+			mHierarchyStats.nodes += 2;
+
+			// subdivision successful
+			EvalSubdivisionStats(*mCurrentCandidate);
+		
+			// reevaluate candidates affected by the split for view space splits, 
+			// this would be object space splits and other way round
+			if (repairQueue) RepairQueue();
+		}
+
+		DEL_PTR(mCurrentCandidate);
+	}
+}
+
+
+void HierarchyManager::ResetObjectSpaceSubdivision(const ObjectContainer &objects)
+{
+	Debug << "old bv hierarchy: " << mBvHierarchy->mBvhStats << endl;
+	mHierarchyStats.nodes -= mBvHierarchy->mBvhStats.nodes;
+	mHierarchyStats.mGlobalCostMisses = 0; // hack: reset global cost misses
+	DEL_PTR(mBvHierarchy);
+	mBvHierarchy = new BvHierarchy();
+	mBvHierarchy->mHierarchyManager = this;
+}
+
+
+void HierarchyManager::ConstructMultiLevel(const VssRayContainer &sampleRays,											 
+										   const ObjectContainer &objects,
+										   AxisAlignedBox3 *forcedViewSpace)
+{
+	mHierarchyStats.Reset();
+	mHierarchyStats.Start();
+
+	mHierarchyStats.nodes = 2;
+	
+
+	mTotalCost = (float)objects.size();
+	Debug << "setting total cost to " << mTotalCost << endl;
+
+	const long startTime = GetTime();
+	cout << "Constructing view space / object space tree ... \n";
+	
+	// compute view space bounding box
+	mVspTree->ComputeBoundingBox(sampleRays, forcedViewSpace);
+
+	// use sah for evaluating object space construction for the first run
+	mSavedViewSpaceSubdivisionType = mViewSpaceSubdivisionType;
+	mViewSpaceSubdivisionType = NO_VIEWSPACE_SUBDIV;
+
+	// start with object space subdivision
+	PrepareObjectSpaceSubdivision(sampleRays, objects);
+	
+	// process object space candidates
+	RunConstruction(false);
+
+	/////////////////
+    // now do view space subdivison on the sah bvh nodes
+	mViewSpaceSubdivisionType = mSavedViewSpaceSubdivisionType;
+	PrepareViewSpaceSubdivision(sampleRays, objects);
+	
+	// process view space candidates
+	RunConstruction(false);
+	
+	// again run object space subdivision on the view cells
+	ResetObjectSpaceSubdivision(objects);
+	PrepareObjectSpaceSubdivision(sampleRays, objects);
+
+	// process object space candidates
+	RunConstruction(false);
+	
+	cout << "\nfinished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl;
+
+#if _DEBUG
+	cout << "view space: " << GetViewSpaceBox() << endl;
+	cout << "object space:  " << GetObjectSpaceBox() << endl;
+#endif
+
+	mHierarchyStats.Stop();
+	mVspTree->mVspStats.Stop();
+	FinishObjectSpaceSubdivision(objects);
 }
 
@@ -863,4 +981,6 @@
 
 	app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl;
+
+	app << "#N_GLOBALCOSTMISSES ( Global cost misses )\n" << mGlobalCostMisses << endl;
 	
 	app << "========== END OF Hierarchy statistics ==========\n";
Index: GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp
===================================================================
--- GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1420)
+++ GTP/trunk/Lib/Vis/Preprocessing/src/Mesh.cpp	(revision 1449)
@@ -735,4 +735,6 @@
 }
 
+
+
 /********************************************************/
 /*	    		MeshInstance implementation             */
