Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.h	(revision 2752)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.h	(revision 2755)
@@ -4,5 +4,5 @@
 #include "common.h"
 #include "AxisAlignedBox3.h"
-
+#include "Triangle3.h"
 
 
@@ -23,4 +23,7 @@
 	Geometry(const TriangleContainer &triangles);
 
+	int CountTriangles() const { return (int)mTriangles.size(); }
+
+
 protected:
 
@@ -35,4 +38,6 @@
 class SceneEntity
 {
+public:
+
 	/** Create scene entity.
 	*/
@@ -44,7 +49,10 @@
 	*/
 	void SetGeometry(Geometry *geom);
+	/** See set
+	*/
+	Geometry *GetGeometry() const { return mGeometry; }
 	/** Set pointer to the geometry
 	*/
-	void SetTransformation(const Matrix4x4 *trafo);
+	void SetTransformation(Matrix4x4 *trafo);
 	/** Set pointer to the material
 	*/
@@ -59,4 +67,5 @@
 	*/
 	int GetLastVisited() const;
+
 
 protected:
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.h	(revision 2755)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.h	(revision 2755)
@@ -0,0 +1,27 @@
+#ifndef __CHCTRAVERSER_H
+#define __CHCTRAVERSER_H
+
+#include "RenderTraverser.h"
+
+
+namespace CHCDemo
+{
+
+/** Class implementing traversal using the CHC algorithm.
+*/
+class CHCTraverser: public RenderTraverser
+{
+public:
+	CHCTraverser();
+	~CHCTraverser();
+
+	/** Renders the scene with the specified method
+	*/
+	virtual void Render();
+};
+
+}
+
+
+
+#endif // __CHCTRAVERSER_H
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Material.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Material.h	(revision 2751)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Material.h	(revision 2755)
@@ -6,7 +6,10 @@
 {
 
+
 class RgbColor 
 {
+
 public:
+
   float r, g, b;
 
@@ -44,30 +47,19 @@
 {
 public:
+
   RgbColor mDiffuseColor;
   RgbColor mSpecularColor;
   RgbColor mAmbientColor;
   
-  Material(): mId(0)
-  {
-  }
+  Material();
   
-  Material(const int id): mId(id)
-  {
-  }
+  Material(const int id);
 
-  Material(const RgbColor &color):mDiffuseColor(color),
-								  mAmbientColor(color),
-								  mSpecularColor(0,0,0), mId(0)
-  {
-  }
-  
-  friend Material RandomMaterial();
-  
+  Material(const RgbColor &color);
   /** Returns unique material id.
   */
-  int GetId() const
-  {
-	  return mId;
-  }
+  int GetId() const;
+
+  friend Material RandomMaterial();
 
 protected:
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.h	(revision 2755)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.h	(revision 2755)
@@ -0,0 +1,27 @@
+#ifndef __CHCPLUSPLUSTRAVERSER_H
+#define __CHCPLUSPLUSTRAVERSER_H
+
+#include "RenderTraverser.h"
+
+
+namespace CHCDemo
+{
+
+/** Class implementing traversal using the CHC algorithm.
+*/
+class CHCPlusPlusTraverser: public RenderTraverser
+{
+public:
+	CHCPlusPlusTraverser();
+	~CHCPlusPlusTraverser();
+
+	/** Renders the scene with the specified method
+	*/
+	virtual void Render();
+};
+
+}
+
+
+
+#endif // __CHCTRAVERSER_H
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/BvhLoader.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/BvhLoader.h	(revision 2755)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/BvhLoader.h	(revision 2755)
@@ -0,0 +1,33 @@
+// This file has been written by Jiri Bittner, October 2006
+
+#ifndef __BVHLOADER_H
+#define __BVHLOADER_H
+
+#include "Bvh.h"
+
+
+namespace CHCDemo
+{
+
+/** Loader for a bounding volume hierarchy.
+*/
+class BvhLoader
+{
+public:
+
+	Bvh *LoadFromFile(const std::string &filename, const SceneEntityContainer &entities);
+
+protected:
+	
+	BvhLeaf *ImportBinLeaf(std::ifstream &stream, BvhInterior *parent);
+
+	BvhInterior *ImportBinInterior(std::ifstream &stream, BvhInterior *parent);
+
+	BvhNode *LoadNextNode(std::ifstream &stream, BvhInterior *parent);
+
+
+};
+
+}
+
+#endif // __BVHLOADER_H
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.cpp	(revision 2754)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.cpp	(revision 2755)
@@ -57,17 +57,29 @@
 }*/
 
-#if 0
-void RenderTraverser::TraverseNode(HierarchyNode *node)
-{
-	if(node->IsLeaf())
-		mNumRenderedGeometry += node->Render();
+void RenderTraverser::EnqueueNode(BvhNode *node)
+{
+	mBvh->CalcDistance(node);
+	mDistanceQueue.push(node);
+}
+
+
+void RenderTraverser::TraverseNode(BvhNode *node)
+{
+	if (node->IsLeaf())
+	{
+		//mNumRenderedGeometry += node->Render();
+	}
 	else 
 	{
 		// for non leafs this renders only the bounding volume (if the flag is set)
 		//node->Render();
-		mDistanceQueue.push(node->GetLeftChild());
-		mDistanceQueue.push(node->GetRightChild());
-	}
-}
+		BvhInterior *interior = static_cast<BvhInterior *>(node);
+
+		EnqueueNode(interior->GetFront());
+		EnqueueNode(interior->GetBack());
+	}
+}
+
+#if 0
 
 void RenderTraverser::RenderVisualization()
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.cpp	(revision 2752)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.cpp	(revision 2755)
@@ -1,21 +1,19 @@
 #include <queue>
 #include <stack>
-#include "Bvh.h"
-
 #include <fstream>
 #include <iostream>
 #include <iomanip>
 
+#include "Bvh.h"
+#include "Camera.h"
+#include "Plane3.h"
+#include "glInterface.h"
+#include "Triangle3.h"
+
 
 namespace CHCDemo
 {
 
-#if TOIMPLEMENT
-
 #define INVALID_TEST ((unsigned int)-1)
-
-#define TYPE_INTERIOR -2
-#define TYPE_LEAF -3
-#define USE_TIGHTER_BOUNDS_FOR_ALL 0
 
 const static bool useVbos = true;
@@ -62,4 +60,10 @@
 */
 
+static Plane3 sNearPlane;
+static Camera::Frustum sFrustum;
+
+/// these values are valid for all nodes
+static int sClipPlaneAABBVertexIndices[12];
+
 
 BvhNode::BvhNode(BvhNode *parent): 
@@ -69,5 +73,4 @@
 mPlaneMask(0),
 mPreferredPlane(0),
-mVizBox(NULL),
 mLastRenderedFrame(-999),
 mFirst(-1), 
@@ -75,5 +78,7 @@
 mNumTestNodes(1),
 mTestNodesIdx(-1),
-mIndicesPtr(-1)
+mIndicesPtr(-1),
+mIndices(NULL),
+mId(0)
 {
 }
@@ -83,5 +88,4 @@
 {
 	mVisibility.Reset();
-	mMeasurements.Reset();
 
 	mLastRenderedFrame = -999;
@@ -91,17 +95,4 @@
 BvhNode::~BvhNode() 
 {
-	if (mVizBox) mVizBox->unref();
-}
-
-
-Box *BvhNode::GetOrCreateVizBox() 
-{
-	if (!mVizBox) 
-	{
-		mVizBox = new Box(mBox); 
-		mVizBox->ref();
-	}
-
-	return mVizBox;
 }
 
@@ -110,34 +101,18 @@
 {
 	mIsVisible = false;
-	mIsFullyVisible = false;
-
-	mVisiblePixels = 0;
+	
 	mAssumedVisibleFrames = 0;
-	mRemainingVisibleFrames = 0;
 
 	mLastVisitedFrame = -1;
-	mLastTestedFrame = -1;
-	mTurnedVisibleFrame = 0;
-
+	
 	mTimesInvisible = 0;
-	mTimesTested = 0;
-	mTimesChangedClassification = 0;
-	mAvgChangedClassification = 0;
 	mIsFrustumCulled = false;
 
-	mLastTestedVisibleFrame = 0;
 	mIsNew = true;
 }
 
 
-void BvhNode::SetFullyVisible(const bool visible)
-{
-	mVisibility.mIsFullyVisible = visible;
-}
-
-
 BvhLeaf::~BvhLeaf()
 {
-	if (mTriangleBvh) delete mTriangleBvh;
 }
 
@@ -148,5 +123,15 @@
 
 
-
+Bvh::Bvh():
+mCamera(NULL), 
+mFrameId(-1), 
+mRoot(NULL), 
+mVertices(NULL),
+mIndices(NULL),
+mTestIndices(NULL),
+mCurrentIndicesPtr(0)
+{}
+
+/*
 Bvh::Bvh(const GeometryVector &geometry, 
 		 DistanceSortedRenderAction *const renderer):
@@ -156,9 +141,6 @@
 mVertices(NULL),
 mIndices(NULL),
-mUseTighterBoundsOnlyForLeafTests(false),
-mRenderer(renderer),
 mTestIndices(NULL),
 mCurrentIndicesPtr(0),
-mCollectTighterBoundsWithMaxLevel(true)
 {
 	mGeometry = new NodeGeometry*[geometry.size()];
@@ -203,10 +185,9 @@
 
 	mMaxDepthForTestingChildren = Settings::Global()->get_nvocc_bvh_max_depth_for_testing_children();
-	mUseTighterBoundsOnlyForLeafTests = (Settings::Global()->get_nvocc_use_tighter_bounds() >= 1);
-	
+		
 	mAreaRatioThreshold = Settings::Global()->get_nvocc_area_ratio_threshold();
 	mVolRatioThreshold = Settings::Global()->get_nvocc_vol_ratio_threshold();
 }
-
+*/
 
 Bvh::~Bvh() 
@@ -221,530 +202,4 @@
 
 
-void Bvh::Construct()
-{
-	PerfTimer constructTimer;
-	constructTimer.Entry();
-
-	OUT1("Info: Constructing BVH");
-
-	mRoot = SubdivideLeaf((BvhLeaf *)mRoot, 0);
-
-	constructTimer.Exit();
-
-	OUT1("Info: Bvh done in " << constructTimer.TotalCount() << " seconds.");
-	OUT1("Info: Number Of BVH Nodes = " << mNumNodes);
-
-	// update stats on leaf nodes
-	UpdateNumLeaves(mRoot);
-	
-	mAvgDepth = 1.0f + log((float)GetNumLeaves()) / log(2.0f);
-
-	BvhLeafContainer leaves;
-	leaves.reserve(GetNumLeaves());
-	CollectLeaves(mRoot, leaves);
-
-	// compute tighter boundaries for the leaves
-	PostProcessLeaves(leaves);
-	// compute unique ids
-	ComputeIds();
-	/// pull up some data from the leaves
-	UpdateInteriors(mRoot);
-	// recompute the boundaries once
-	RecomputeBounds();
-	// do stats
-	ComputeBvhStats();
-
-	PrintBvhStats();
-}
-
-
-float Bvh::EvaluateSahCost(BvhLeaf *leaf, const int axis, const float position)
-{
-	// count triangles on the left / right
-	int left = 0;
-	int right = 0;
-	BoundingBox leftBox, rightBox;
-
-	const int candidates = std::max(50, (int)(leaf->CountPrimitives() / 20));
-
-	const float finc = leaf->CountPrimitives() / (float)candidates;
-
-	int i = leaf->mFirst;
-	float fi = leaf->mFirst + 0.5f;
-
-	BoundingBox box;
-
-	for (; i <= leaf->mLast;) 
-	{
-		box = mGeometry[i]->GetBoundingBox();
-
-		if (box.getCenter()[axis] < position) 
-		{
-			++ left;
-			// update the box
-			leftBox.combine(&box);
-		} 
-		else 
-		{
-			++ right;
-			rightBox.combine(&box);
-		}
-		 
-		fi += finc;
-		i = (int)fi;
-	}
-
-	float bW = 1.0f;
-	float leftRatio = left / (float)leaf->CountPrimitives();
-	float rightRatio = right / (float)leaf->CountPrimitives();
-
-	float saLeft = 0.0f;
-	float saRight = 0.0f;
-
-	// not a valid split
-	if (!left || !right)
-		return 1e25f;
-
-	saLeft = leftBox.getSurface();
-	saRight = rightBox.getSurface();
-
-
-	return
-		saLeft  * ((1.0f - bW) + bW * leftRatio) + 
-		saRight * ((1.0f - bW) + bW * rightRatio);
-}
-
-
-float Bvh::SelectPlaneSah(BvhLeaf *leaf, int &axis, float &minCost)
-{
-	minCost = MAXFLOAT;
-	float bestPos = minCost;
-	int bestAxis = 0;
-
-	//  cout<<"Evaluating axis..."<<endl<<flush;
-
-	const int initialPlanes = 3;
-
-	// initiate the costs
-	for (axis = 0; axis < 3; ++ axis) 
-	{
-		const float size = leaf->mBox.getUpper()[axis] - leaf->mBox.getLower()[axis];
-
-		for (int i = 0; i < initialPlanes; ++ i) 
-		{
-			const float pos = leaf->mBox.getLower()[axis] + (i + 1) * size / (initialPlanes + 1);
-			const float cost = EvaluateSahCost(leaf, axis, pos);
-
-			if (cost < minCost) 
-			{
-				minCost = cost;
-				bestPos = pos;
-				bestAxis = axis;
-			}
-		}
-	}
-
-	axis = bestAxis;
-
-	//  cout<<axis<<endl<<flush;
-	const float shrink = 0.5f;
-
-	// now hierarchically refine the initial interval
-	float size = shrink * 
-		(leaf->mBox.getUpper()[axis] - leaf->mBox.getLower()[axis]) / (initialPlanes + 1);
-
-	const int steps = 4;
-	float cost;
-
-	for (int i = 0; i < steps; ++ i) 
-	{
-		const float left = bestPos - size;
-		const float right = bestPos + size;
-
-		cost = EvaluateSahCost(leaf, axis, left);
-
-		if (cost < minCost) 
-		{
-			minCost = cost;
-			bestPos = left;
-		}
-
-		cost = EvaluateSahCost(leaf, axis, right);
-
-		if (cost < minCost) 
-		{
-			minCost = cost;
-			bestPos = right;
-		}
-
-		size = shrink * size;
-	}
-
-	//OUT1("best axis: " << axis << " " << bestPos << " " << minCost);
-
-	return bestPos;
-}
-
-
-void Bvh::ResizeVisibilityBuffers(const int maxSize)
-{
-	std::stack<BvhNode *> nodeStack;
-
-	nodeStack.push(mRoot);
-
-	while (!nodeStack.empty()) 
-	{
-		BvhNode *node = nodeStack.top();
-		nodeStack.pop();
-
-		static_cast<BvhLeaf *>(node)->mMeasurements.Reset();
-
-		if (!node->IsLeaf()) 
-		{
-			BvhInterior *interior = static_cast<BvhInterior *>(node);
-			
-			nodeStack.push(interior->mBack);
-			nodeStack.push(interior->mFront);
-		}
-	}
-}
-
-
-int Bvh::SortTriangles(BvhLeaf *leaf, 
-					   const int axis, 
-					   const float position)
-{
-	int i = leaf->mFirst;
-	int j = leaf->mLast;
-
-    while (1) 
-	{
-		while (mGeometry[i]->GetBoundingBox().getCenter()[axis] < position) 
-			++ i;
-	
-		while (position < mGeometry[j]->GetBoundingBox().getCenter()[axis])
-			-- j;
-
-		if (i < j) 
-		{
-			std::swap(mGeometry[i], mGeometry[j]);
-			
-			++ i;
-			-- j;
-		}
-		else
-		{
-			break;
-		}
-	}
-
-	return j;
-}
-
-
-int Bvh::SortTrianglesSpatialMedian(BvhLeaf *leaf, const int axis)
-{
-	// spatial median
-	float x = leaf->mBox.getCenter()[axis];
-
-	return SortTriangles(leaf, axis, x);
-}
-
-
-int Bvh::SortTrianglesObjectMedian(BvhLeaf *leaf, const int axis, float &pos)
-{
-	// Now distribute the objects into the subnodes
-	// Use QuickMedian sort
-	int l = leaf->mFirst;
-	int r = leaf->mLast;
-	int k = (l + r) / 2;
-
-	while (l < r) 
-	{
-		int i = l;
-		int j = r;
-
-		// get some estimation of the pivot
-		pos = mGeometry[(l + r) / 2]->GetBoundingBox().getCenter()[axis];
-
-		while (1) 
-		{
-			while ((i  <= leaf->mLast) && (mGeometry[i]->GetBoundingBox().getCenter()[axis] < pos))
-				++ i;
-
-			while((j >= leaf->mFirst) && (pos < mGeometry[j]->GetBoundingBox().getCenter()[axis]))
-				-- j;
-
-			if (i <= j) 
-			{
-				std::swap(mGeometry[i], mGeometry[j]);
-				++ i;
-				-- j;
-			}
-			else
-			{
-				break;
-			}
-		}
-
-		// now check the extents
-		if (i >= k)
-			r = j;
-		else
-			l = i;
-	}
-
-	return k;
-}
-
-
-int Bvh::SortTrianglesSurfaceArea(BvhLeaf *leaf, const float sa)
-{
-	int i = leaf->mFirst;
-	int j = leaf->mLast;
-
-	while(1) 
-	{
-		while ((i <= j) && (mGeometry[i]->GetBoundingBox().getSurface() < sa)) 
-			++ i;
-
-		while ((i <= j) && (sa < mGeometry[j]->GetBoundingBox().getSurface()))
-			-- j;
-
-		if (i < j) 
-		{
-			swap(mGeometry[i], mGeometry[j]);
-			++ i;
-			-- j;
-		}
-		else
-			break;
-	}
-
-	return j;
-}
-
-
-bool Bvh::TerminationCriteriaMet(BvhLeaf *leaf) const
-{
-	const bool terminationCriteriaMet = 
-		(leaf->mBox.getSurface() < mMinArea) ||
-		(leaf->CountPrimitives() <= mMaxGeometry) ||
-		(CountTriangles(leaf) <= mMaxTriangles) ||
-		(leaf->mDepth > mMaxDepth);
-
-	return terminationCriteriaMet;
-}
-
-
-BvhNode *Bvh::SubdivideLeaf(BvhLeaf *leaf, const int parentAxis)
-{
-	if (TerminationCriteriaMet(leaf))
-		return leaf;
-	
-	//int axis = leaf->mBox.MajorAxis();
-	int axis = (parentAxis + 1) % 3;
-
-	// position of the split in the partailly sorted array of triangles
-	// corresponding to this leaf
-	int split = -1;
-	const int scale = 20;
-
-	float pos = -1.0f;
-
-	// Spatial median subdivision
-	switch (mSplitType) 
-	{
-	case SPATIAL_MEDIAN:
-		split = SortTrianglesSpatialMedian(leaf, axis);
-
-		if ( 
-			((split - leaf->mFirst) < leaf->CountPrimitives() / scale) ||
-			((leaf->mLast - split) < leaf->CountPrimitives() / scale) ) 
-		{
-			split = SortTrianglesObjectMedian(leaf, axis, pos);
-		}
-
-		pos = leaf->mBox.getCenter()[axis];
-		break;
-	case OBJECT_MEDIAN:
-		// Object median subdivision: approximately the same number
-		// of objects on the left of the the splitting point.
-		split = SortTrianglesObjectMedian(leaf, axis, pos);
-		break;
-	case SAH:
-		{
-			float cost;
-			pos = SelectPlaneSah(leaf, axis, cost);
-
-			if (pos != MAXFLOAT)
-			{
-				split = SortTriangles(leaf, axis, pos);
-			}
-
-			if ((pos == MAXFLOAT) || (split == leaf->mLast))
-			{
-				split = -1;
-				split = SortTrianglesObjectMedian(leaf, axis, pos);
-			}
-		}
-		break;
-	case SAH_OR_SIZE: 
-		{
-			// split by size instead
-			const float saThreshold = 0.2f * leaf->GetBox().getSurface();
-			split = SortTrianglesSurfaceArea(leaf, saThreshold);
-
-			if ((split == leaf->mLast) || (split == leaf->mFirst - 1)) 
-			{
-				// use SAH
-				float cost;
-				pos = SelectPlaneSah(leaf, axis, cost);
-
-				if (pos != MAXFLOAT)
-					split = SortTriangles(leaf, axis, pos);
-				else
-					split = SortTrianglesObjectMedian(leaf, axis, pos);
-			}
-			else
-			{
-				// note: no position is computed!!
-				//OUT1("sorted by size");
-			}
-		}
-		break;
-	default:
-		OUT1("should not come here");
-		break;
-	}
-
-	if (1 && ((split == leaf->mLast)))
-	{
-		// no reduction: we should never come here
-		OUT1("error: no reduction " << leaf->CountPrimitives() << " " << leaf->mFirst << " " << split << " " << leaf->mLast);
-		return leaf;
-	}
-
-	// create two more nodes
-	mNumNodes += 2;
-	BvhInterior *parent = new BvhInterior(leaf->GetParent());
-	BvhLeaf *front = new BvhLeaf(parent);
-	
-	parent->mAxis = axis;
-	parent->mBox = leaf->mBox;
-	parent->mDepth = leaf->mDepth;
-
-	parent->mBack = leaf;
-	parent->mFront = front;
-	parent->mPosition = pos;
-	
-	// now assign the triangles to the subnodes
-	front->mFirst = split + 1;
-	front->mLast = leaf->mLast;
-	front->mDepth = leaf->mDepth + 1;
-	leaf->mLast = split;
-	leaf->mDepth = front->mDepth;
-	leaf->mParent = parent;
-	
-	// reset box
-	leaf->mBox = BoundingBox();
-
-	UpdateLeafBox(static_cast<BvhLeaf *>(parent->mBack));
-	UpdateLeafBox(static_cast<BvhLeaf *>(parent->mFront));
-
-	// some output
-	const int n = 500;
-	if ((GetNumLeaves() % n) == n - 1)
-		OUT1("created " << GetNumLeaves() << " leaves");
-	
-#if VERBOSE_OUTPUT
-	OUT1("box: " << parent->mBox.getUpper() << " " << parent->mBox.getLower());
-	OUT1("depth: " << (int)parent->mDepth);
-	OUT1("axis: " << axis);
-	OUT1("bc="<<((BvhLeaf *)parent->mBack)->Count());
-	OUT1("fc="<<((BvhLeaf *)parent->mFront)->Count());
-	OUT1("back: " << parent->mBack->mBox.getSurface());
-	OUT1("front: " << parent->mFront->mBox.getSurface());
-#endif
-
-	// recursively continue subdivision
-	parent->mBack = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mBack), axis);
-	parent->mFront = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mFront), axis);
-
-	return parent;
-}
-
-
-void Bvh::UpdateLeafBox(BvhLeaf *leaf)
-{
-	for (int i = leaf->mFirst; i <= leaf->mLast; ++ i) 
-	{
-		leaf->mBox.combine(&mGeometry[i]->mBox);
-	} // for
-}
-
-
-void Bvh::UpdateNumLeaves(BvhNode *node) const
-{
-	if (node->IsLeaf())
-	{
-		node->mNumLeaves = 1;
-	}
-	else
-	{
-		BvhNode *f = static_cast<BvhInterior *>(node)->GetFront();
-		BvhNode *b = static_cast<BvhInterior *>(node)->GetBack();
-
-		UpdateNumLeaves(f);
-		UpdateNumLeaves(b);
-
-		node->mNumLeaves = f->mNumLeaves + b->mNumLeaves;
-	}
-}
-
-
-void Bvh::UpdateBoxes(BvhNode *node)
-{
-	if (node->IsLeaf()) 
-	{
-		UpdateLeafBox(static_cast<BvhLeaf *>(node));
-	}
-	else 
-	{
-		BvhInterior *interior = static_cast<BvhInterior *>(node);
-	
-		UpdateBoxes(interior->mBack);
-		UpdateBoxes(interior->mFront);
-
-		node->mBox = interior->mBack->mBox;
-		node->mBox.combine(&interior->mFront->mBox);
-	}
-}
-
-
-void Bvh::UpdateFullVisibility(BvhNode *node) const
-{		
-	// node not visited in this frame => no change
-	if (node->GetLastVisitedFrame() != mFrameId) 
-		return;
-
-	// leaf node: terminate recursion
-	if (node->IsLeaf())
-	{
-		node->SetFullyVisible(node->IsVisible());	
-		return;
-	}
-
-	BvhInterior *interior = static_cast<BvhInterior *>(node);
-	
-	// recursive traversal
-	UpdateFullVisibility(interior->mBack);
-	UpdateFullVisibility(interior->mFront);
-	
-	interior->SetFullyVisible(interior->mBack->IsFullyVisible() && 
-							  interior->mFront->IsFullyVisible());
-}
-
-
 void Bvh::PullUpLastVisited(BvhNode *node, const int frameId) const
 {		
@@ -823,7 +278,5 @@
 typedef pair<BvhNode *, int> tPair;
 
-void Bvh::CollectNodes(BvhNode *root, 
-					   const int depth, 
-					   HierarchyNodeContainer &nodes)
+void Bvh::CollectNodes(BvhNode *root, BvhNodeContainer &nodes, int depth)
 {
 	stack<tPair> tStack;
@@ -838,25 +291,9 @@
 
 		// found depth => take this node
-		if (d == depth)
+		if ((d == depth) || (node->IsLeaf()))
 		{
 			nodes.push_back(node);
 		}
-		else if (node->IsLeaf())
-		{
-			// found leaf
-			BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
-
-			// there is no further subdivision on triangle level
-			if (leaf->mTriangleBvh->GetNumNodes() == 1)
-			{
-				nodes.push_back(leaf);
-			}
-			else // more than a root => search in local bvh
-			{
-				leaf->mTriangleBvh->
-					CollectNodes(leaf->mTriangleBvh->GetRoot(), depth - d, nodes);
-			}
-		}
-		else // interior
+		else
 		{
 			BvhInterior *interior = static_cast<BvhInterior *>(node);
@@ -869,143 +306,5 @@
 
 
-void Bvh::CollectAllNodes(BvhNode *node, HierarchyNodeContainer &nodes)
-{
-	BvhNodeContainer bvhNodes;
-
-	// collect nodes of geometry bvh
-	CollectNodes(mRoot, bvhNodes);
-
-	
-	// first collect nodes of object bvh
-	BvhNodeContainer::const_iterator lit, lit_end = bvhNodes.end();
-
-	for (lit = bvhNodes.begin(); lit != lit_end; ++ lit)
-	{
-		nodes.push_back(*lit);
-	}
-
-	// collect nodes of local bvh: all except roots, 
-	// because they are equivalent to geometry bvh leaves
-	for (lit = bvhNodes.begin(); lit != lit_end; ++ lit)
-	{
-		if ((*lit)->IsLeaf())
-		{
-			BvhLeaf *leaf = static_cast<BvhLeaf *>(*lit);
-
-			TriangleBvhNodeContainer hnodes;
-			leaf->mTriangleBvh->CollectNodes(leaf->mTriangleBvh->GetRoot(), hnodes);
-
-			TriangleBvhNodeContainer::const_iterator hit, hit_end = hnodes.end();
-
-			for (hit = hnodes.begin(); hit != hit_end; ++ hit)
-			{
-				TriangleBvhNode *n = *hit;
-
-				// don't include root of local bvh - it has the same bounds as the leaves
-				if (n != leaf->mTriangleBvh->GetRoot())
-					nodes.push_back(n);
-			}
-		}
-	}
-}
-
-
-void Bvh::CollectVisibleLeaves(BvhNode *node, BvhLeafContainer &leaves)
-{
-	stack<BvhNode *> tStack;
-	tStack.push(node);
-
-	while (!tStack.empty())
-	{
-		BvhNode *node = tStack.top();
-		tStack.pop();
-
-		if (IsWithinViewFrustum(node))
-		{
-			if (!node->IsLeaf())
-			{
-				BvhInterior *interior = static_cast<BvhInterior *>(node);
-
-				tStack.push(interior->mFront);
-				tStack.push(interior->mBack);
-			}
-			else
-			{
-				leaves.push_back(static_cast<BvhLeaf *>(node));
-			}
-		}
-	}
-}
-
-
-BvhLeaf *Bvh::GetRandomLeaf(BvhNode *node)
-{
-	stack<BvhNode *> nodeStack;
-  
-	nodeStack.push(node);
-
-	int mask = rand();
-
-    while (!nodeStack.empty()) 
-	{
-		BvhNode *node = nodeStack.top();
-		nodeStack.pop();
-		
-		if (node->IsLeaf()) 
-		{
-			// random leaf
-			return static_cast<BvhLeaf *>(node);
-		} 
-		else 
-		{
-			BvhInterior *interior = static_cast<BvhInterior *>(node);
-			
-			BvhNode *next;
-			
-			// random decision
-			if (mask & 1)
-				next = interior->mBack;
-			else
-				next = interior->mFront;
-
-			mask = mask >> 1;
-
-			nodeStack.push(next);
-		}
-	}
-  
-	// should never come here
-	return NULL;
-}
-
-
-BvhLeaf *Bvh::GetRandomVisibleLeaf(BvhNode *node)
-{
-	BvhLeafContainer leaves;
-	leaves.reserve(node->GetNumLeaves());
-
-	CollectVisibleLeaves(node, leaves);
-
-	if (leaves.empty())
-		return NULL;
-
-	const int r = (int)(((float)rand() / RAND_MAX) * ((float)leaves.size() - 0.5f));
-
-	return leaves[r];
-}
-
-
-void Bvh::CollectGeometry(BvhNode *node, GeometryVector &geometry)
-{
-	//geometry.reserve(node->CountPrimitives());
-
-	for (int i = node->mFirst; i <= node->mLast; ++ i)
-	{
-		geometry.push_back(mGeometry[i]);
-	}
-}
-
-
-NodeGeometry **Bvh::GetGeometry(BvhNode *node, int &geometrySize)
+SceneEntity **Bvh::GetGeometry(BvhNode *node, int &geometrySize)
 {
 	geometrySize = node->CountPrimitives();
@@ -1014,24 +313,5 @@
 
 
-void Bvh::UpdateInteriors(BvhNode *node)
-{
-	if (!node->IsLeaf())
-	{
-		BvhInterior *interior = static_cast<BvhInterior *> (node);
-		
-		// update the indices of the geometry so we can render interiors as well
-		UpdateInteriors(interior->GetBack());
-		UpdateInteriors(interior->GetFront());
-
-		// update area
-		interior->mFirst = min(interior->GetBack()->mFirst, interior->GetFront()->mFirst);
-		interior->mLast = max(interior->GetBack()->mLast, interior->GetFront()->mLast);
-	
-		interior->mArea = interior->GetBack()->mArea + interior->GetFront()->mArea;
-	}
-}
-
-
-int	Bvh::IsWithinViewFrustumLocal(BvhNode *node)
+int	Bvh::IsWithinViewFrustum(BvhNode *node)
 {
 	bool bIntersect	= false;
@@ -1050,5 +330,5 @@
 		{
 			//-- test the n-vertex
-			if (node->mBox.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f)
+			if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 0], sFrustum.mClipPlanes[i]) > 0.0f)
 			{
 				//-- outside
@@ -1058,5 +338,5 @@
 
 			//-- test the p-vertex
-			if (node->mBox.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f)
+			if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 1], sFrustum.mClipPlanes[i]) <= 0.0f)
 			{
 				//-- completely inside: children don't need to check against this plane no more
@@ -1079,5 +359,5 @@
 		{
 			//-- test the n-vertex
-			if (node->mBox.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f)
+			if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 0], sFrustum.mClipPlanes[i]) > 0.0f)
 			{
 				// outside
@@ -1087,5 +367,5 @@
 
 			//-- test the p-vertex
-			if (node->mBox.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f)
+			if (node->mBox.GetDistance(sClipPlaneAABBVertexIndices[i * 2 + 1], sFrustum.mClipPlanes[i]) <= 0.0f)
 			{
 				// completely inside: children don't need to check against this plane no more
@@ -1103,101 +383,5 @@
 
 
-int	Bvh::IsWithinViewFrustum(const BoundingBox &box, const int planeMask, const int preferredPlane)
-{
-	bool bIntersect	= false;
-
-	////////
-	//-- do the view frustum culling for the planes [mPreferredPlane - 5]
-
-	for (int i = preferredPlane; i < 6; ++ i)
-	{
-		//-- do the test only if necessary
-		if (planeMask & (1 << i))
-		{
-			//-- test the n-vertex
-			if (box.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f)
-				return 0;
-
-			//-- test the p-vertex
-			if (!(box.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f))
-				bIntersect = true;
-		}
-	}
-
-	//////////
-	//-- do the view frustum culling for the planes [0 - m_iPreferredPlane)
-
-	for (int i = 0; i < preferredPlane; ++ i)
-	{
-		// do the test only if necessary
-		if (planeMask & (1 << i))
-		{
-			//-- test the n-vertex
-			if (box.getDistance(mClipPlaneAABBVertexIndices[i][0], mFrustum.mClipPlane[i]) > 0.0f)
-				// outside
-				return 0;
-
-			//-- test the p-vertex
-			if (!(box.getDistance(mClipPlaneAABBVertexIndices[i][1], mFrustum.mClipPlane[i]) <= 0.0f))
-				bIntersect = true;
-		}
-	}
-
-	return bIntersect ? -1 : 1;
-}
-
-
-int	Bvh::IsWithinViewFrustum(BvhNode *node)
-{
-	if (node->mCache.mLastFrustumTestedFrameId == mFrameId)
-	{
-		return node->mCache.mFrustumCulled;
-	}
-
-	node->mCache.mLastFrustumTestedFrameId = mFrameId;
-
-	timeViewFrustumCulling.Entry();
-	
-	if (Settings::Global()->get_nvocc_use_tighter_bounds_for_frustum_culling())
-	{
-		const int intersect = IsWithinViewFrustumLocal(node);
-
-		if ((node->mNumTestNodes == 1) || (intersect != -1))
-		{
-			//OUT1("x");
-			node->mCache.mFrustumCulled = intersect;
-		}
-		else 
-		{
-			// maybe intersecting one of the tighter boxes
-			node->mCache.mFrustumCulled = 0;
-
-			for (int i = 0; i < node->mNumTestNodes; ++ i)
-			{
-				RenderableHierarchyNode *n = mTestNodes[node->mTestNodesIdx + i];
-
-				if (IsWithinViewFrustum(n->GetBox(), 
-										node->mPlaneMask, 
-										node->mPreferredPlane))
-				{
-					node->mCache.mFrustumCulled = -1;
-					break;
-				}
-			}
-		}
-	}
-	else
-	{
-		//OUT1("y");
-		node->mCache.mFrustumCulled = IsWithinViewFrustumLocal(node);
-	}
-
-	timeViewFrustumCulling.Exit();
-
-	return node->mCache.mFrustumCulled;
-}
-
-
-void Bvh::InitFrame(Camera *camera, const int currentFrameId, Viewer *viewer)
+void Bvh::InitFrame(Camera *camera, int currentFrameId)
 {
 	// = 0011 1111 which means that at the beginning, all six planes have to frustum culled
@@ -1207,65 +391,10 @@
 	mFrameId = currentFrameId;
 
-	// to begin with, we must grab the plane equations of the six clipplanes of the viewfrustum
-	Matrix4f matViewing, matProjectionView;
-	Transform3D	transform;
-
-	camera->GetTransform(transform);
-	transform.get(matViewing);
-
-	camera->GetProjectionMatrix(matProjectionView);
-	matProjectionView *= matViewing;
-
-	Vec3f vec;
-	float fInvLength;
-
-
-	//////////
-	//-- extract the plane equations
-
-	for (int i = 0; i < 4; ++ i)
-	{
-		mFrustum.mClipPlane[0][i] = matProjectionView[i][3] - matProjectionView[i][0];	// right plane
-		mFrustum.mClipPlane[1][i] = matProjectionView[i][3] + matProjectionView[i][0];	// left plane
-		mFrustum.mClipPlane[2][i] = matProjectionView[i][3] + matProjectionView[i][1];	// bottom plane
-		mFrustum.mClipPlane[3][i] = matProjectionView[i][3] - matProjectionView[i][1];	// top plane
-		mFrustum.mClipPlane[4][i] = matProjectionView[i][3] - matProjectionView[i][2];	// far plane
-		mFrustum.mClipPlane[5][i] = matProjectionView[i][3] + matProjectionView[i][2];	// near plane
-	}
-
-	////////////
-	//-- normalize the coefficients and find the indices of the n- and p-vertices
-
-	for (int i = 0; i < 6; ++ i)
-	{
-		// the clipping planes look outward the frustum,
-		// so distances > 0 mean that a point is outside
-		fInvLength	= -1.0f / sqrt(	mFrustum.mClipPlane[i][0] * mFrustum.mClipPlane[i][0] +	
-									mFrustum.mClipPlane[i][1] * mFrustum.mClipPlane[i][1] +	
-									mFrustum.mClipPlane[i][2] * mFrustum.mClipPlane[i][2]);
-
-		mFrustum.mClipPlane[i][0] *= fInvLength;
-		mFrustum.mClipPlane[i][1] *= fInvLength;
-		mFrustum.mClipPlane[i][2] *= fInvLength;
-		mFrustum.mClipPlane[i][3] *= fInvLength;
-
-		vec.x = mFrustum.mClipPlane[i][0];
-		vec.y = mFrustum.mClipPlane[i][1];
-		vec.z = mFrustum.mClipPlane[i][2];
-
-		// n-vertex
-		mClipPlaneAABBVertexIndices[i][0] = BoundingBox::getIndexNearestVertex(vec);
-		// p-vertex
-		mClipPlaneAABBVertexIndices[i][1] = BoundingBox::getIndexFurthestVertex(vec);	
-	}
-
-
-	const float aspect = mCamera->GetAspect();
-	const float fov = mCamera->GetFov();
-	
-	mScale = sqrt(aspect) * 2.0f * tan(fov * mypi / 180.0f);
-
-	mNearPlane = mCamera->GetRealViewDirection();
-	mNearPlaneD = - mNearPlane * (mCamera->GetPosition() - Origin3f);
+	mCamera->CalcFrustum(sFrustum);
+	sFrustum.CalcNPVertexIndices(sClipPlaneAABBVertexIndices);
+
+	// calc near plane
+	sNearPlane = Plane3(mCamera->GetDirection(), 
+		                -mCamera->GetDirection() * mCamera->GetPosition());
 }
 
@@ -1273,329 +402,5 @@
 float Bvh::CalcDistance(BvhNode *node) const
 {
-	timeDistance.Entry();
-
-	float distance;
-
-#if USE_TIGHTER_BOUNDS_FOR_ALL
-	float minDist = 1e25f;
-
-	//OUT1("testing " << mNumTestNodes << " nodes");
-	for (int i = 0; i < node->mNumTestNodes; ++ i)
-	{
-		RenderableHierarchyNode *hnode = mTestNodes[node->mTestNodesIdx + i];
-
-		if(hnode->mCache.mLastDistanceTestedFrameId < mFrameId)
-		{
-			hnode->mCache.mDistance = 
-				hnode->GetBox().getMinVisibleDistance(mNearPlane, mNearPlaneD);
-			hnode->mCache.mLastDistanceTestedFrameId = mFrameId;
-		}
-
-		if (hnode->mCache.mDistance < minDist)
-			minDist = hnode->mCache.mDistance;
-	}
-
-	distance = minDist;
-
-#else
-
-	if(node->mCache.mLastDistanceTestedFrameId != mFrameId)
-	{
-		//OUT1("z " << node->mLastDistanceTestedFrameId  << " " << mFrameId);
-		node->mCache.mDistance = node->GetBox().getMinVisibleDistance(mNearPlane, mNearPlaneD);
-		node->mCache.mLastDistanceTestedFrameId = mFrameId;
-	}
-
-	distance = node->mCache.mDistance;
-#endif
-
-	timeDistance.Exit();
-
-	return distance;
-}
-
-
-float Bvh::GetSquareDistance(BvhNode *node) const
-{
-	timeDistance.Entry();
-
-	float distance;
-
-#if USE_TIGHTER_BOUNDS_FOR_ALL
-	const Vector3f nearplane = mCamera->GetRealViewDirection();
-	const float nearplaneD = - nearplane * (mCamera->GetPosition() - Origin3f);
-
-	float minDist = 1e25f;
-	
-	//OUT1("testing " << mNumTestNodes << " nodes");
-	for (int i = 0; i < node->mNumTestNodes; ++ i)
-	{
-		RenderableHierarchyNode *hnode = mTestNodes[node->mTestNodesIdx + i];
-		const float dist = GetMinSquareDistance(hnode->GetBox());
-
-		if (dist < minDist)
-			minDist = dist;
-	}
-
-	distance = minDist;
-#else
-	distance = GetMinSquareDistance(node->GetBox());
-#endif
-
-	timeDistance.Exit();
-
-	return distance;
-}
-
-
-float Bvh::GetMinSquareDistance(const BoundingBox &box) const
-{
-	float minDist = 1e25f;
-
-	const Point3f *pts = (const Point3f *)box.getVertexData();
-	const Point3f pos = mCamera->GetPosition();
-
-	for (int i = 0; i < 8; ++ i)
-	{
-		const float newDist = DistanceSquared(pts[i], pos);
-
-		if (newDist < minDist)
-			minDist = newDist;
-	}
-
-	return minDist;
-}
-
-
-bool Bvh::ExportBinTree(const string &filename)
-{
-	ofstream stream(filename.c_str(), ifstream::binary);
-	
-	if (!stream.is_open()) return false;
-
-	OUT1("exporting bvh");
-
-	std::queue<BvhNode *> tStack;
-	tStack.push(mRoot);
-
-	while(!tStack.empty())
-	{
-		BvhNode *node = tStack.front();
-		tStack.pop();
-		
-		if (node->IsLeaf())
-		{
-			//OUT1("l");
-			ExportBinLeaf(stream, static_cast<BvhLeaf *>(node));
-		}
-		else
-		{
-			//OUT1("i");
-			BvhInterior *interior = static_cast<BvhInterior *>(node);
-
-			ExportBinInterior(stream, interior);
-			
-			tStack.push(interior->mFront);
-			tStack.push(interior->mBack);
-		}
-	}
-
-	OUT1("... finished");
-
-	return true;
-}
-
-
-void Bvh::ExportBinLeaf(ofstream &stream, BvhLeaf *leaf)
-{
-	int type = TYPE_LEAF;
-	int first = leaf->mFirst;
-	int last = leaf->mLast;
-
-	stream.write(reinterpret_cast<char *>(&type), sizeof(int));
-	stream.write(reinterpret_cast<char *>(&first), sizeof(int));
-	stream.write(reinterpret_cast<char *>(&last), sizeof(int));
-}
-
-
-void Bvh::ExportBinInterior(ofstream &stream, BvhInterior *interior)
-{
-	int type = TYPE_INTERIOR;
-	stream.write(reinterpret_cast<char *>(&type), sizeof(int));
-	stream.write(reinterpret_cast<char *>(&interior->mAxis), sizeof(char));
-	stream.write(reinterpret_cast<char *>(&interior->mPosition), sizeof(float));
-}
-
-
-BvhLeaf *Bvh::ImportBinLeaf(ifstream &stream, BvhInterior *parent)
-{
-	BvhLeaf *leaf = new BvhLeaf(parent);
-
-	int first, last;
-
-	stream.read(reinterpret_cast<char *>(&first), sizeof(int));
-	stream.read(reinterpret_cast<char *>(&last), sizeof(int));
-
-	leaf->mFirst = first;
-	leaf->mLast = last;
-
-	return leaf;
-}
-
-
-BvhInterior *Bvh::ImportBinInterior(ifstream &stream, BvhInterior *parent)
-{
-	BvhInterior *interior = new BvhInterior(parent);
-
-	stream.read(reinterpret_cast<char *>(&interior->mAxis), sizeof(char));
-	stream.read(reinterpret_cast<char *>(&interior->mPosition), sizeof(float));
-
-	return interior;
-}
-
-
-BvhNode *Bvh::LoadNextNode(ifstream &stream, BvhInterior *parent)
-{
-	int nodeType;
-	stream.read(reinterpret_cast<char *>(&nodeType), sizeof(int));
-
-	if (nodeType == TYPE_LEAF)
-	{
-		//OUT1("l");
-		return ImportBinLeaf(stream, static_cast<BvhInterior *>(parent));
-	}
-
-	if (nodeType == TYPE_INTERIOR)
-	{
-		//OUT1("i");
-		return ImportBinInterior(stream, static_cast<BvhInterior *>(parent));
-	}
-
-	return NULL;
-}
-
-
-Bvh *Bvh::LoadFromFile(const string &filename, const GeometryVector &geom)
-{
-	// export binary version of mesh
-	queue<BvhNode *> tStack;
-	ifstream stream(filename.c_str(), ifstream::binary);
-
-	if (!stream.is_open()) return NULL;
-
-	OUT1("loading bvh");
-	Bvh *bvh = new Bvh();
-
-	bvh->mGeometrySize = geom.size();
-	bvh->mGeometry = new NodeGeometry*[bvh->mGeometrySize];
-
-	for (size_t i = 0; i < bvh->mGeometrySize; ++ i)
-		bvh->mGeometry[i] = geom[i];
-
-	bvh->mRoot = bvh->LoadNextNode(stream, NULL);
-
-	tStack.push(bvh->mRoot);
-	bvh->mNumNodes = 1;
-
-	while(!tStack.empty())
-	{
-		BvhNode *node = tStack.front();
-		tStack.pop();
-
-		if (!node->IsLeaf())
-		{
-			bvh->mNumNodes += 2;
-
-			BvhInterior *interior = static_cast<BvhInterior *>(node);
-
-            BvhNode *front = bvh->LoadNextNode(stream, interior);
-			BvhNode *back = bvh->LoadNextNode(stream, interior);
-	
-			interior->mFront = front;
-			interior->mBack = back;
-
-			front->mDepth = interior->mDepth + 1;
-			back->mDepth = interior->mDepth + 1;
-
-			tStack.push(front);			
-			tStack.push(back);
-		}
-	}
-
-	OUT1("... finished loading " << bvh->mNumNodes << " nodes, updating boxes");
-
-	//adjust bounding boxes
-	bvh->UpdateBoxes(bvh->mRoot);
-	bvh->UpdateNumLeaves(bvh->mRoot);
-
-	// compute unique ids
-	bvh->ComputeIds();
-	// update the indices of the geometry so we can render interiors as well
-	bvh->UpdateInteriors(bvh->mRoot);
-	// do this once so at least the current node bounding box is tested
-	bvh->RecomputeBounds();
-
-	return bvh;
-}
-
-
-float Bvh::ComputeScreenSpaceProjection(BvhNode *node) const
-{
-#if 0
-	int projection = 0;
-
-	for (int i = 0; i < node->mNumTestNodes; ++ i)
-	{
-		RenderableHierarchyNode *n = mTestNodes[node->mTestNodesIdx + i];
-
-		if(hnode->.mCache.mLastProjectionFrameId < mFrameId)
-		{
-			hnode->mCache.mProjection = 
-				ComputeScreenSpaceProjection(hnode->GetBox());
-			hnode->mCache.mLastProjectionFrameId = mCurrentFrameId;
-		}
-		
-		projection += hnode->mCache.mProjection;
-	}
-
-	return projection;
-
-#else
-
-	if(node->mCache.mLastProjectionFrameId < mFrameId)
-	{
-		node->mCache.mProjection = 
-			ComputeScreenSpaceProjection(node->GetBox());
-		node->mCache.mLastProjectionFrameId = mFrameId;
-	}
-
-	return node->mCache.mProjection;
-#endif
-}
-
-
-float Bvh::ComputeScreenSpaceProjection(const BoundingBox &box) const
-{
-#if 0
-	const float dist = CalcDistance(box);
-#else
-	//const float dist = sqrt(GetMinSquareDistance(box));
-	const float dist = Distance(mCamera->GetPosition(), box.getCenter());
-#endif
-
-	const float scale = dist ? dist * mScale : 1e-6;
-	const float f = 1.0f / scale;
-	const float coverage = f * f * box.getSurface() / 6.0f;
-
-#if 0
-	OUT1("scale: " << scale);
-	OUT1("box: " << box.getSurface());
-	OUT1("aspect: " << aspect);
-	OUT1("fov: " << fov);
-	OUT1("tan: " << tan(fov * mypi / 180.0f));
-	//OUT1("w: " << w << " h: " << h);
-	OUT1("cov: " << coverage << " pix: " << coverage * w * h << " f: " << f);
-#endif
-	return coverage;
+	return node->GetBox().GetMinVisibleDistance(sNearPlane);
 }
 
@@ -1603,107 +408,17 @@
 void Bvh::RenderBoundingBox(BvhNode *node)
 {
-#if 1
 	static BvhNodeContainer dummy(1);
 	dummy[0] = node;
 	RenderBoundingBoxes(dummy);
-#else
-	RenderBoxIndividual(node);
-#endif
-}
-
-
-void Bvh::RenderBoundingBoxImmediate(const BoundingBox &box, const bool restartStrip)
-{
-	const Point3f *pU = box.getUpperPtr();
-	const Point3f *pL = box.getLowerPtr();
-
-	///////////
-	//-- render AABB as triangle strips
-
-	glVertex3f(pL->x, pL->y, pU->z);
-	glVertex3f(pU->x, pL->y, pU->z);
-	glVertex3f(pL->x, pU->y, pU->z);
-	glVertex3f(pU->x, pU->y, pU->z);
-	glVertex3f(pL->x, pU->y, pL->z); 
-	glVertex3f(pU->x, pU->y, pL->z);
-	glVertex3f(pL->x, pL->y, pL->z); 
-	glVertex3f(pU->x, pL->y, pL->z);
-
-	glPrimitiveRestartNV();
-
-	//-- render second half of AABB
-	glVertex3f(pL->x, pU->y, pU->z); 
-	glVertex3f(pL->x, pU->y, pL->z);
-	glVertex3f(pL->x, pL->y, pU->z);
-	glVertex3f(pL->x, pL->y, pL->z);
-	glVertex3f(pU->x, pL->y, pU->z); 
-	glVertex3f(pU->x, pL->y, pL->z);
-	glVertex3f(pU->x, pU->y, pU->z); 
-	glVertex3f(pU->x, pU->y, pL->z);
-
-	
-	// restart for all but last node
-	if (restartStrip)
-	{
-		glPrimitiveRestartNV();
-	}
-}
-
-
-int Bvh::RenderBoundingBoxesImmediate(const BvhNodeContainer &nodes)
-{
-	timeSetup.Entry();
-	int renderedBoxes = 0;
-	
-	glBegin(GL_TRIANGLE_STRIP);
-
-	BvhNodeContainer::const_iterator bit, bit_end = nodes.end();
-
-	for (bit = nodes.begin(); bit != bit_end; ++ bit)
-	{
-		BvhNode *node = *bit;
-
-		renderedBoxes += node->mNumTestNodes;
-#if 0
-		const bool restartStrip = false;
-		RenderBoundingBoxImmediate(node->GetBox(), restartStrip);
-#else
-		//OUT1("nodes: " << node->mTestNodes.size() << " l: " << node->IsLeaf());
-		for (int i = 0; i < node->mNumTestNodes; ++ i)
-		{
-			RenderableHierarchyNode *testNode = mTestNodes[node->mTestNodesIdx + i];
-			const BoundingBox &box = testNode->GetBox();
-
-			// restart for all but last node
-			const bool restartStrip = (bit != bit_end - 1) || (i != node->mNumTestNodes - 1);
-
-			RenderBoundingBoxImmediate(box, restartStrip);
-		}
-#endif
-	}
-	glEnd();
-	timeSetup.Exit();
+}
+
+
+
+int Bvh::RenderBoundingBoxes(const BvhNodeContainer &nodes)
+{
+	int renderedBoxes = PrepareBoundingBoxesWithDrawArrays(nodes);
+	RenderBoundingBoxesWithDrawArrays(renderedBoxes);
 
 	return renderedBoxes;
-}
-
-
-int Bvh::RenderBoundingBoxes(const BvhNodeContainer &nodes)
-{
-	// always render in immediate mode if there is only one box to render
-	if (((nodes.size() == 1) && (nodes[0]->mNumTestNodes == 1)) || 
-		!Settings::Global()->get_nvocc_use_index_arrays())
-	{	
-		// render bounding boxes individually
-		return RenderBoundingBoxesImmediate(nodes);
-	}
-	else 
-	{
-		const int renderedBoxes = 
-			PrepareBoundingBoxesWithDrawArrays(nodes);
-		RenderBoundingBoxesWithDrawArrays(renderedBoxes);
-
-		return renderedBoxes;
-	}
 }
 
@@ -1726,6 +441,4 @@
 
 	///////////////
-
-	timeSetup.Entry();
 
 	int numNodes = 0;
@@ -1750,17 +463,12 @@
 	}
 
-	timeSetup.Exit();
-
 	return numNodes;
 }
 
 
-void Bvh::RenderBoundingBoxesWithDrawArrays(const int numNodes)
+void Bvh::RenderBoundingBoxesWithDrawArrays(int numNodes)
 {
 	//////
 	//-- Rendering the vbo
-
-	timeIssueDrawElements.Entry();
-
 	if (useVbos)
 		// set the vertex pointer to the vertex buffer
@@ -1774,6 +482,4 @@
 	// don't render first degenerate index
 	glDrawElements(GL_TRIANGLE_STRIP, numElements, GL_UNSIGNED_INT, mIndices + 1); 
-	
-	timeIssueDrawElements.Exit();
 }
 
@@ -1787,5 +493,5 @@
 	CollectNodes(mRoot, nodes);
 
-	OUT1("creating new indices");
+	cout << "creating new indices" << endl;
 
 	int numMaxIndices = 0;
@@ -1804,5 +510,5 @@
 
 
-	OUT1("creating global indices buffer");
+	cout << "creating global indices buffer" << endl;
 
 	if (mIndices) delete [] mIndices;
@@ -1831,5 +537,5 @@
 		for (int i = 0; i < node->mNumTestNodes; ++ i, numIndices += sNumIndicesPerBox)
 		{
-			RenderableHierarchyNode *testNode = mTestNodes[node->mTestNodesIdx + i];
+			BvhNode *testNode = mTestNodes[node->mTestNodesIdx + i];
 
 			// add indices to root node
@@ -1851,4 +557,5 @@
 
 
+/*
 void Bvh::ComputeIds()
 {
@@ -1856,5 +563,5 @@
 	// warning: root nodes local bvh are not in there, as they 
 	// are equivalent geometry bvh leaves
-	HierarchyNodeContainer nodes;
+	BvhNodeContainer nodes;
 	CollectAllNodes(mRoot, nodes);
 
@@ -1868,33 +575,28 @@
 	}
 }
-
+*/
 
 void Bvh::PrepareVertices()
 {
-	// collect all nodes, also the nodes from local bvh
-	// warning: root nodes local bvh are not in there, as they 
-	// are equivalent geometry bvh leaves
-	HierarchyNodeContainer nodes;
+	// collect all nodes
+	BvhNodeContainer nodes;
 
 	nodes.reserve(GetNumNodes());
-	CollectAllNodes(mRoot, nodes);
+	CollectNodes(mRoot, nodes);
 
 	const unsigned int bufferSize = 8 * (int)nodes.size();
-	mVertices = new Point3f[bufferSize];
+	mVertices = new Vector3[bufferSize];
 	
 	int i = 0;
 	
 	// store bounding box vertices
-	HierarchyNodeContainer::const_iterator lit, lit_end = nodes.end();
+	BvhNodeContainer::const_iterator lit, lit_end = nodes.end();
 
 	for (lit = nodes.begin(); lit != lit_end; ++ lit, i += 8)
 	{
-		RenderableHierarchyNode *node = *lit;
-		const Point3f *vertices = (const Point3f *)node->GetBox().getVertexData();
+		BvhNode *node = *lit;
 
 		for (int j = 0; j < 8; ++ j)
-		{	
-			((Point3f *)mVertices)[node->GetId() * 8 + j] = vertices[j];
-		}
+			((Vector3 *)mVertices)[node->GetId() * 8 + j] = node->GetBox().GetVertex(j);
 	}
 
@@ -1906,5 +608,5 @@
 	
 		glBufferDataARB(GL_ARRAY_BUFFER_ARB, 
-			            bufferSize * sizeof(Point3f), 
+			            bufferSize * sizeof(Vector3), 
 			            mVertices, 
 						GL_STATIC_DRAW_ARB);
@@ -1913,7 +615,7 @@
 
 		// data handled by graphics driver from now on
-		DELAPTR(mVertices);
-
-		OUT1("***** created vbos *********");
+		DEL_PTR(mVertices);
+
+		cout << "***** created vbos *********" << endl;
 	}
 	else
@@ -1922,10 +624,10 @@
         glVertexPointer(3, GL_FLOAT, 0, mVertices);
 
-		OUT1("created vertices");
-	}
-}
-
-
-void Bvh::SetMaxDepthForTestingChildren(const int maxDepth) 
+		cout << "******* created vertex arrays ********" << endl;
+	}
+}
+
+
+void Bvh::SetMaxDepthForTestingChildren(int maxDepth) 
 {
 	if (maxDepth != mMaxDepthForTestingChildren)
@@ -1937,39 +639,9 @@
 
 
-void Bvh::SetAreaRatioThresholdForTestingChildren(const float ratio) 
+void Bvh::SetAreaRatioThresholdForTestingChildren(float ratio) 
 {
 	if (ratio != mAreaRatioThreshold)
 	{
 		mAreaRatioThreshold = ratio;
-		RecomputeBounds();
-	}
-}
-
-
-void Bvh::SetVolRatioThresholdForTestingChildren(const float ratio) 
-{
-	if (ratio != mVolRatioThreshold)
-	{
-		mVolRatioThreshold = ratio;
-		RecomputeBounds();
-	}
-}
-
-
-void Bvh::SetUseTighterBoundsForTests(const bool tighterBoundsForTests)
-{
-	if (mUseTighterBoundsOnlyForLeafTests != tighterBoundsForTests)
-	{
-		mUseTighterBoundsOnlyForLeafTests = tighterBoundsForTests;
-		RecomputeBounds();
-	}
-}
-
-
-void Bvh::SetCollectTighterBoundsWithMaxLevel(bool t)
-{
-	if (mCollectTighterBoundsWithMaxLevel != t)
-	{
-		mCollectTighterBoundsWithMaxLevel = t;
 		RecomputeBounds();
 	}
@@ -1986,10 +658,5 @@
 	CollectNodes(mRoot, nodes);
 
-	OUT1("recomputing bounds, children will be tested in depth " << mMaxDepthForTestingChildren);
-
-	if (mCollectTighterBoundsWithMaxLevel)
-		OUT1("creating tighter bounds using max level");
-	else
-		OUT1("creating tighter bounds using best set");
+	cout << "recomputing bounds, children will be tested in depth " << mMaxDepthForTestingChildren << endl;
 
 	int success = 0;
@@ -2000,45 +667,15 @@
 		BvhNode *node = *lit;
 
-		if (mCollectTighterBoundsWithMaxLevel)
-		{
-			//OUT1("creating tighter bounds using max level");
-
-			// recreate list of nodes that will be tested as a proxy ...
-			if (CreateNodeRenderList(node))
-				++ success;
-		}
-		else
-		{
-			//OUT1("creating tighter bounds using best set");
-
-			HierarchyNodeContainer hnodes;
-			CollectBestNodes(node, hnodes);	
-
-			// the new test nodes are added at the end of the vector
-			node->mTestNodesIdx = mTestNodes.size();
-
-			HierarchyNodeContainer::const_iterator cit;
-
-			// use the found nodes as nodes during the occlusion tests
-			for (cit = hnodes.begin(); cit != hnodes.end(); ++ cit)
-			{
-				RenderableHierarchyNode *child = *cit;
-				mTestNodes.push_back(child);
-			}
-
-			node->mNumTestNodes = (int)hnodes.size();
-		}
-		//OUT1("testnodes: " << node->mNumTestNodes);
-	}
-
-	const float p = 100.0f * (float)success / nodes.size();
-
-	OUT1("created tighter bounds for " << p << " percent of the nodes");
+		// recreate list of nodes that will be tested as a proxy ...
+		if (CreateNodeRenderList(node))
+			++ success;
+	}
+
+	float p = 100.0f * (float)success / nodes.size();
+	cout << "created tighter bounds for " << p << " percent of the nodes" << endl;
 
 	// recreate indices used for indirect mode rendering
 	if (mIndices)
-	{
 		CreateIndices();
-	}
 }
 
@@ -2046,17 +683,10 @@
 bool Bvh::CreateNodeRenderList(BvhNode *node)
 {
-	HierarchyNodeContainer children;
-
-	if (mUseTighterBoundsOnlyForLeafTests && !node->IsLeaf())
-	{
-		children.push_back(node);
-	}
-	else
-	{
-		// collect nodes that will be tested instead of the leaf node
-		// in order to get a tighter bounding box test
-		CollectNodes(node, mMaxDepthForTestingChildren, children);
-	}
-
+	BvhNodeContainer children;
+
+	// collect nodes that will be tested instead of the leaf node
+	// in order to get a tighter bounding box test
+	CollectNodes(node, children, mMaxDepthForTestingChildren);
+	
 
 	// using the tighter bounds is not feasable in case
@@ -2068,24 +698,15 @@
 	float area = 0;
 
-	HierarchyNodeContainer::const_iterator cit;
+	BvhNodeContainer::const_iterator cit;
 
 	for (cit = children.begin(); cit != children.end(); ++ cit)
-	{
-		RenderableHierarchyNode *c = *cit;
-
-		area += c->GetBox().getSurface();
-		vol += c->GetBox().getVolume();
-	}
-
-	const float volRatio = vol / node->GetBox().getVolume();
-	const float areaRatio = area / node->GetBox().getSurface();
+		area += (*cit)->GetBox().SurfaceArea();
+
+	const float areaRatio = area / node->GetBox().SurfaceArea();
 	
 	bool success;
 
-	if ((areaRatio < mAreaRatioThreshold) &&
-		(volRatio < mVolRatioThreshold))
-	{
+	if (areaRatio < mAreaRatioThreshold)
 		success = true;
-	}
 	else
 	{
@@ -2098,10 +719,10 @@
 
 	// the new test nodes are added at the end of the vector
-	node->mTestNodesIdx = mTestNodes.size();
+	node->mTestNodesIdx = (int)mTestNodes.size();
 
 	// use the found nodes as nodes during the occlusion tests
 	for (cit = children.begin(); cit != children.end(); ++ cit)
 	{
-		RenderableHierarchyNode *child = *cit;
+		BvhNode *child = *cit;
 		mTestNodes.push_back(child);
 	}
@@ -2129,138 +750,4 @@
 
 
-int Bvh::PostProcessLeaves(BvhLeafContainer &leaves)
-{
-	OUT1("creating tighter bounds for leaves");
-
-	BvhLeafContainer::const_iterator lit, lit_end = leaves.end();
-
-	int i = 0;
-	int tighter = 0;
-
-	for (lit = leaves.begin(); lit != lit_end; ++ lit, ++ i)
-	{
-		BvhLeaf *leaf = *lit;
-
-		int triangleCount;
-		// collect the triangles from the stored geometry
-		Point3f *triangles = CollectTriangles(leaf, triangleCount);
-
-		if (CreateTighterBoundsForLeaf(leaf, triangles, triangleCount))
-			++ tighter;
-
-		leaf->mArea = ComputeGeometryArea(leaf, triangles, triangleCount);
-
-		delete [] triangles;
-
-		if (i % 1000 == 999)
-			OUT1(i << " leaves processed ");
-	}
-
-	const float p = 100.0f * tighter / leaves.size();
-	OUT1("created tighter bounds for " << p << " percent of the leaves");
-
-	return tighter;
-}
-
-
-bool Bvh::CreateTighterBoundsForLeaf(BvhLeaf *leaf, Point3f *triangles, const int triangleCount)
-{
-	// create a local bvh over the triangles
-	if (leaf->mTriangleBvh) delete leaf->mTriangleBvh;
-
-	leaf->mTriangleBvh = new TriangleBvh((Triangle *)triangles, triangleCount);
-
-	const int maxDepth = Settings::Global()->get_nvocc_local_bvh_max_depth();
-	const int maxTriangles = Settings::Global()->get_nvocc_local_bvh_max_triangles();
-	const int minArea = Settings::Global()->get_nvocc_local_bvh_min_area();
-	const int splitType = Settings::Global()->get_nvocc_local_bvh_split_type();
-
-	leaf->mTriangleBvh->SetMaxDepth(maxDepth);
-	leaf->mTriangleBvh->SetMaxTriangles(maxTriangles);
-	leaf->mTriangleBvh->SetMinAreaRatio(minArea);
-	leaf->mTriangleBvh->SetSplitType(splitType);
-	
-	leaf->mTriangleBvh->SetVerboseOutput(false);
-
-	// construct
-	leaf->mTriangleBvh->Construct();
-
-	return true;
-}
-
-
-float Bvh::ComputeGeometryArea(BvhLeaf *leaf, Point3f *triangles, const int triangleCount) const
-{
-	float area = 0;
-
-	for (int i = 0; i < triangleCount; ++ i)
-	{
-		area += ((Triangle *)triangles)[i].GetArea();
-	}
-
-	return area;
-}
-
-
-Point3f *Bvh::CollectTriangles(BvhLeaf *leaf, int &triangleCount)
-{
-	// count triangles in the leaf
-	triangleCount = 0;
-
-	for (int geomIdx = leaf->mFirst; geomIdx <= leaf->mLast; ++ geomIdx)
-	{
-		Shape3D *sh = static_cast<Shape3D *>(mGeometry[geomIdx]->GetNode());
-		IndexedTriangleStripArray *strips = static_cast<IndexedTriangleStripArray *>(sh->getGeometry());
-
-		triangleCount += strips->getNumTriangles();
-	}
-
-	Triangle *triangles = new Triangle[triangleCount];
-	//OUT1("The leaf contains " << triangleCount << " triangles in " << (int)geometry.size() << " nodes");
-
-	int currentIdx = 0;
-	
-	for (int geomIdx = leaf->mFirst; geomIdx <= leaf->mLast; ++ geomIdx)
-	{
-		NodeGeometry *geom = mGeometry[geomIdx];
-
-		Shape3D *sh = static_cast<Shape3D *>(geom->GetNode());
-		
-		IndexedTriangleStripArray *strips = 
-			static_cast<IndexedTriangleStripArray *>(sh->getGeometry());
-
-		// get indices of containted triangles (strips are converted before)
-		int *indices;
-	
-		int tCount = strips->getNumTriangles();
-		int indexCount = tCount * 3;
-		
-		// compute triangles from strips
-		Point3f *coordinates = (Point3f *)strips->getCoordRef3f();
-		strips->getTriangleCoordinateIndices(0, &indices, indexCount);
-
-		for (int i = 0; i < tCount; ++ i)
-		{
-			triangles[i + currentIdx].mVertices[0] = coordinates[indices[i * 3 + 0]]; 
-			triangles[i + currentIdx].mVertices[1] = coordinates[indices[i * 3 + 1]]; 
-			triangles[i + currentIdx].mVertices[2] = coordinates[indices[i * 3 + 2]]; 
-
-			if (geom->mMatId != NV_RenderPredictorRenderAction::NO_MAT)
-			{
-				const Matrix4f &m = mRenderer->app_mats[geom->mMatId];
-				Transform3D tf(m);
-				tf.transform(triangles[i + currentIdx].mVertices[0]);
-				tf.transform(triangles[i + currentIdx].mVertices[1]);
-				tf.transform(triangles[i + currentIdx].mVertices[2]);
-			}
-		}
-
-		currentIdx += tCount;
-	}
-
-	return (Point3f *)triangles;
-}
-
-
 int Bvh::CountTriangles(BvhLeaf *leaf) const
 {
@@ -2268,8 +755,6 @@
 	
 	for (int i = leaf->mFirst; i <= leaf->mLast; ++ i)
-	{
-		triangleCount += mGeometry[i]->mNumTriangles;
-	}
-
+		triangleCount += mGeometry[i]->GetGeometry()->CountTriangles();
+	
 	return triangleCount;
 }
@@ -2290,22 +775,11 @@
 			BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
 
-			mBvhStats.mLeafSA += leaf->mBox.getSurface();
-			mBvhStats.mLeafVol += leaf->mBox.getVolume();
-
-			TriangleBvh::TriangleBvhStats tStats;
-			leaf->mTriangleBvh->GetBvhStats(tStats);
-
-			mBvhStats.mBoundsLeafSA += tStats.mLeafSA;
-			mBvhStats.mBoundsInteriorSA += tStats.mInteriorSA;
-
-			mBvhStats.mBoundsLeafVol += tStats.mLeafVol;
-			mBvhStats.mBoundsInteriorVol += tStats.mInteriorVol;
-
-			mBvhStats.mBoundsLeavesCount += leaf->mTriangleBvh->GetNumLeaves();
+			mBvhStats.mLeafSA += leaf->mBox.SurfaceArea();
+			mBvhStats.mLeafVol += leaf->mBox.GetVolume();
 		} 
 		else 
 		{
-			mBvhStats.mInteriorSA += node->mBox.getSurface();
-			mBvhStats.mInteriorVol += node->mBox.getVolume();
+			mBvhStats.mInteriorSA += node->mBox.SurfaceArea();
+			mBvhStats.mInteriorVol += node->mBox.GetVolume();
 
 			BvhInterior *interior = static_cast<BvhInterior *>(node);
@@ -2323,100 +797,18 @@
 void Bvh::PrintBvhStats() const
 {
-	//OUT1("triangle bvh surface " << mBvhStats.mBoundsLeafSA);
-	//OUT1("triangle bvh volume " << mBvhStats.mBoundsLeafVol);
-
-	OUT1("bvh stats:");
-	OUT1("interiorNodesSA = " << mBvhStats.mInteriorSA / mRoot->mBox.getSurface());
-	OUT1("leafNodesSA = " << mBvhStats.mLeafSA / mRoot->mBox.getSurface());
-	OUT1("interiorNodesVolume = " << mBvhStats.mInteriorVol / mRoot->mBox.getVolume());
-	OUT1("leafNodesVolume = " << mBvhStats.mLeafVol / mRoot->mBox.getVolume() << "\n");
-
-	OUT1("boundsInteriorNodesSA = " << mBvhStats.mBoundsInteriorSA / mBvhStats.mLeafSA);
-	OUT1("boundsLeafNodesSA = " << mBvhStats.mBoundsLeafSA / mBvhStats.mLeafSA);
-	OUT1("boundsInteriorNodesVolume = " << mBvhStats.mBoundsInteriorVol / mBvhStats.mLeafVol);
-	OUT1("boundsLeafNodesVolume = " << mBvhStats.mBoundsLeafVol / mBvhStats.mLeafVol << "\n");
-
-	OUT1("boundsLeaves: " <<  (float)mBvhStats.mBoundsLeavesCount / (float)GetNumLeaves() << "\n");
-	OUT1("geometry per leaf: " <<  mBvhStats.mGeometryRatio);
-	OUT1("triangles per leaf: " <<  mBvhStats.mTriangleRatio);
-	OUT1("");
-}
-
-
-static void RenderBoxForViz(const BoundingBox &box)
-{
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z);
-	glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z);
-	glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z);
-	glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z);
-	glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z);
-	glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getLowerPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z);
-	glVertex3d(box.getLowerPtr()->x, box.getLowerPtr()->y, box.getUpperPtr()->z);
-	glEnd();
-
-	glBegin(GL_LINE_LOOP);
-	glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getLowerPtr()->z);
-	glVertex3d(box.getUpperPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z);
-	glVertex3d(box.getLowerPtr()->x, box.getUpperPtr()->y, box.getUpperPtr()->z);
-
-	glEnd();
-}
-
-
-void Bvh::RenderBoundingBoxesForViz(const int mode)
-{
-	BvhLeafContainer leaves;
-	leaves.reserve(mRoot->GetNumLeaves());
-
-	CollectLeaves(mRoot, leaves);
-
-	BvhLeafContainer::const_iterator it, it_end = leaves.end();
-
-	for (it = leaves.begin(); it != it_end; ++ it)
-	{
-		BvhLeaf *leaf = *it;
-
-		if ((mode == 0) || (mode == 2))
-		{
-			glColor3f(1.0f, 1.0f, 1.0f);
-            RenderBoxForViz(leaf->GetBox());
-		}
-		
-		if ((mode == 1) || (mode == 2)) 
-		{
-			glColor3f(1.0f, 0, 0);
-			for (int i = 0; i < leaf->mNumTestNodes; ++ i)
-			{
-				RenderBoxForViz(mTestNodes[leaf->mTestNodesIdx + i]->GetBox());
-			}
-		}
-	}
+	cout << "bvh stats:" << endl;
+	cout << "interiorNodesSA = " << mBvhStats.mInteriorSA / mRoot->mBox.SurfaceArea() << endl;
+	cout << "leafNodesSA = " << mBvhStats.mLeafSA / mRoot->mBox.SurfaceArea() << endl;
+	cout << "interiorNodesVolume = " << mBvhStats.mInteriorVol / mRoot->mBox.GetVolume() << endl;
+	cout << "leafNodesVolume = " << mBvhStats.mLeafVol / mRoot->mBox.GetVolume() << endl;
+
+	cout << "boundsInteriorNodesSA = " << mBvhStats.mBoundsInteriorSA / mBvhStats.mLeafSA << endl;
+	cout << "boundsLeafNodesSA = " << mBvhStats.mBoundsLeafSA / mBvhStats.mLeafSA << endl;
+	cout << "boundsInteriorNodesVolume = " << mBvhStats.mBoundsInteriorVol / mBvhStats.mLeafVol << endl;
+	cout << "boundsLeafNodesVolume = " << mBvhStats.mBoundsLeafVol / mBvhStats.mLeafVol << "\n" << endl;
+
+	cout << "boundsLeaves: " <<  (float)mBvhStats.mBoundsLeavesCount / (float)GetNumLeaves() << "\n" << endl;
+	cout << "geometry per leaf: " <<  mBvhStats.mGeometryRatio << endl;
+	cout << "triangles per leaf: " <<  mBvhStats.mTriangleRatio << endl;
 }
 
@@ -2428,5 +820,5 @@
 	for (int i = node->mFirst; i <= node->mLast; ++ i)
 	{
-		numTriangles += mGeometry[i]->mNumTriangles;
+		numTriangles += mGeometry[i]->GetGeometry()->CountTriangles();
 	}
 
@@ -2440,149 +832,3 @@
 }
 
-
-float Bvh::GetAvgDepth() const
-{
-	return mAvgDepth;
-}
-
-
-static float GetNodePriority(RenderableHierarchyNode *node)
-{
-	if (node->IsLeaf())
-		return 0.0f;
-
-	float result;
-
-	if (node->GetType() == BVH_NODE)
-	{
-		BvhInterior *interior = static_cast<BvhInterior *>(node);
-		
-		// evaluate the priority of this node
-		const float correctionFactor = 0.0f;
-		//  1.0f*interior->box.FaceArea(node->axis);
-
-		result = 
-			interior->GetBox().getSurface() - 
-			(interior->GetBack()->GetBox().getSurface() + interior->GetFront()->GetBox().getSurface()) + 
-			correctionFactor;
-	}
-	else
-	{
-		TriangleBvhInterior *interior = static_cast<TriangleBvhInterior *>(node);
-		
-		// evaluate the priority of this node
-		const float correctionFactor = 0.0f;
-		//  1.0f*interior->box.FaceArea(node->axis);
-
-		result = 
-			interior->GetBox().getSurface() - 
-			(interior->GetBack()->GetBox().getSurface() + interior->GetFront()->GetBox().getSurface()) + 
-			correctionFactor;
-	}
-
-	return result;
-}
-
-
-struct NodeEntry
-{
-	NodeEntry(RenderableHierarchyNode *node, float p): mNode(node), mPriority(p)
-	{}
-
-	RenderableHierarchyNode *mNode;
-	float mPriority;
-};
-
-
-bool operator<(const NodeEntry &a, const NodeEntry &b)
-{
-	return a.mPriority < b.mPriority;
-}
-
-
-void Bvh::CollectBestNodes(RenderableHierarchyNode *node, HierarchyNodeContainer &nodes)
-{
-	int maxNodes = 32;
-	priority_queue<NodeEntry> nodeStack;
-
-	nodeStack.push(NodeEntry(node, GetNodePriority(node)));
-	nodes.clear();
-
-	float SA = node->GetBox().getSurface();
-	float saThreshold = 1.1f * SA;
-	int numNodes = 1;
-	OUT1(numNodes << " " << SA);
-
-	while (!nodeStack.empty() &&
-		int(nodes.size() + nodeStack.size()) < maxNodes)
-	{
-		NodeEntry entry = nodeStack.top();
-		nodeStack.pop();
-
-		RenderableHierarchyNode *current = entry.mNode;
-
-		if (current->IsLeaf())
-		{
-			// check if there further subdivision on triangle level
-			if ((current->GetType() == BVH_NODE) && (((BvhLeaf *)current)->mTriangleBvh->GetNumNodes() > 1))
-			{
-				// push back the root of the local bvh
-				nodeStack.push(NodeEntry(((BvhLeaf *)current)->mTriangleBvh->GetRoot(), entry.mPriority));
-			}
-			else // terminate traversal
-			{
-				nodes.push_back(current);
-			}
-		}
-		else // interior node
-		{
-			// surface area of child nodes
-			SA -= entry.mPriority;
-		
-			// finish the search if we have too much fillrate increase
-			if (SA > saThreshold)
-			{
-				OUT1("break at " << SA << " > " << saThreshold);
-				nodes.push_back(current);
-			}
-			else
-			{
-				++ numNodes;
-
-				OUT1(numNodes << " " << SA << " " << entry.mPriority);
-
-				if (current->GetType() == BVH_NODE)
-				{
-					BvhInterior *interior = static_cast<BvhInterior *>(current);
-
-					nodeStack.push(NodeEntry(interior->GetBack(), 
-						GetNodePriority(interior->GetBack())));
-					nodeStack.push(NodeEntry(interior->GetFront(),
-						GetNodePriority(interior->GetFront())));
-				}
-				else
-				{
-					TriangleBvhInterior *interior = static_cast<TriangleBvhInterior *>(current);
-
-					nodeStack.push(NodeEntry(interior->GetBack(), 
-						GetNodePriority(interior->GetBack())));
-					nodeStack.push(NodeEntry(interior->GetFront(),
-						GetNodePriority(interior->GetFront())));
-				}
-			}
-		}
-	}
-
-	while (!nodeStack.empty()) 
-	{
-		NodeEntry entry = nodeStack.top();
-	
-		nodeStack.pop();
-		RenderableHierarchyNode *current = entry.mNode;
-		nodes.push_back(current);
-	}
-} 
-
-#endif
-
-}
+}
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.h	(revision 2747)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.h	(revision 2755)
@@ -4,10 +4,15 @@
 // note use forward declaration instead
 #include <string>
+#include <iostream>
+#include <fstream>
+#include "common.h"
 
 
+namespace CHCDemo
+{
+
 class igzstream;
-class Shape3D;
-class BranchGroup;
-class Appearance;
+class SceneEntity;
+class Material;
 class Geometry;
 
@@ -17,14 +22,18 @@
 public:
 
-	BranchGroup *Load(const std::string &filename);
+	bool Load(const std::string &filename, SceneEntityContainer &geometry);
 
 protected:
+	
+	SceneEntity *LoadShape(std::ifstream &str);
+	Material *LoadMaterial(std::ifstream &str);
+	Geometry *LoadGeometry(std::ifstream &str);
 
-	Shape3D *LoadShape(igzstream &str);
-
-	Appearance *LoadAppearance(igzstream &str);
-
+	/*SceneEntity *LoadShape(igzstream &str);
+	Material *LoadMaterial(igzstream &str);
 	Geometry *LoadGeometry(igzstream &str);
+	*/
 };
 
+}
 #endif
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.cpp	(revision 2751)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.cpp	(revision 2755)
@@ -8,7 +8,13 @@
 Plane3::Plane3(const Vector3 &a, const Vector3 &b, const Vector3 &c) 
 {
-    Vector3 v1=a-b, v2=c-b;
-    mNormal = Normalize(CrossProd(v2,v1));
+    Vector3 v1 = a - b, v2 = c - b;
+    mNormal = Normalize(CrossProd(v2, v1));
     mD = -DotProd(b, mNormal);
+}
+
+
+Plane3::Plane3(Vector3 &normal, float dist): 
+mNormal(normal), mD(dist)
+{
 }
 
@@ -28,34 +34,34 @@
 	Vector3 sx(a.mNormal.x, b.mNormal.x, c.mNormal.x),
 		    sy(a.mNormal.y, b.mNormal.y, c.mNormal.y),
-			sz(a.mNormal.z, b.mNormal.z, c.mNormal.z),
-			sd(a.mD, b.mD, c.mD);
+		    sz(a.mNormal.z, b.mNormal.z, c.mNormal.z),
+		    sd(a.mD, b.mD, c.mD);
 
-  Matrix4x4 md(a.mNormal, b.mNormal, c.mNormal), mx, my, mz;
+	Matrix4x4 md(a.mNormal, b.mNormal, c.mNormal), mx, my, mz;
 
-  mx.SetColumns(sd, sy, sz);
-  my.SetColumns(sx, sd, sz);
-  mz.SetColumns(sx, sy, sd);
-  
-  const float det = md.Det3x3();
+	mx.SetColumns(sd, sy, sz);
+	my.SetColumns(sx, sd, sz);
+	mz.SetColumns(sx, sy, sd);
 
-  if (fabs(det) < TRASH)
-    return false;
+	const float det = md.Det3x3();
 
-  result.SetValue(mx.Det3x3()/det,
-				  my.Det3x3()/det,
-				  mz.Det3x3()/det);
-  
-  return true;
+	if (fabs(det) < TRASH)
+		return false;
+
+	result.SetValue(mx.Det3x3()/det,
+		my.Det3x3()/det,
+		mz.Det3x3()/det);
+
+	return true;
 }
 
 
- bool PlaneIntersection(const Plane3 &p1, const Plane3 &p2)
- {
-	 return 
-		 p1.mNormal.x != p2.mNormal.x ||
-		 p1.mNormal.y != p2.mNormal.y ||
-		 p1.mNormal.z != p2.mNormal.z ||
-		 p1.mD == p2.mD;
- }
+bool PlaneIntersection(const Plane3 &p1, const Plane3 &p2)
+{
+	return 
+		p1.mNormal.x != p2.mNormal.x ||
+		p1.mNormal.y != p2.mNormal.y ||
+		p1.mNormal.z != p2.mNormal.z ||
+		p1.mD == p2.mD;
+}
 
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.h	(revision 2751)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.h	(revision 2755)
@@ -3,9 +3,6 @@
 
 
-
 #include "Matrix4x4.h"
 #include "Vector3.h"
-//#include "Plane3.h"
-//#include "Containers.h"
 
 
@@ -14,4 +11,5 @@
 
 struct Triangle3;
+class Plane3;
 
 /** Axis alignedd box class.
@@ -52,5 +50,5 @@
 	const Vector3& Max() const;
 
-	void Enlarge (const Vector3 &v);
+	void Enlarge(const Vector3 &v);
 
 	void EnlargeToMinSize();
@@ -63,6 +61,6 @@
 
 	void SetMax(int axis, const float value);
-
-	// Decrease box by given splitting plane
+	/** Decrease box by given splitting plane
+	*/
 	void Reduce(int axis, int right, float value); 
 
@@ -71,6 +69,6 @@
 	// the size of the box along all the axes
 	Vector3 Size() const;
-	float Radius() const { return 0.5f*Magnitude(Size()); }
-	float SqrRadius() const { return 0.5f*SqrMagnitude(Size()); }
+	float Radius() const { return 0.5f * Magnitude(Size()); }
+	float SqrRadius() const { return 0.5f * SqrMagnitude(Size()); }
 
 	// Return whether the box is unbounded.  Unbounded boxes appear
@@ -84,25 +82,7 @@
 	*/
 	void Include(const int &axis, const float &newBound);
-	// int Side(const Plane3 &plane) const;
-
-	// Overlap returns 1 if the two axis-aligned boxes overlap .. even weakly
-	friend inline bool Overlap(const AxisAlignedBox3 &, const AxisAlignedBox3 &);
-
-	// Overlap returns 1 if the two axis-aligned boxes overlap .. only strongly
-	friend inline bool OverlapS(const AxisAlignedBox3 &,const AxisAlignedBox3 &);
-
-	/** Overlap returns 1 if the two axis-aligned boxes overlap for a given
-	epsilon. If eps > 0.0, then the boxes has to have the real intersection
-	box, if eps < 0.0, then the boxes need not intersect really, they
-	can be at eps distance in the projection.
-	*/
-	friend inline bool Overlap(const AxisAlignedBox3 &,
-		const AxisAlignedBox3 &,
-		float eps);
-
 	/** Includes returns true if a includes b (completely)
 	*/
 	bool Includes(const AxisAlignedBox3 &b) const;
-
 	/** Returns true if this point is inside box.
 	*/
@@ -122,5 +102,5 @@
 	/** Scales the box with the factor.
 	*/
-	void Scale(const float scale);
+	void Scale(float scale);
 
 	void Scale(const Vector3 &scale);
@@ -177,15 +157,32 @@
 
 	int GetFaceVisibilityMask(const Vector3 &position) const;
-	/** Extracts plane of bounding box.
-	*/
-	//Plane3 GetPlane(const int face) const;
 	/** Returns vertex indices of edge.
 	*/
-	void GetEdge(const int edge, int  &aIdx, int &bIdx) const;
-
+	void GetEdge(int edge, int  &aIdx, int &bIdx) const;
+	/** Get distance of plane to vertex with specified index.
+	*/
+	float GetDistance(int index, const Plane3 &plane) const;
+	/** Returns the distance between the plane given by 'vecNearplaneNormal' and the vertex that
+	    is closest to it (this vertex is unequivocally identified by the direction of the vector)
+	*/
+	float GetMinVisibleDistance(const Plane3 &near) const;
 
 
 	////////////
 	//-- friend functions
+
+	/// Overlap returns 1 if the two axis-aligned boxes overlap .. even weakly
+	friend inline bool Overlap(const AxisAlignedBox3 &, const AxisAlignedBox3 &);
+
+	/// Overlap returns 1 if the two axis-aligned boxes overlap .. only strongly
+	friend inline bool OverlapS(const AxisAlignedBox3 &,const AxisAlignedBox3 &);
+
+	/** Overlap returns 1 if the two axis-aligned boxes overlap for a given
+	epsilon. If eps > 0.0, then the boxes has to have the real intersection
+	box, if eps < 0.0, then the boxes need not intersect really, they
+	can be at eps distance in the projection.
+	*/
+	friend inline bool Overlap(const AxisAlignedBox3 &,	const AxisAlignedBox3 &, float eps);
+
 
 	// Returns the smallest axis-aligned box that includes all points
@@ -250,8 +247,16 @@
 	static const int fsvertices[27][9];
 
+	/** Returns the vertex index nearest from the plane specified by the normal.
+	*/
+	static int GetIndexNearestVertex(const Vector3 &vecPlaneNormal);
+	/** Returns the vertwx index farthest from the plane specified by the normal.
+	*/
+	static int GetIndexFarthestVertex(const Vector3 &vecPlaneNormal);
+
+
+
 protected:
 
 	Vector3 mMin, mMax;
-
 };
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.cpp	(revision 2755)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/CHCTraverser.cpp	(revision 2755)
@@ -0,0 +1,104 @@
+#include "CHCTraverser.h"
+
+namespace CHCDemo
+{
+
+CHCTraverser::CHCTraverser(): RenderTraverser() 
+{
+}
+
+
+CHCTraverser::~CHCTraverser()
+{
+	//DelQueries();
+}
+
+
+void CHCTraverser::Render()
+{
+#if 0
+	QueryQueue queryQueue;
+
+	//-- PART 1: process finished occlusion queries
+	while (!mDistanceQueue.empty() || !queryQueue.empty())
+	{
+		while (!queryQueue.empty() && 
+			   (ResultAvailable(queryQueue.front()) || mDistanceQueue.empty()))
+		{
+			HierarchyNode *node = queryQueue.front();
+			queryQueue.pop();
+			
+			// wait until result available
+			int visiblePixels = GetOcclusionQueryResult(node);
+
+			if(visiblePixels > mVisibilityThreshold)
+			{
+				PullUpVisibility(node);
+				TraverseNode(node);
+			}
+			else
+			{
+				mNumQueryCulledNodes ++;
+			}
+		}	
+
+		//-- PART 2: hierarchical traversal
+		if (!mDistanceQueue.empty())
+		{
+			HierarchyNode *node = mDistanceQueue.top();
+
+			mDistanceQueue.pop();
+	
+			mNumTraversedNodes ++;
+
+			bool intersects;
+			
+			if (InsideViewFrustum(node, intersects))
+			{
+				// for near plane intersecting bounding box possible 
+				// wrong results => skip occlusion query
+				if(intersects)
+				{
+					// update node's visited flag
+					node->SetLastVisited(mFrameID);
+					node->SetVisible(true);
+					PullUpVisibility(node);
+					TraverseNode(node);
+				}
+				else
+				{		
+					// identify previously visible nodes
+					bool wasVisible = node->Visible() && (node->LastVisited() == mFrameID - 1);
+					
+					// identify nodes that we cannot skip queries for
+					bool leafOrWasInvisible = (node->LastVisited() != mFrameID) && (!wasVisible || node->IsLeaf());
+
+					// reset node's visibility classification 
+					node->SetVisible(false);
+
+					// update node's visited flag
+					node->SetLastVisited(mFrameID);
+					
+					// skip testing previously visible interior nodes
+					if(leafOrWasInvisible)
+					{
+						IssueOcclusionQuery(node, wasVisible);
+						queryQueue.push(node);
+					}
+					
+					// always traverse a node if it was visible
+					if(wasVisible)
+						TraverseNode(node);
+				}
+			}
+			else
+			{
+				// for stats
+				mNumFrustumCulledNodes ++;
+			}
+		}
+	}
+#endif
+}
+
+}
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.cpp	(revision 2751)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Geometry.cpp	(revision 2755)
@@ -1,11 +1,4 @@
-#if 0
-
-
 #include "Geometry.h"
-#include "glInterface.h"
-#include "stdio.h"
-#include "teapot.h"
-
-#include <math.h>
+#include "Triangle3.h"
 
 
@@ -13,208 +6,40 @@
 {
 
-#define NO_LIST    -1
-#define STRIP_END  -1
+Geometry::Geometry(const TriangleContainer &triangles)
+{}
 
-int Geometry::num_torus_indices;
-int Geometry::num_torus_vertices;
-int Geometry::num_torus_normals;
 
-const int Geometry::torus_precision = 24;
-const int Geometry::sphere_precision = 24;
-
-float *Geometry::torus_vertices;
-float *Geometry::torus_normals;
-int *Geometry::torus_indices;
-
-// choose size so the glut-rendered sphere is approximately
-// as big as the other objects
-const float Geometry::sphere_radius = 1.0 / 9.0f;
-const float Geometry::torus_inner_radius = 0.05;
-const float Geometry::torus_outer_radius = 0.07;
-
-int Geometry::sDisplayList[NUM_OBJECTS];
-
-bool Geometry::sIsInitialised = Init();
-
-Geometry::Geometry(): 
-mXRotation(0), mYRotation(0), mZRotation(0), mScale(1.0), mObjectType(TEAPOT)
+SceneEntity::SceneEntity(Geometry *geometry, 
+						 Matrix4x4 *trafo, 
+						 Material *mat):
+mGeometry(geometry), mTransform(trafo), mMaterial(mat)
 {
-	copyVector3Values(mTranslation, 0, 0, 0);
-	
-	SetAmbientColor(0.1745, 0.01175, 0.01175);
-	SetDiffuseColor(0.61424, 0.04136, 0.04136);
-	SetSpecularColor(0.727811, 0.626959, 0.626959);
-	
-	CalcBoundingVolume();
-	CalcTransform();
-	GenerateList();
-}
-
-Geometry::Geometry(Vector3 translation, float xRot, float yRot, float zRot, float scale, int objectType):
-mXRotation(xRot), mYRotation(yRot), mZRotation(zRot), mScale(scale), mObjectType(objectType)
-{
-	copyVector3(mTranslation, translation);
-
-	SetAmbientColor(0.1745, 0.01175, 0.01175);
-	SetDiffuseColor(0.61424, 0.04136, 0.04136);
-	SetSpecularColor(0.727811, 0.626959, 0.626959);
-	
-	CalcBoundingVolume();
-	CalcTransform();
-	GenerateList();
-}
-
-void Geometry::ResetLists()
-{
-	for(int i = 0; i < NUM_OBJECTS; i++)
-	{
-        if(sDisplayList[i] == NO_LIST)
-			glDeleteLists(sDisplayList[i], 1);
-
-		sDisplayList[i] = NO_LIST;
-	}
-}
-
-void Geometry::CleanUp()
-{
-	ResetLists();
-
-	delete [] torus_vertices;
-	delete [] torus_normals;
-	delete [] torus_indices;
 }
 
 
-bool Geometry::Init()
+void SceneEntity::Render()
 {
-	for(int i=0; i < NUM_OBJECTS; i++)
-		sDisplayList[i] = NO_LIST;
-
-	// parameters chosen so torus is approximately as big as teapot
-	CreateTorus(torus_inner_radius, torus_outer_radius, torus_precision);
-
-	return true;
 }
 
 
-void Geometry::GenerateList()
+void SceneEntity::SetGeometry(Geometry *geom)
 {
-	if(sDisplayList[mObjectType] == NO_LIST)
-	{
-		sDisplayList[mObjectType] = glGenLists(1);
-		glNewList(sDisplayList[mObjectType], GL_COMPILE);
-
-		switch(mObjectType)
-		{
-			case TEAPOT:
-				RenderTeapot();
-				break;
-			case TORUS:
-				RenderTorus();
-				break;
-			case SPHERE:	
-				RenderSphere();
-				break;
-			
-			default:
-				break;
-		}
-
-		glEndList();
-	}
+	mGeometry = geom;
 }
 
 
-void Geometry::Render()
+void SceneEntity::SetTransformation(Matrix4x4 *trafo)
 {
-	glMaterialfv(GL_FRONT, GL_AMBIENT, mAmbientColor);
-	glMaterialfv(GL_FRONT, GL_DIFFUSE, mDiffuseColor);
-	glMaterialfv(GL_FRONT, GL_SPECULAR, mSpecularColor);
-	
-	glPushMatrix();
-	
-	Transform();
-	
-	glCallList(sDisplayList[mObjectType]);
-
-	glPopMatrix();
+	mTransform = trafo;
 }
 
 
-//! sets rotations around the three axis: executed in the order specified here
-void Geometry::SetRotations(float xRot, float yRot, float zRot)
+void SceneEntity::SetMaterial(Material *mat)
 {
-	mXRotation = xRot;
-	mYRotation = yRot;
-	mZRotation = zRot;
-
-	CalcBoundingVolume();
-	CalcTransform();
+	mMaterial = mat;
 }
 
 
-void Geometry::SetTranslation(Vector3 translation)
-{
-	copyVector3(mTranslation, translation);
-
-	CalcBoundingVolume();
-	CalcTransform();
-}
-
-
-void Geometry::SetScale(float scale)
-{
-	mScale = scale;
-	CalcTransform();
-
-	CalcBoundingVolume();
-}
-
-
-void Geometry::SetAmbientColor(float ambientR, float ambientG, float ambientB)
-{
-	mAmbientColor[0] = ambientR;
-	mAmbientColor[1] = ambientG;
-	mAmbientColor[2] = ambientB;
-}
-
-
-void Geometry::SetDiffuseColor(float diffuseR, float diffuseG, float diffuseB)
-{
-	mDiffuseColor[0] = diffuseR;
-	mDiffuseColor[1] = diffuseG;
-	mDiffuseColor[2] = diffuseB;
-}
-
-
-void Geometry::SetSpecularColor(float specularR, float specularG, float specularB)
-{
-	mSpecularColor[0] = specularR;
-	mSpecularColor[1] = specularG;
-	mSpecularColor[2] = specularB;
-}
-
-
-float Geometry::GetScale()
-{
-	return mScale;
-}
-
-
-void Geometry::GetTranslation(Vector3 translation)
-{
-	copyVector3(translation, mTranslation);
-}
-
-
-void Geometry::GetRotations(float &xRot, float &yRot, float &zRot)
-{
-	xRot = mXRotation;
-	yRot = mYRotation;
-	zRot = mZRotation;
-}
-
-	
-const AABox &Geometry::GetBoundingVolume()
+const AxisAlignedBox3& SceneEntity::GetBoundingVolume()
 {
 	return mBoundingBox;
@@ -222,5 +47,5 @@
 
 
-void Geometry::SetLastVisited(int lastVisited)
+void SceneEntity::SetLastVisited(int lastVisited)
 {
 	mLastVisited = lastVisited;
@@ -228,5 +53,5 @@
 
 
-int Geometry::GetLastVisited()
+int SceneEntity::GetLastVisited() const
 {
 	return mLastVisited;
@@ -234,326 +59,3 @@
 
 
-void Geometry::SetObjectType(int type)
-{
-	mObjectType = type;
-	GenerateList();
 }
-
-
-void Geometry::RenderTeapot()
-{
-	int i = 0;
-
-	while(i < num_teapot_indices)
-	{
-		glBegin(GL_TRIANGLE_STRIP);
-		
-		while (teapot_indices[i] != STRIP_END)
-		{	
-			int index = teapot_indices[i] * 3;
-
-			glNormal3fv(teapot_normals + index);
-			glVertex3fv(teapot_vertices + index);
-			
-			++ i;		
-		}
-
-		glEnd();
-
-		++ i; // skip strip end flag
-	}
-}
-
-
-void Geometry::CalcBoundingVolume()
-{
-    switch(mObjectType)
-	{
-		case TORUS:
-			CalcBoundingVolume(torus_vertices, num_torus_vertices);
-			break;
-		case SPHERE:
-			CalcSphereBoundingVolume();
-			break;
-		case TEAPOT:
-			CalcBoundingVolume(teapot_vertices, num_teapot_vertices);
-			break;
-		default:
-			break;
-	}
-}
-
-
-void Geometry::CalcBoundingVolume(float *vertices, const int num_vertices)
-{
-	Vector3 *rotatedPoints = new Vector3[num_vertices];
-	
-	for (int i = 0; i < num_vertices; ++ i)
-	{
-		copyVector3Values(rotatedPoints[i], vertices[i * 3],
-						  vertices[i * 3 + 1], vertices[i * 3 + 2]);
-	
-		rotateVectorZ(rotatedPoints[i], mZRotation * PI_180);
-		rotateVectorY(rotatedPoints[i], mYRotation * PI_180);
-		rotateVectorX(rotatedPoints[i], mXRotation * PI_180);
-	}
-
-	calcCubicHull(mBoundingBox.min, mBoundingBox.max, rotatedPoints, num_vertices);
-
-	for (int i = 0; i < 3; ++ i)
-	{
-		mBoundingBox.min[i] *= mScale;
-		mBoundingBox.max[i] *= mScale;
-	}
-
-	addVector3(mBoundingBox.min, mTranslation, mBoundingBox.min);
-    addVector3(mBoundingBox.max, mTranslation, mBoundingBox.max);
-
-	delete [] rotatedPoints;
-}
-
-
-void Geometry::CalcSphereBoundingVolume()
-{
-	float len = mScale * sphere_radius;
-	Vector3 size = {len, len, len};
-					
-	diffVector3(mBoundingBox.min, mTranslation, size);
-	addVector3(mBoundingBox.max, mTranslation, size);
-}
-
-
-void Geometry::RenderTorus()
-{
-	glVertexPointer(3, GL_FLOAT, sizeof(float), torus_vertices);
-	glEnableClientState(GL_VERTEX_ARRAY);
-
-	glNormalPointer(GL_FLOAT, sizeof(float), torus_normals);
-	glEnableClientState(GL_NORMAL_ARRAY);
-
-    glDrawElements(GL_TRIANGLES, num_torus_indices, GL_UNSIGNED_INT, torus_indices);
-
-	glDisableClientState(GL_VERTEX_ARRAY);
-	glDisableClientState(GL_NORMAL_ARRAY);
-}
-
-/*	Creates a torus with specified radii, with number of rings and ring
-	subdivision = precision.
-*/
-void Geometry::CreateTorus(float innerRadius, float outerRadius, int precision)
-{
-	num_torus_vertices = num_torus_normals = (precision + 1) * (precision + 1);
-	num_torus_indices = 2 * precision * precision * 3;
-
-	torus_vertices = new float[num_torus_vertices * 3];
-	torus_normals = new float[num_torus_normals * 3];
-	torus_indices = new int[num_torus_indices];
-
-	for (int i = 0; i < precision + 1; ++ i)
-	{
-		int index = i * 3;
-
-		Vector3 currentVertex = {innerRadius, 0.0f, 0.0f};
-		rotateVectorZ(currentVertex, ((float)i * 2.0 * PI) / (float)precision);
-
-		currentVertex[0] += outerRadius;
-		
-		Vector3 sTangent = {0.0f, 0.0f, -1.0f};
-		Vector3 tTangent = {0, -1, 0};
-		rotateVectorZ(tTangent, ((float)i * 2.0 * PI) / (float)precision);
-
-      	Vector3 currentNormal;
-
-		cross(currentNormal, tTangent, sTangent);
-
-		torus_normals[index + 0] = currentNormal[0];
-		torus_normals[index + 1] = currentNormal[1];
-		torus_normals[index + 2] = currentNormal[2];
-		
-		torus_vertices[index + 0] = currentVertex[0];
-		torus_vertices[index + 1] = currentVertex[1];
-		torus_vertices[index + 2] = currentVertex[2];
-	}
-
-	for (int i_rng = 1; i_rng < precision + 1; ++ i_rng)
-	{
-		for(int i = 0; i<precision + 1; ++ i)
-		{
-			int index = 3 * (i_rng * (precision + 1) + i);
-
-			Vector3 currentVertex = {torus_vertices[i*3], torus_vertices[i*3+1], torus_vertices[i*3+2]};
-			
-			rotateVectorY(currentVertex, ((float)i_rng * 2.0 * PI) / (float)precision);
-						
-			Vector3 currentNormal = {torus_normals[i*3], torus_normals[i*3+1], torus_normals[i*3+2]};
-			
-			rotateVectorY(currentNormal, ((float)i_rng * 2.0 * PI) / (float)precision);
-
-			torus_normals[index + 0] = currentNormal[0];
-			torus_normals[index + 1] = currentNormal[1];
-			torus_normals[index + 2] = currentNormal[2];
-		
-			torus_vertices[index + 0] = currentVertex[0];
-			torus_vertices[index + 1] = currentVertex[1];
-			torus_vertices[index + 2] = currentVertex[2];
-		}
-	}
-
-	for (int i_rng = 0; i_rng < precision; ++ i_rng)
-	{
-		for (int i = 0; i < precision; ++ i)
-		{
-			int index = ((i_rng * precision + i) * 2) * 3;
-
-			torus_indices[index+0] = (i_rng     * (precision+1) + i)*3;
-			torus_indices[index+1] = ((i_rng+1) * (precision+1) + i)*3;
-			torus_indices[index+2] = (i_rng     * (precision+1) + i + 1)*3;
-
-			index = ((i_rng * precision + i) * 2 + 1) * 3;
-
-			torus_indices[index+0] = (i_rng     * (precision+1) + i + 1)*3;
-			torus_indices[index+1] = ((i_rng+1) * (precision+1) + i)*3;
-			torus_indices[index+2] = ((i_rng+1) * (precision+1) + i + 1)*3;
-		}
-	}
-}
-
-
-/** Counts the triangles of the teapot.
-	traverses through all the triangle strips.
-*/
-int Geometry::CountTeapotTriangles()
-{
-	int result = 0;
-	int i = 0;
-
-	// n - 2 triangles are drawn for a strip
-	while (i < num_teapot_indices)
-	{
-		while (teapot_indices[i] != STRIP_END)
-		{	
-			result ++;;
-			++ i;		
-		}
-		result -= 2;
-		++ i; // skip STRIP_END
-	}
-
-	return result;
-}
-
-
-/**	Counts the triangles of the torus
-*/
-int Geometry::CountTorusTriangles()
-{
-	// every 3 indices specify one triangle
-	return num_torus_indices / 3;
-}
-
-/**
-	counts the triangles of the sphere.
-	sphere_precision / 2 + 1 strips with sphere_precision * 2 - 2 triangles each
-*/
-int Geometry::CountSphereTriangles()
-{
-	return sphere_precision * sphere_precision;
-}
-
-
-int Geometry::CountTriangles(int objectType)
-{
-	int result = 0;
-
-	switch (objectType)
-	{
-		case TEAPOT:
-			result = CountTeapotTriangles();
-			break;
-		case TORUS:
-			result = CountTorusTriangles();
-			break;
-		case SPHERE:	
-			result = CountSphereTriangles();
-			break;
-		default:
-			break;
-	}
-
-	return result;
-}
-
-
-void Geometry::Transform()
-{
-	glMultMatrixd(mTransform);
-}
-
-void Geometry::CalcTransform()
-{
-	Matrix4x4 scale;
-	Matrix4x4 xrot;
-	Matrix4x4 yrot;
-	Matrix4x4 zrot;
-	Matrix4x4 transl;
-
-	makeScaleMtx(scale, mScale, mScale, mScale);
-	makeTranslationMtx(transl, mTranslation);
-	makeRotationXMtx(xrot, mXRotation * PI_180);
-	makeRotationYMtx(yrot, mYRotation * PI_180);
-	makeRotationZMtx(zrot, mZRotation * PI_180);
-
-	copyMatrix(mTransform, IDENTITY);
-	mult(mTransform, mTransform, transl);
-	mult(mTransform, mTransform, xrot);
-	mult(mTransform, mTransform, yrot);
-	mult(mTransform, mTransform, zrot);
-	mult(mTransform, mTransform, scale);
-}
-
-
-/** Renders a sphere with sphere_precision subdivisions. 
-    Note: works only for even sphere_precision
-*/
-void Geometry::RenderSphere()
-{
-	Vector3 vertex;
-
-	// this algorithm renders the triangles clockwise
-	glFrontFace(GL_CW);
-
-	for (int j = 0; j < sphere_precision / 2; ++ j) 
-	{
-		double alpha = j * PI * 2.0 / (double)sphere_precision - PI_2;
-		double beta = (j + 1) * PI * 2.0 / (double)sphere_precision - PI_2;
-
-		glBegin(GL_TRIANGLE_STRIP);
-
-		for (int i = 0; i <= sphere_precision; ++ i) 
-		{
-			double gamma = i * PI * 2.0 / (double)sphere_precision;
-	
-			vertex[0] = sphere_radius * cos(beta) * cos(gamma);
-			vertex[1] = sphere_radius * sin(beta);
-			vertex[2] = sphere_radius * cos(beta) * sin(gamma);
-
-			glNormal3dv(vertex);
-			glVertex3dv(vertex);
-
-			vertex[0] = sphere_radius * cos(alpha) * cos(gamma);
-			vertex[1] = sphere_radius * sin(alpha);
-			vertex[2] = sphere_radius * cos(alpha) * sin(gamma);
-
-		    glNormal3dv(vertex);
-			glVertex3dv(vertex);
-
-		}
-		glEnd();
-	}
-
-	glFrontFace(GL_CCW);
-}
-
-}
-
-#endif
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/chc_revisited.vcproj
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/chc_revisited.vcproj	(revision 2754)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/chc_revisited.vcproj	(revision 2755)
@@ -120,4 +120,5 @@
 			<Tool
 				Name="VCCLCompilerTool"
+				Optimization="3"
 				InlineFunctionExpansion="2"
 				EnableIntrinsicFunctions="true"
@@ -130,4 +131,5 @@
 				RuntimeTypeInfo="false"
 				UsePrecompiledHeader="0"
+				BrowseInformation="1"
 				WarningLevel="3"
 				Detect64BitPortabilityProblems="true"
@@ -205,4 +207,8 @@
 			</File>
 			<File
+				RelativePath=".\Material.cpp"
+				>
+			</File>
+			<File
 				RelativePath=".\OcclusionQuery.cpp"
 				>
@@ -247,4 +253,20 @@
 			</File>
 			<File
+				RelativePath=".\BinaryLoader.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\BinaryLoader.h"
+				>
+			</File>
+			<File
+				RelativePath=".\BvhLoader.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\BvhLoader.h"
+				>
+			</File>
+			<File
 				RelativePath=".\common.cpp"
 				>
@@ -256,8 +278,4 @@
 			<File
 				RelativePath=".\glInterface.h"
-				>
-			</File>
-			<File
-				RelativePath=".\Material.cpp"
 				>
 			</File>
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.h	(revision 2753)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.h	(revision 2755)
@@ -4,7 +4,9 @@
 #include "Vector3.h"
 #include "AxisAlignedBox3.h"
+#include "Plane3.h"
 
 
-namespace CHCDemo {
+namespace CHCDemo 
+{
 
 
@@ -12,5 +14,16 @@
 {
 public:
+	
+	/** Small struct representing a frustum.
+	*/
+	struct Frustum
+	{
+		/// the 6 clip planes
+		//float mClipPlane[6][4];
+		Plane3 mClipPlanes[6];
 
+		void CalcNPVertexIndices(int *indices);
+	};
+	
 	Camera();
 
@@ -34,4 +47,11 @@
 	inline float GetFov() const { return mFovy; }
 	inline void GetSize(int &width, int &height) const { width = mWidth; height = mHeight; }
+	inline float GetAspect() const { return (float) mWidth / mHeight; }
+
+	void GetProjectionMatrix(Matrix4x4 &mat);
+	void GetModelViewMatrix(Matrix4x4 &mat);
+
+	void CalcFrustum(Frustum &frustum);
+
 
 protected:
@@ -50,5 +70,4 @@
 	int mWidth;
 	int mHeight;
-
 };
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Material.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Material.cpp	(revision 2751)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Material.cpp	(revision 2755)
@@ -8,4 +8,27 @@
 {
 	return RgbColor(a + Random(b), a + Random(b), a + Random(b));
+}
+
+
+ 
+Material::Material(): mId(0)
+{}
+  
+
+Material::Material(const int id): mId(id)
+{
+}
+
+
+Material::Material(const RgbColor &color):mDiffuseColor(color),
+mAmbientColor(color),
+mSpecularColor(0,0,0), mId(0)
+{
+}
+
+
+int Material::GetId() const
+{
+	return mId;
 }
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.cpp	(revision 2755)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/CHCPlusPlusTraverser.cpp	(revision 2755)
@@ -0,0 +1,21 @@
+#include "CHCPlusPlusTraverser.h"
+
+namespace CHCDemo
+{
+
+CHCPlusPlusTraverser::CHCPlusPlusTraverser(): RenderTraverser() 
+{
+}
+
+
+CHCPlusPlusTraverser::~CHCPlusPlusTraverser()
+{
+	//DelQueries();
+}
+
+
+void CHCPlusPlusTraverser::Render()
+{
+}
+
+}
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/BvhLoader.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/BvhLoader.cpp	(revision 2755)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/BvhLoader.cpp	(revision 2755)
@@ -0,0 +1,134 @@
+#include <queue>
+#include <stack>
+#include <fstream>
+#include <iostream>
+
+#include "BvhLoader.h"
+
+
+
+namespace CHCDemo
+{
+
+using namespace std;
+
+
+#define TYPE_INTERIOR -2
+#define TYPE_LEAF -3
+
+
+
+BvhLeaf *BvhLoader::ImportBinLeaf(ifstream &stream, BvhInterior *parent)
+{
+	BvhLeaf *leaf = new BvhLeaf(parent);
+
+	int first, last;
+
+	stream.read(reinterpret_cast<char *>(&first), sizeof(int));
+	stream.read(reinterpret_cast<char *>(&last), sizeof(int));
+
+	leaf->mFirst = first;
+	leaf->mLast = last;
+
+	return leaf;
+}
+
+
+BvhInterior *BvhLoader::ImportBinInterior(ifstream &stream, BvhInterior *parent)
+{
+	BvhInterior *interior = new BvhInterior(parent);
+
+	stream.read(reinterpret_cast<char *>(&interior->mAxis), sizeof(char));
+	stream.read(reinterpret_cast<char *>(&interior->mPosition), sizeof(float));
+
+	return interior;
+}
+
+
+BvhNode *BvhLoader::LoadNextNode(ifstream &stream, BvhInterior *parent)
+{
+	int nodeType;
+	stream.read(reinterpret_cast<char *>(&nodeType), sizeof(int));
+
+	if (nodeType == TYPE_LEAF)
+	{
+		//OUT1("l");
+		return ImportBinLeaf(stream, static_cast<BvhInterior *>(parent));
+	}
+
+	if (nodeType == TYPE_INTERIOR)
+	{
+		//OUT1("i");
+		return ImportBinInterior(stream, static_cast<BvhInterior *>(parent));
+	}
+
+	return NULL;
+}
+
+
+Bvh *BvhLoader::LoadFromFile(const string &filename,  
+							 const SceneEntityContainer &entities)
+{
+	// export binary version of mesh
+	queue<BvhNode *> tStack;
+	ifstream stream(filename.c_str(), ifstream::binary);
+
+	if (!stream.is_open()) return NULL;
+
+	cout << "loading bvh" << endl;
+	Bvh *bvh = new Bvh();
+
+	bvh->mGeometrySize = entities.size();
+	bvh->mGeometry = new SceneEntity*[bvh->mGeometrySize];
+
+	for (size_t i = 0; i < bvh->mGeometrySize; ++ i)
+		bvh->mGeometry[i] = entities[i];
+
+	bvh->mRoot = LoadNextNode(stream, NULL);
+
+	tStack.push(bvh->mRoot);
+	bvh->mNumNodes = 1;
+
+	while(!tStack.empty())
+	{
+		BvhNode *node = tStack.front();
+		tStack.pop();
+
+		if (!node->IsLeaf())
+		{
+			bvh->mNumNodes += 2;
+
+			BvhInterior *interior = static_cast<BvhInterior *>(node);
+
+            BvhNode *front = LoadNextNode(stream, interior);
+			BvhNode *back = LoadNextNode(stream, interior);
+	
+			interior->mFront = front;
+			interior->mBack = back;
+
+			front->mDepth = interior->mDepth + 1;
+			back->mDepth = interior->mDepth + 1;
+
+			tStack.push(front);			
+			tStack.push(back);
+		}
+	}
+
+	cout << "... finished loading " << bvh->mNumNodes << " nodes, updating boxes" << endl;
+
+	//adjust bounding boxes
+	//bvh->UpdateBoxes(bvh->mRoot);
+	//bvh->UpdateNumLeaves(bvh->mRoot);
+
+	// compute unique ids
+	//bvh->ComputeIds();
+	// update the indices of the geometry so we can render interiors as well
+	//bvh->UpdateInteriors(bvh->mRoot);
+	// do this once so at least the current node bounding box is tested
+	//bvh->RecomputeBounds();
+
+	return bvh;
+}
+
+
+}
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.cpp	(revision 2747)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/BinaryLoader.cpp	(revision 2755)
@@ -1,14 +1,16 @@
 #include "BinaryLoader.h"
-#include "yare.h"
-#include "yamath.h"
-#include "gzstream.h"
-#include "ImageComponent.h"
-#include "RenderState.h"
-#include "GeometryProcessor.h"
+#include "Matrix4x4.h"
+#include "Geometry.h"
+#include "Material.h"
+//#include "gzstream.h"
 
 
 using namespace std;
 
-static STL_MAP<String,Texture *> stlm_textures;
+
+namespace CHCDemo
+{
+
+/*static STL_MAP<String,Texture *> stlm_textures;
 
 
@@ -61,22 +63,25 @@
 
 	return myTexture;
-}
-
-
-Shape3D *BinaryLoader::LoadShape(igzstream &str)
+}*/
+
+
+//SceneEntity *BinaryLoader::LoadShape(igzstream &str)
+SceneEntity *BinaryLoader::LoadShape(ifstream &str)
 {	
 	Geometry *geom = LoadGeometry(str);
-	Appearance *app = LoadAppearance(str);
-
-	Shape3D *shape = new Shape3D(geom, app);
-
-	return shape;
-}
-
-
-Appearance *BinaryLoader::LoadAppearance(igzstream &str)
-{
-	Appearance *app = new Appearance();
-	
+	Material *mat = LoadMaterial(str);
+
+	Matrix4x4 *m;
+	SceneEntity *sceneGeom = new SceneEntity(geom, m, mat);
+
+	return sceneGeom;
+}
+
+
+//Appearance *BinaryLoader::LoadMaterial(igzstream &str)
+Material *BinaryLoader::LoadMaterial(ifstream &str)
+{
+	Material *mat = new Material();
+/*	
 	// texture
 	int texnameSize;
@@ -113,6 +118,4 @@
 		//str.read(reinterpret_cast<char *>(&spec), sizeof(Color3f));
 		//str.read(reinterpret_cast<char *>(&shine), sizeof(float));
-#if 1
-		Material *mat = new Material();
 
 		mat->setAmbientColor(amb);
@@ -123,13 +126,16 @@
 
 		app->setMaterial(mat);
-#endif
-	}
-
-	return app;
-}
-
-
-Geometry *BinaryLoader::LoadGeometry(igzstream &str)
-{
+	}
+
+	return app;*/
+
+	return mat;
+}
+
+
+//Geometry *BinaryLoader::LoadGeometry(igzstream &str)
+Geometry *BinaryLoader::LoadGeometry(ifstream &str)
+{
+/*
 	int vertexCount;
 	int stripCount;
@@ -254,9 +260,12 @@
 	
 	return geom; 
-}
-
-
-BranchGroup *BinaryLoader::Load(const string &filename)
-{
+	*/
+return 0;
+}
+
+
+bool BinaryLoader::Load(const std::string &filename, SceneEntityContainer &geometry)
+{
+#if 0
 	clear_textures(); // clear the texture table
 
@@ -320,38 +329,6 @@
 
 	return root;
-}
-
-
-#if 0
-
-collectvertices
-{
-	int newIndex = 0;
-
-	for (int i = 0; i < numTriangles; ++ i)
-	{
-		Triangle tri = mTriangles[i];
-
-		for (int j = 0; j < 3; ++ j)
-		{
-			const int index = tri.mVertexIndices[j];
-			if (!mHashtable[index])
-			{
-				mHashTable[index] = newIndex;
-				mNewVertices.push_back(mVertices[index];
-			}
-	}
-
-	// now loop again, exchange indices;
-	for (int i = 0; i < numTriangles; ++ i
-	{
-		Triangle tri = mTriangles[i];
-
-		for (int j = 0; j < 3; ++ j)
-		{
-			const int index = tri.mVertexIndices[j];
-			tri.mVertexIndices[j] = mHashTable[index];
-	}
-}
-
 #endif
+}
+
+}
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.h	(revision 2754)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/RenderTraverser.h	(revision 2755)
@@ -5,11 +5,9 @@
 #include <stack>
 #include "glInterface.h"
-
+#include "Bvh.h"
 
 namespace CHCDemo
 {
 
-class BvhNode;
-class Bvh;
 class Camera;
 class Matrix4x4;
@@ -44,4 +42,5 @@
 
 //typedef std::priority_queue<BvhNode *, std::vector<BvhNode *>, myless<std::vector<BvhNode *>::value_type> > TraversalQueue;
+typedef std::priority_queue<BvhNode *, std::vector<BvhNode *>, myless> TraversalQueue;
 
 /** Abstract class implementing a scene traversal for rendering.
@@ -112,6 +111,8 @@
 	void Switch2GLQueryState();
 
+	void EnqueueNode(BvhNode *node);
 
-protected:
+	////////////
+	//-- members
 
 	// /the current clip planes of the view frustum
@@ -126,5 +127,5 @@
 	Bvh *mBvh;
 	/// use a priority queue rather than a renderstack
-	//PriorityQueue mDistanceQueue; 
+	TraversalQueue mDistanceQueue; 
 	
 	int mFrameID;
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.cpp	(revision 2751)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/AxisAlignedBox3.cpp	(revision 2755)
@@ -2,7 +2,9 @@
 #include <iostream>
 #include "AxisAlignedBox3.h"
+#include "Plane3.h"
 
 
 using namespace std;
+
 
 namespace CHCDemo
@@ -1027,8 +1029,48 @@
 		return mMin[face];
 	else
-			return mMax[face - 3];
-}
-
-
-}
-
+		return mMax[face - 3];
+}
+
+
+int AxisAlignedBox3::GetIndexNearestVertex(const Vector3 &vecPlaneNormal)
+{
+	int index;
+
+	if (vecPlaneNormal.x > 0.0f)
+		index = (vecPlaneNormal.y > 0.0f) ? 0 : 3;
+	else
+		index = (vecPlaneNormal.y > 0.0f) ? 1 : 2;
+
+	return (vecPlaneNormal.z > 0.0f) ? index : 7 - index;
+}
+
+
+int AxisAlignedBox3::GetIndexFarthestVertex(const Vector3 &vecPlaneNormal)
+{
+	int index;
+
+	if (vecPlaneNormal.x <= 0.0f)
+		index = (vecPlaneNormal.y <= 0.0f) ? 0 : 3;
+	else
+		index = (vecPlaneNormal.y <= 0.0f) ? 1 : 2;
+
+	return (vecPlaneNormal.z <= 0.0f) ? index : 7 - index;
+}
+
+
+float AxisAlignedBox3::GetDistance(int index, const Plane3 &plane) const
+{
+	return plane.Distance(GetVertex(index));
+}
+
+
+float AxisAlignedBox3::GetMinVisibleDistance(const Plane3 &near) const
+{
+	return	near.mNormal.x * ((near.mNormal.x > 0.0f) ? mMin.x : mMax.x) +
+			near.mNormal.y * ((near.mNormal.y > 0.0f) ? mMin.y : mMax.y) +
+			near.mNormal.z * ((near.mNormal.z > 0.0f) ? mMin.z : mMax.z) +
+			near.mD;
+}
+
+}
+
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.h	(revision 2753)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Bvh.h	(revision 2755)
@@ -5,5 +5,4 @@
 
 #include "Geometry.h"
-//#include "FlexibleHeap.h"
 
 
@@ -14,5 +13,5 @@
 // Forward declarations
 
-class SceneGeometry;
+class SceneEntity;
 class Camera;
 
@@ -23,4 +22,6 @@
 {
 	friend class Bvh;
+	friend class BvhLoader;
+	friend class myless;
 
 public:
@@ -52,5 +53,4 @@
 	*/
 	BvhNode(BvhNode *parent);
-	
 	/** Returns true if this node is a leaf.
 	*/
@@ -75,13 +75,13 @@
 	virtual void ResetVisibility();
 
-	virtual int GetType() = 0; //{ return BVH_NODE; }
-
-
-	/////////////////////
+	virtual bool IsLeaf() = 0; //{ return BVH_NODE; }
+
+
+	////////////////
 	//-- visibility culling related functions
 
 	inline int GetLastVisitedFrame() const;
 
-	inline void SetLastVisitedFrame(const int lastVisited);
+	inline void SetLastVisitedFrame(int lastVisited);
 	/** If this node is considered visible.
 	*/
@@ -89,8 +89,8 @@
 	/** Set visibility flag of the node.
 	*/
-	inline void SetVisible(const bool visible);
+	inline void SetVisible(bool visible);
 	/** The assumed visible time span of this node.
 	*/
-	inline void SetAssumedVisibleFrames(const int t);
+	inline void SetAssumedVisibleFrames(int t);
 	/** See set.
 	*/
@@ -108,17 +108,28 @@
 	
 	inline int GetTimesInvisible() const;
-	inline void SetTimesInvisible(const int t);
+	inline void SetTimesInvisible(int t);
 	
 	inline int GetTurnedVisibleFrame() const;
-	inline void SetTurnedVisibleFrame(const int turnedVisibleFrame);
+	inline void SetTurnedVisibleFrame(int turnedVisibleFrame);
 
 	inline int GetLastTestedFrame();
-	inline void SetLastTestedFrame(const int lastTested);
+	inline void SetLastTestedFrame(int lastTested);
 	
 	inline bool IsViewFrustumCulled() const;
-	inline void SetViewFrustumCulled(const bool frustumCulled);
+	inline void SetViewFrustumCulled(bool frustumCulled);
 
 	inline bool IsNew() const;
-	inline void SetIsNew(const bool isNew);
+	inline void SetIsNew(bool isNew);
+
+
+	/** Returns the bounding box of this node.
+	*/
+	inline const AxisAlignedBox3 &GetBox() { return mBox; }
+	/** Return index of this node.
+	*/
+	inline int GetId() const { return mId; }
+	/** See get
+	*/
+	inline void SetId(int id) { mId = id; }
 
 
@@ -152,5 +163,5 @@
 	/// the parent node
 	BvhNode *mParent;
-	/// stores the visibility related parameters
+	/// stores the visibility related info
 	VisibilityInfo mVisibility;
 
@@ -181,8 +192,20 @@
 	/// these nodes can be tested instead of the current node
 	int mTestNodesIdx;
+	
 	int mNumTestNodes;
+
 	int mIndicesPtr;
+
 	/// Area of this node
 	float mArea;
+	/// distance to the camera
+	float mDistance;
+	/// the index of this node
+	unsigned int mId;
+	/// indices used for draw array rendering
+	unsigned int *mIndices;
+	/// the bounding box
+	AxisAlignedBox3 mBox;
+
 };
 
@@ -302,7 +325,9 @@
 class BvhInterior: public BvhNode
 {
-friend class Bvh;
+	friend class Bvh;
+	friend class BvhLoader;
 
 public:
+
 	BvhInterior(BvhNode *parent): mBack(NULL), mFront(NULL), BvhNode(parent)
 	{}
@@ -319,5 +344,5 @@
 	/** Returns split axis of this interior node.
 	*/
-	inline int GetAxis() {return (int)mAxis;}
+	inline int GetAxis() { return (int)mAxis; }
 	/** Returns position of the split axis.
 	*/
@@ -337,5 +362,6 @@
 class BvhLeaf: public BvhNode
 {
-friend class Bvh;
+	friend class Bvh;
+	friend class BvhLoader;
 
 public:
@@ -347,4 +373,17 @@
 
 	virtual bool IsLeaf() { return true; }
+};
+
+
+/**	This class implements the compare operator for the priority queue.
+	a lower distance has a higher value in the queue
+*/
+class myless
+{
+public:
+	bool operator() (BvhNode *v1, BvhNode *v2) const
+    {
+		return (v1->mDistance > v2->mDistance);
+    }
 };
 
@@ -354,4 +393,6 @@
 class Bvh
 {
+	friend class BvhLoader;
+
 	/** Bvh properties
 	*/
@@ -401,10 +442,7 @@
 	*/
 	inline int GetNumLeaves() const {return mNumNodes / 2 + 1;}
-	/** Constructs the bounding volume hierarchy.
-	*/
-	void Construct();
 	/** Returns root node of the bvh.
 	*/
-	BvhNode *GetRoot() {return mRoot;}
+	BvhNode *GetRoot() { return mRoot; }
 	/** Counts the triangle in this leaf.
 	*/
@@ -412,9 +450,14 @@
 
 
+	void CollectNodes(BvhNode *node, BvhNodeContainer &nodes, int depth);
+	void CollectNodes(BvhNode *node, BvhNodeContainer &nodes);
+	void CollectLeaves(BvhNode *node, BvhLeafContainer &leaves);
+
+
 	//////////////////////
 
 	/** Returns geometry by reference (faster).
 	*/
-	SceneGeometry **GetGeometry(BvhNode *node, int &size);
+	SceneEntity **GetGeometry(BvhNode *node, int &size);
 
 
@@ -442,21 +485,14 @@
 	*/
 	int	IsWithinViewFrustum(BvhNode *node);
-	/** sets frame dependent values.
-	*/
-	void InitFrame(Camera *camera, const int currentFrameId);
-	/** this gives the orthogonal distance from the viewpoint to the nearest bounding box vertex
+	/** Sets frame dependent values.
+	*/
+	void InitFrame(Camera *camera, int currentFrameId);
+	/** This gives the orthogonal distance from the viewpoint to the nearest bounding box vertex
 		note that negative values can appear because culling is done only afterwards
 	*/
 	float CalcDistance(BvhNode *node) const;
-	/** Sets maximal depth for taking the bounding boxes to test the
-		visibility of a node. The deeper the more the box fits to the geometry.
-	*/
-	void SetMaxDepthForTestingChildren(const int maxDepth);
-	/** Pulls up the fully visible classification in the bvh.
-	*/
-	void UpdateFullVisibility(BvhNode *node) const;
 	/** Pulls up the last visited classification in the bvh.
 	*/
-	void PullUpLastVisited(BvhNode *node, const int frameId) const;
+	void PullUpLastVisited(BvhNode *node, int frameId) const;
 	/** Resets the node classifications in the tree.
 	*/
@@ -465,8 +501,5 @@
 		wireframes for visualization purpose.
 	*/
-	void RenderBoundingBoxesForViz(const int mode);
-	/** Returns squared min distance to the view point.
-	*/
-	float GetSquareDistance(BvhNode *node) const;
+	//void RenderBoundingBoxesForViz(int mode);
 	/** Count triangles the node contains.
 	*/
@@ -477,42 +510,28 @@
 
 
-	////////////
-	//-- functions that change the boundaries of the nodes
-
-	void SetUseTighterBoundsForTests(bool tighterBoundsForTests);
-
-	void SetAreaRatioThresholdForTestingChildren(const float ratio);
-
-
+	////////
+	//-- functions influencing tighter bounds
+
+
+	/** Sets maximal depth for taking the bounding boxes to test the
+		visibility of a node. 
+		Deeper => the bounds adapt more to the geometry.
+	*/
+	void SetMaxDepthForTestingChildren(int maxDepth);
+
+	void SetAreaRatioThresholdForTestingChildren(float ratio);
+
+	/** Returns stats.
+	*/
 	const BvhStats &GetBvhStats() const {return mBvhStats;}
-
-	void SetCollectTighterBoundsWithMaxLevel(bool t);
-
-
-	//////////////
-
-	static unsigned int sCurrentVboId;
 	
 
 protected:
 
-	/** Small struct representing a frustum.
-	*/
-	struct Frustum
-	{
-		/// the 6 clip planes
-		float mClipPlane[6][4];
-	};
-	
-
-
 	////////////////////
 
-	/** Constructor loading the bvh from disc
-	*/
-	Bvh(const std::string &filename);
 	/** protected constructor: do nothing.
 	*/
-	//Bvh(): mCamera(NULL), mFrameId(-1), mVertices(NULL), mRenderer(NULL) {}
+	Bvh();
 	/** Destructor.
 	*/
@@ -534,9 +553,4 @@
 	void RenderBoundingBoxesWithDrawArrays(int numNodes);
 
-	int RenderBoundingBoxesImmediate(const BvhNodeContainer &nodes);
-	/** Renders a bounding box in immediate mode using index restart
-		and restarts the strip only if wished.
-	*/
-	void RenderBoundingBoxImmediate(const AxisAlignedBox3 &box, bool restartStrip);
 	/** Create the indices that each node needs to use vbo rendering.
 	*/
@@ -550,6 +564,6 @@
 	*/
 	void UpdateInteriors(BvhNode *node);
-	/** Recomputes the boundaries of the nodes. This function is always called if
-		some boundary options are changed.
+	/** Recomputes the boundaries of the nodes. 
+	    This function is always called if some boundary options are changed.
 	*/
 	void RecomputeBounds();
@@ -558,12 +572,5 @@
 	*/
 	int PostProcessLeaves(BvhLeafContainer &leaves);
-
-
-	int	IsWithinViewFrustumLocal(BvhNode *node);
-
-	int	IsWithinViewFrustum(const AxisAlignedBox3 &box, int planeMask, int preferredPlane);
-	
-	float GetMinSquareDistance(const AxisAlignedBox3 &box) const;
-	
+		
 	
 	////////////////////////
@@ -572,5 +579,5 @@
 	BvhNode *mRoot;
 	/// pointers to the geometry associated with this node
-	SceneGeometry **mGeometry;
+	SceneEntity **mGeometry;
 	/// #of entities
 	size_t mGeometrySize;
@@ -579,9 +586,4 @@
 	////////////////
 
-
-	/// these values are valid for all nodes
-	char mClipPlaneAABBVertexIndices[6][2];
-	/// the current view frustum
-	Frustum mFrustum;
 	/// the current camera
 	Camera *mCamera;
@@ -589,5 +591,5 @@
 	int mFrameId;
 	/// a vertex array used if working with indexed arrays (without vbo)
-	//Point3f *mVertices;
+	Vector3 *mVertices;
 	/// indices used for draw array rendering
 	unsigned int *mIndices;
@@ -599,9 +601,9 @@
 
 	float mAreaRatioThreshold;
-	float mVolRatioThreshold;
+
 
 	BvhStats mBvhStats;
 
-	//HierarchyNodeContainer mTestNodes;
+	BvhNodeContainer mTestNodes;
 	
 	unsigned int *mTestIndices;
@@ -609,9 +611,10 @@
 	int mCurrentIndicesPtr;
 
-	float mScale;
-
-	Vector3 mNearPlane;
-	float mNearPlaneD;
 	int mNumNodes;
+
+
+	//////////////
+
+	static unsigned int sCurrentVboId;
 };
 
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.h	(revision 2751)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Plane3.h	(revision 2755)
@@ -1,6 +1,7 @@
-#ifndef _Plane3_H__
-#define _Plane3_H__
+#ifndef __Plane3_H__
+#define __Plane3_H__
 
 #include "Vector3.h"
+
 
 namespace CHCDemo 
@@ -15,15 +16,18 @@
 	Plane3() {}
 
+	Plane3(Vector3 &normal, float dist);
+
 	Plane3(const Vector3 &a, const Vector3 &b, const Vector3 &c);
 
 	Plane3(const Vector3 &normal, const Vector3 &point);
 
-	void ReverseOrientation()
+	inline void ReverseOrientation()
 	{
 		mNormal *= -1;
 		mD *= -1;
 	}
-
-	float Distance(const Vector3 &v) const 
+	/** Get disance to point.
+	*/
+	inline float Distance(const Vector3 &v) const 
 	{
 		return DotProd(v, mNormal) + mD;
@@ -31,5 +35,4 @@
 
 	enum {BACK_SIDE = -1, INTERSECTS = 0, FRONT_SIDE = 1};
-
 	/** Returns 1 if v is on front side, -1 if on back side, 0 if on plane.
 	*/
@@ -52,5 +55,5 @@
 
 
-	//////////////////
+	///////////
 	//-- friends
 
@@ -61,5 +64,5 @@
 	friend std::ostream &operator<<(std::ostream &s, const Plane3 &p) 
 	{	
-		s<<p.mNormal<<" "<<p.mD;
+		s << p.mNormal << " " << p.mD;
 		return s;
 	}
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.cpp	(revision 2753)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/Camera.cpp	(revision 2755)
@@ -1,5 +1,5 @@
 #include "common.h"
 #include "Camera.h"
-
+#include "glInterface.h"
 
 
@@ -70,4 +70,86 @@
 }
 
+
+void Camera::GetProjectionMatrix(Matrix4x4 &mat)
+{
+	//float m[16];
+	
+	glGetFloatv(GL_PROJECTION_MATRIX, (float *)mat.x);
+	//mat = Matrix4x4((const float *)m);
 }
 
+
+void Camera::GetModelViewMatrix(Matrix4x4 &mat)
+{
+	//float m[16];
+
+	glGetFloatv(GL_MODELVIEW_MATRIX, (float *)mat.x);
+	//mat = Matrix4f((const float *)m);
+}
+
+
+void Camera::CalcFrustum(Frustum &frustum)
+{
+	// we grab the plane equations of the six clipplanes of the viewfrustum
+	Matrix4x4 matViewing, matProjectionView;
+
+	GetModelViewMatrix(matViewing);
+	GetProjectionMatrix(matProjectionView);
+
+	matProjectionView *= matViewing;
+
+	
+	float fInvLength;
+
+	float planes[6][4];
+
+	//////////
+	//-- extract the plane equations
+
+	for (int i = 0; i < 4; ++ i)
+	{
+		planes[0][i] = matProjectionView.x[i][3] - matProjectionView.x[i][0]; // right plane
+		planes[1][i] = matProjectionView.x[i][3] + matProjectionView.x[i][0]; // left plane
+		planes[2][i] = matProjectionView.x[i][3] + matProjectionView.x[i][1]; // bottom plane
+		planes[3][i] = matProjectionView.x[i][3] - matProjectionView.x[i][1]; // top plane
+		planes[4][i] = matProjectionView.x[i][3] - matProjectionView.x[i][2]; // far plane
+		planes[5][i] = matProjectionView.x[i][3] + matProjectionView.x[i][2]; // near plane
+	}
+
+
+	////////////
+	//-- normalize the coefficients
+
+	for (int i = 0; i < 6; ++ i)
+	{
+		// the clipping planes look outward the frustum,
+		// so distances > 0 mean that a point is outside
+		fInvLength	= -1.0f / sqrt(planes[i][0] * planes[i][0] +	
+								   planes[i][1] * planes[i][1] +	
+								   planes[i][2] * planes[i][2]);
+
+		planes[i][0] *= fInvLength;
+		planes[i][1] *= fInvLength;
+		planes[i][2] *= fInvLength;
+		planes[i][3] *= fInvLength;
+
+		Vector3 normal(planes[i][0], planes[i][1], planes[i][2]);
+		frustum.mClipPlanes[i] = Plane3(normal, planes[i][3]);
+	}
+}
+
+
+void Camera::Frustum::CalcNPVertexIndices(int *indices)
+{
+	for (int i = 0; i < 6; ++ i)
+	{
+		// n-vertex
+		indices[i * 2 + 0] = AxisAlignedBox3::GetIndexNearestVertex(mClipPlanes[i].mNormal);
+		// p-vertex
+		indices[i * 2 + 1] = AxisAlignedBox3::GetIndexFarthestVertex(mClipPlanes[i].mNormal);	
+	}
+}
+
+
+}
+
Index: GTP/trunk/App/Demos/Vis/CHC_revisited/common.h
===================================================================
--- GTP/trunk/App/Demos/Vis/CHC_revisited/common.h	(revision 2754)
+++ GTP/trunk/App/Demos/Vis/CHC_revisited/common.h	(revision 2755)
@@ -25,4 +25,6 @@
 class BvhLeaf;
 class OcclusionQuery;
+class SceneEntity;
+
 
 
@@ -465,4 +467,5 @@
 
 typedef std::vector<BvhNode *> BvhNodeContainer;
+typedef std::vector<SceneEntity *> SceneEntityContainer;
 typedef std::vector<BvhLeaf *> BvhLeafContainer;
 typedef std::vector<Triangle3> TriangleContainer;
