Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h	(revision 3042)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.h	(revision 3070)
@@ -34,5 +34,9 @@
 	*/
 	SceneEntity(Transform3 *trafo);
-
+	/** Copy constructur.
+	*/
+	//SceneEntity(const SceneEntity &trafo);
+	/** Destructor.
+	*/
 	virtual ~SceneEntity();
 	/** Renders this node.
@@ -64,10 +68,10 @@
 	*/
 	int CountNumTriangles(int lodLevel = -1);
-	/** Returns the bounding box.
+	/** Returns the local bounding box.
 	*/
 	AxisAlignedBox3 GetBoundingBox() const;
 	/** Returns the transformed bounding box.
 	*/
-	AxisAlignedBox3 GetTransformedBoundingBox() const;
+	AxisAlignedBox3 GetWorldBoundingBox() const;
 	
 
@@ -84,5 +88,5 @@
 	/** Adds a new lod level.
 	*/
-	void AddLODLevel(LODLevel *lod) { mLODLevels.push_back(lod); }
+	void AddLODLevel(const LODLevel &lod) { mLODLevels.push_back(lod); }
 	/** Returns numbers of lod levels.
 	*/
@@ -90,5 +94,5 @@
 	/** Returns transformed center point of this shape.
 	*/
-	Vector3 GetCenter() const;
+	Vector3 GetWorldCenter() const;
 	/** If false, the highest (most detailed) LOD level is used for all entities.
 	*/
@@ -111,5 +115,5 @@
 	Transform3 *mTransform;
 	/// Stores information about the LOD levels
-	LODLevelContainer mLODLevels;
+	LODLevelArray mLODLevels;
 	/// the renderable shapes
 	ShapeContainer mShapes;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Transform3.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Transform3.h	(revision 3061)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Transform3.h	(revision 3070)
@@ -3,8 +3,5 @@
 
 #include "Matrix4x4.h"
-#include "glInterface.h"
 #include "common.h"
-#include <Cg/cg.h>
-#include <Cg/cgGL.h>
 
 
@@ -49,6 +46,4 @@
 	inline bool IsIdentity() const { return mIsIdentity; }
 
-	static CGparameter sModelMatrixParam;
-
 
 protected:
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.cpp	(revision 3066)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/RenderTraverser.cpp	(revision 3070)
@@ -157,4 +157,6 @@
 	// add root node to queue
 	EnqueueNode(mBvh->GetRoot());
+	// add dynamic root
+	EnqueueNode(mBvh->GetDynamicRoot());
 
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.h	(revision 2951)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.h	(revision 3070)
@@ -65,6 +65,9 @@
 
 	float Size(const int axis) const;
-
-	// Read-only const access tomMin and max vectors using references
+	/** Returns axis where box has largest extent.
+	*/
+	int MajorAxis() const;
+	/** Read-only const access tomMin and max vectors using references
+	*/
 	const Vector3& Min() const;
 	const Vector3& Max() const;
@@ -91,7 +94,7 @@
 	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
-	// when unbounded objects such as quadric surfaces are included.
+	/** Return whether the box is unbounded.  Unbounded boxes appear
+		when unbounded objects such as quadric surfaces are included.
+	*/
 	bool Unbounded() const;
 
@@ -127,5 +130,6 @@
 	*/
 	void Scale(float scale);
-
+	/** Scale box non-uniformally
+	*/
 	void Scale(const Vector3 &scale);
 	/** Translates the box with the factor.
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.cpp	(revision 3054)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.cpp	(revision 3070)
@@ -53,5 +53,5 @@
 
 
-AxisAlignedBox3 Shape::GetTransformedBoundingBox() const
+AxisAlignedBox3 Shape::GetWorldBoundingBox() const
 {
 	if (mParent->GetTransform()->IsIdentity())
@@ -64,5 +64,5 @@
 
 
-Vector3 Shape::GetCenter() const
+Vector3 Shape::GetWorldCenter() const
 {
 	if (mParent->GetTransform()->IsIdentity())
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhLoader.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhLoader.cpp	(revision 3069)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhLoader.cpp	(revision 3070)
@@ -130,6 +130,6 @@
 
 	// compute and print stats
-	bvh->ComputeBvhStats();
-	bvh->PrintBvhStats();
+	bvh->ComputeBvhStats(bvh->mRoot, bvh->mBvhStats);
+	bvh->PrintBvhStats(bvh->mBvhStats);
 
 	return bvh;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/EntityMerger.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/EntityMerger.cpp	(revision 2980)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/EntityMerger.cpp	(revision 3070)
@@ -30,7 +30,7 @@
 	Shape *shape = MergeShapes(shape1, shape2, ent);
 	
-	LODLevel *lodLevel = new LODLevel(0);
+	LODLevel lodLevel(0);
 
-	lodLevel->AddShape(shape);
+	lodLevel.AddShape(shape);
 	ent->AddLODLevel(lodLevel);
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 3058)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.cpp	(revision 3070)
@@ -51,5 +51,5 @@
 	CLEAR_CONTAINER(mTrafos);
 	CLEAR_CONTAINER(mShapes);
-	CLEAR_CONTAINER(mLODs);
+	//CLEAR_CONTAINER(mLODs);
 }
 
@@ -103,5 +103,6 @@
 		str.read(reinterpret_cast<char *>(&numShapes), sizeof(int));
 
-		LODLevel *lodLevel = new LODLevel(dist);
+		//LODLevel *lodLevel = new LODLevel(dist);
+		LODLevel lodLevel(dist);
 
 		for (int j = 0; j < numShapes; ++ j)
@@ -119,8 +120,8 @@
 
 			sceneGeom->AddShape(shape);
-			lodLevel->AddShape(shape);
+			lodLevel.AddShape(shape);
 		}
 
-		mLODs.push_back(lodLevel);
+		//mLODs.push_back(lodLevel);
 		sceneGeom->AddLODLevel(lodLevel);
 	}
@@ -407,4 +408,18 @@
 }
 
-}
-
+
+void ResourceManager::AddSceneEntity(SceneEntity *ent)
+{
+	mSceneEntities.push_back(ent);
+}
+
+
+Transform3 *ResourceManager::CreateTransform(const Matrix4x4 &m)
+{
+	Transform3 *t = new Transform3(m);
+
+	mTrafos.push_back(t);
+	return t;
+}
+
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntityConverter.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntityConverter.cpp	(revision 3023)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntityConverter.cpp	(revision 3070)
@@ -46,7 +46,7 @@
 	ent->AddShape(shape);
 
-	LODLevel *lodLevel = new LODLevel(0);
+	LODLevel lodLevel(0);
 
-	lodLevel->AddShape(shape);
+	lodLevel.AddShape(shape);
 	ent->AddLODLevel(lodLevel);
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.h	(revision 3065)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.h	(revision 3070)
@@ -478,16 +478,21 @@
 	struct BvhStats
 	{
-		BvhStats(): 
-		mInteriorSA(0),
-		mLeafSA(0),
-		mInteriorVol(0),
-		mLeafVol(0),
-		mTriangles(0),
-		mTriangleRatio(0),
-		mGeometryRatio(0),
-		mMaxGeometry(0),
-		mMaxTriangles(0)
-		{}
-		
+		BvhStats() { Reset(); }
+
+		void Reset() 
+		{
+			mInteriorSA = .0f;
+			mLeafSA = .0f;
+			mInteriorVol = .0f;
+			mLeafVol = .0f;
+			mTriangleRatio = .0f;
+			mGeometryRatio = .0f;
+
+			mTriangles = 0;
+			mLeaves = 0;
+		}
+
+		///////////////////
+
 		float mInteriorSA;
 		float mLeafSA;
@@ -495,11 +500,9 @@
 		float mLeafVol; 
 		
-		int mTriangles;
-
 		float mTriangleRatio;
 		float mGeometryRatio;
 
-		int mMaxGeometry;
-		int mMaxTriangles;
+		int mTriangles;
+		int mLeaves;
 	};
 
@@ -525,4 +528,6 @@
 	*/
 	inline BvhNode *GetRoot();
+
+	inline BvhNode *GetDynamicRoot();
 	/** Returns the bounding box of this bvh.
 	*/
@@ -643,5 +648,6 @@
 	void RenderBoundsForViz(BvhNode *node, RenderState *state, bool useTightBounds);
 
-	void AddDynamicObject(SceneEntity *ent);
+	void AddDynamicObjects(const SceneEntityContainer &entities);
+
 
 
@@ -661,7 +667,10 @@
 
 	/////////////
-
-	void ComputeBvhStats();
-	void PrintBvhStats() const;
+	/** Traverse hierarchy and compute stats.
+	*/
+	void ComputeBvhStats(BvhNode *root, BvhStats &bvhStats);
+	/** Output the bvh statistics.
+	*/
+	void PrintBvhStats(const BvhStats &bvhStats) const;
 
 
@@ -712,17 +721,16 @@
 	int SortTriangles(BvhLeaf *leaf, 
 		              int axis, 
-					  float position,
-					  SceneEntityContainer &entities);
+					  float position);
 
 	int SortTrianglesSpatialMedian(BvhLeaf *leaf, 
-		                           int axis,
-								   SceneEntityContainer &entities);
+		                           int axis);
 
 	BvhNode *SubdivideLeaf(BvhLeaf *leaf, 
-		                   int parentAxis, 
-						   SceneEntityContainer &entities);
+		                   int parentAxis);
 	/** Recompute the dynamic branch of the hierarchy.
 	*/
-	void UpdateDynamicBranch();
+	void CreateDynamicBranch();
+
+	void UpdateDynamicBranch(BvhNode *node);
 
 	inline bool TerminationCriteriaMet(BvhLeaf *leaf) const;
@@ -830,4 +838,10 @@
 
 
+BvhNode *Bvh::GetDynamicRoot()
+{ 
+	return mDynamicRoot; 
+}
+
+
 const AxisAlignedBox3 &Bvh::GetBox() const 
 { 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Triangle3.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Triangle3.cpp	(revision 2957)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Triangle3.cpp	(revision 3070)
@@ -49,5 +49,5 @@
 
 
-Vector3 Triangle3::GetCenter() const 
+Vector3 Triangle3::GetWorldCenter() const 
 {
 	return (mVertices[0] + mVertices[1] + mVertices[2]) / 3.0f;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 3057)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SkyPreetham.cpp	(revision 3070)
@@ -157,5 +157,5 @@
 void SkyPreetham::RenderSunDisk(const Vector3 &sunDir, Camera *camera)
 {
-#if TODOD
+#if TODO
 	// Move skybox with camera.
 	Vector3 position = camera->GetPosition();
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.h	(revision 3061)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Shape.h	(revision 3070)
@@ -52,5 +52,5 @@
 	/** Returns bounding box transformed with the parent transform.
 	*/
-	AxisAlignedBox3 GetTransformedBoundingBox() const;
+	AxisAlignedBox3 GetWorldBoundingBox() const;
 	/** Returns material of this shape.
 	*/
@@ -58,5 +58,5 @@
 	/** Returns transformed center point of this shape.
 	*/
-	Vector3 GetCenter() const;
+	Vector3 GetWorldCenter() const;
 
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp	(revision 3069)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Bvh.cpp	(revision 3070)
@@ -151,4 +151,18 @@
 
 
+
+inline AxisAlignedBox3 ComputeBoundingBox(SceneEntity **entities, int numEntities)
+{
+	AxisAlignedBox3 box = entities[0]->GetWorldBoundingBox();
+
+	for (int i = 1; i < numEntities; ++ i)
+	{
+		box.Include(entities[i]->GetWorldBoundingBox());
+	}
+
+	return box;
+}
+
+
 Bvh::Bvh()
 {
@@ -419,5 +433,8 @@
 	if (!mDynamicEntities.empty())
 	{
-		UpdateDynamicBranch();
+		if (!mDynamicRoot)
+			CreateDynamicBranch();
+		
+		UpdateDynamicBranch(mDynamicRoot);
 	}
 }
@@ -448,5 +465,5 @@
 	{
 		SceneEntity *ent = entities[i];
-		float dist = ent->GetTransformedBoundingBox().GetMaxDistance(sNearPlane);
+		float dist = ent->GetWorldBoundingBox().GetMaxDistance(sNearPlane);
 
 		if (dist > maxDist) maxDist = dist;
@@ -800,10 +817,12 @@
 
 
-void Bvh::ComputeBvhStats() 
-{
+void Bvh::ComputeBvhStats(BvhNode *root, BvhStats &bvhStats) 
+{
+	bvhStats.Reset();
 	std::stack<BvhNode *> nodeStack;
-	nodeStack.push(mRoot);
+	nodeStack.push(root);
 
 	int numVirtualLeaves = 0;
+	int numGeometry = 0;
 
 	while (!nodeStack.empty()) 
@@ -815,15 +834,16 @@
 		{
 			++ numVirtualLeaves;
+			numGeometry += node->CountPrimitives();
 
 			BvhLeaf *leaf = static_cast<BvhLeaf *>(node);
 
-			mBvhStats.mTriangles += CountTriangles(leaf);
-			mBvhStats.mLeafSA += leaf->mBox.SurfaceArea();
-			mBvhStats.mLeafVol += leaf->mBox.GetVolume();
+			bvhStats.mTriangles += CountTriangles(leaf);
+			bvhStats.mLeafSA += leaf->mBox.SurfaceArea();
+			bvhStats.mLeafVol += leaf->mBox.GetVolume();
 		} 
 		else 
 		{
-			mBvhStats.mInteriorSA += node->mBox.SurfaceArea();
-			mBvhStats.mInteriorVol += node->mBox.GetVolume();
+			bvhStats.mInteriorSA += node->mBox.SurfaceArea();
+			bvhStats.mInteriorVol += node->mBox.GetVolume();
 
 			BvhInterior *interior = static_cast<BvhInterior *>(node);
@@ -834,20 +854,21 @@
 	}
 
-	mBvhStats.mGeometryRatio = mGeometrySize / (float)numVirtualLeaves;
-	mBvhStats.mTriangleRatio = mBvhStats.mTriangles / (float)numVirtualLeaves;
-}
-
-
-void Bvh::PrintBvhStats() const
-{
-	cout << "\n******** 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 << "geometry per leaf: " <<  mBvhStats.mGeometryRatio << endl;
-	cout << "triangles per leaf: " <<  mBvhStats.mTriangleRatio << endl;
-	cout << "**************" << endl << endl;
+	bvhStats.mGeometryRatio = (float)numGeometry / numVirtualLeaves;
+	bvhStats.mTriangleRatio = (float)bvhStats.mTriangles / numVirtualLeaves;
+	bvhStats.mLeaves = numVirtualLeaves;
+}
+
+
+void Bvh::PrintBvhStats(const BvhStats &bvhStats) const
+{
+	cout << "\n============ BVH statistics =============" << endl;
+	cout << "interiorNodesSA = " << bvhStats.mInteriorSA / mRoot->mBox.SurfaceArea() << endl;
+	cout << "leafNodesSA = " << bvhStats.mLeafSA / mRoot->mBox.SurfaceArea() << endl;
+	cout << "interiorNodesVolume = " << bvhStats.mInteriorVol / mRoot->mBox.GetVolume() << endl;
+	cout << "leafNodesVolume = " << bvhStats.mLeafVol / mRoot->mBox.GetVolume() << endl;
+
+	cout << "geometry per leaf: " << bvhStats.mGeometryRatio << endl;
+	cout << "triangles per leaf: " << bvhStats.mTriangleRatio << endl;
+	cout << "===========================================" << endl << endl;
 }
 
@@ -1155,17 +1176,23 @@
 int Bvh::SortTriangles(BvhLeaf *leaf, 
 					   int axis, 
-					   float position,
-					   SceneEntityContainer &entities)
+					   float position
+					   )
 {
 	int i = leaf->mFirst;
 	int j = leaf->mLast;
 
-    while (1) 
-	{
-		while (entities[i]->GetCenter()[axis] < position) 
+    while (1)
+	{
+		while (mGeometry[i]->GetWorldCenter()[axis] < position) 
+		{
+			//cout<<" i " << i << " " << mGeometry[i]->GetWorldCenter()[axis];
 			++ i;
-	
-		while (position < entities[j]->GetCenter()[axis])
+		}
+
+		while (position < mGeometry[j]->GetWorldCenter()[axis])
+		{
+			//cout<< axis << " j " << j << " " << mGeometry[j]->GetWorldCenter()[axis] << " " << position<< " ";
 			-- j;
+		}
 
 		// sorting finished
@@ -1173,5 +1200,5 @@
 
 		// swap entities
-		swap(entities[i], entities[j]);
+		swap(mGeometry[i], mGeometry[j]);
 			
 		++ i;
@@ -1184,35 +1211,38 @@
 
 int Bvh::SortTrianglesSpatialMedian(BvhLeaf *leaf, 
-									int axis,
-									SceneEntityContainer &entities)
+									int axis
+									)
 {
 	// spatial median
 	float m = leaf->mBox.Center()[axis];
-	return SortTriangles(leaf, axis, m, entities);
+	//cout << "here3 " << leaf->mBox << " " << leaf->mFirst << " " << leaf->mLast << endl;
+	return SortTriangles(leaf, axis, m);
 }
 
 
 BvhNode *Bvh::SubdivideLeaf(BvhLeaf *leaf, 
-							int parentAxis, 
-							SceneEntityContainer &entities)
+							int parentAxis
+							)
 {
 	if (TerminationCriteriaMet(leaf))
 	{
 		leaf->mIsVirtualLeaf = true;
+		leaf->mIsMaxDepthForVirtualLeaf = true;
 		return leaf;
 	}
 
-	//int axis = leaf->mBox.MajorAxis();
-	int axis = (parentAxis + 1) % 3;
+	//const int axis = (parentAxis + 1) % 3;
+	const int axis = leaf->mBox.MajorAxis();
+	
+
+	const int scale = 20;
 
 	// 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
-	split = SortTrianglesSpatialMedian(leaf, axis, entities);
+	split = SortTrianglesSpatialMedian(leaf, axis);
 	pos = leaf->mBox.Center()[axis];
 	
@@ -1247,9 +1277,12 @@
 	
 	// reset box
-	leaf->mBox.Initialize();
+	//leaf->mBox.Initialize();
+
+	front->mBox = ComputeBoundingBox(mGeometry + front->mFirst, front->CountPrimitives());
+	leaf->mBox = ComputeBoundingBox(mGeometry + leaf->mFirst, leaf->CountPrimitives());
 
 	// recursively continue subdivision
-	parent->mBack = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mBack), axis, entities);
-	parent->mFront = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mFront), axis, entities);
+	parent->mBack = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mBack), axis);
+	parent->mFront = SubdivideLeaf(static_cast<BvhLeaf *>(parent->mFront), axis);
 	
 	return parent;
@@ -1267,5 +1300,29 @@
 
 
-void Bvh::UpdateDynamicBranch()
+void Bvh::UpdateDynamicBranch(BvhNode *node)
+{
+	if (node->IsLeaf())
+	{
+		int numEntities;
+		SceneEntity **entities = GetGeometry(node, numEntities);
+
+		node->mBox = ComputeBoundingBox(entities, numEntities);
+		//cout << "box: " << node->mBox << endl;
+	}
+	else
+	{
+		BvhNode *f = static_cast<BvhInterior *>(node)->GetFront();
+		BvhNode *b = static_cast<BvhInterior *>(node)->GetBack();
+
+		UpdateDynamicBranch(f);
+		UpdateDynamicBranch(b);
+
+		node->mBox = f->mBox;
+		node->mBox.Include(b->mBox);
+	}
+}
+
+
+void Bvh::CreateDynamicBranch()
 {
 	// the bvh has two main branches
@@ -1278,27 +1335,63 @@
 	// the movements of the objects within
 
-	// delete old branch
-	cout << "deleting old branch" << endl;
-
 	DEL_PTR(mDynamicRoot);
 
-	mDynamicRoot = new BvhLeaf(mRoot);
-	mDynamicRoot->mBox = mRoot->mBox;
-
-	mDynamicRoot->mFirst = 0;
-	mDynamicRoot->mLast = (int)mDynamicEntities.size() - 1;
-	mDynamicRoot->mArea = mDynamicRoot->mBox.SurfaceArea();
-	
-	cout << "updating dynamic branch" << endl;
-
-	mDynamicRoot = SubdivideLeaf(static_cast<BvhLeaf *>(mDynamicRoot), 0, mDynamicEntities);
-
-	cout << "finished updating dynamic branch" << endl;
-}
-
-
-void Bvh::AddDynamicObject(SceneEntity *ent)
-{
-	mDynamicEntities.push_back(ent);
+	BvhLeaf *l = new BvhLeaf(mRoot);
+
+	l->mBox.Initialize();
+
+	SceneEntityContainer::const_iterator sit, sit_end = mDynamicEntities.end();
+
+	for (sit = mDynamicEntities.begin(); sit != sit_end; ++ sit)
+	{
+		l->mBox.Include((*sit)->GetWorldBoundingBox());
+	}
+
+	l->mFirst = (int)(mGeometrySize - mDynamicEntities.size());
+	l->mLast = (int)mGeometrySize - 1;
+	l->mArea = l->mBox.SurfaceArea();
+	
+	cout << "updating dynamic branch " << l->mFirst << " " << l->mLast << endl;
+
+	mDynamicRoot = SubdivideLeaf(l, 0);
+
+	BvhStats bvhStats;
+	ComputeBvhStats(mDynamicRoot, bvhStats);
+
+	cout << "\n=========== Dynamic BVH statistics: =========" << endl;
+	cout << "leaves = " << bvhStats.mLeaves << endl;
+	cout << "interiorNodesSA = " << bvhStats.mInteriorSA << endl;
+	cout << "leafNodesSA = " << bvhStats.mLeafSA << endl;
+	cout << "interiorNodesVolume = " << bvhStats.mInteriorVol  << endl;
+	cout << "leafNodesVolume = " << bvhStats.mLeafVol << endl;
+
+	cout << "geometry per leaf: " << bvhStats.mGeometryRatio << endl;
+	cout << "triangles per leaf: " << bvhStats.mTriangleRatio << endl;
+	cout << "=============================================" << endl << endl;
+}
+
+
+void Bvh::AddDynamicObjects(const SceneEntityContainer &entities)
+{
+	// copy old entities
+	SceneEntity **newGeom = new SceneEntity*[mGeometrySize + (int)entities.size()];
+
+	memcpy(newGeom, mGeometry, mGeometrySize * sizeof(SceneEntity *));
+
+	delete [] mGeometry;
+	mGeometry = newGeom;
+
+	// now add new entities
+	SceneEntityContainer::const_iterator it, it_end = entities.end();
+
+	size_t i = mGeometrySize;
+	for (it = entities.begin(); it != it_end; ++ it, ++ i)
+	{
+		mGeometry[i] = (*it);
+		mDynamicEntities.push_back(*it);
+	}
+
+
+	mGeometrySize += entities.size();
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.h	(revision 3057)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ResourceManager.h	(revision 3070)
@@ -50,4 +50,11 @@
 	*/
 	static void DelSingleton();
+	/** Adds a scene entity to be handled by the resource mananger.
+	*/
+	void AddSceneEntity(SceneEntity *ent);
+	/** Adds a scene entity to be handled by the resource mananger.
+	*/
+	Transform3 *CreateTransform(const Matrix4x4 &m);
+
 
 protected:
@@ -83,5 +90,5 @@
 	TransformContainer mTrafos;
 	ShapeContainer mShapes;
-	LODContainer mLODs;
+	//LODContainer mLODs;
 	/// the scene entities
 	SceneEntityContainer mSceneEntities;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.cpp	(revision 3034)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/SceneEntity.cpp	(revision 3070)
@@ -39,5 +39,5 @@
 	if (!sUseLODs) return;
 
-	const Vector3 pos = GetCenter();
+	const Vector3 pos = GetWorldCenter();
 
 	const float dist = SqrDistance(pos, viewPoint);
@@ -48,7 +48,5 @@
 	for (int i = 0; i < l; ++ i)
 	{
-		LODLevel *lod = mLODLevels[i];
-
-		if (lod->GetSquaredDistance() > dist)
+		if (mLODLevels[i].GetSquaredDistance() > dist)
 			break;
 
@@ -79,6 +77,6 @@
 	}
 
-	start = mLODLevels[mCurrentLODLevel]->GetShapes().begin(); 
-	end   = mLODLevels[mCurrentLODLevel]->GetShapes().end();
+	start = mLODLevels[mCurrentLODLevel].GetShapes().begin(); 
+	end   = mLODLevels[mCurrentLODLevel].GetShapes().end();
 }
 
@@ -88,8 +86,6 @@
 							  ShapeContainer::iterator &end)
 {
-	LODLevel *lod = mLODLevels[level];
-
-	start = lod->GetShapes().begin();
-	end = lod->GetShapes().end();
+	start = mLODLevels[level].GetShapes().begin();
+	end = mLODLevels[level].GetShapes().end();
 }
 
@@ -99,5 +95,10 @@
 	ShapeContainer::iterator sit, sit_end;
 
-	GetCurrentLODLevel(sit, sit_end);
+	if (!mLODLevels.empty())
+		GetCurrentLODLevel(sit, sit_end);
+	else
+	{
+		sit = mShapes.begin(); sit_end = mShapes.end();
+	}
 
 	for (; sit != sit_end; ++ sit)
@@ -146,9 +147,9 @@
 	}
 
-	return mLODLevels[lodLevel]->GetNumTriangles();
+	return mLODLevels[lodLevel].GetNumTriangles();
 }
 
 
-AxisAlignedBox3 SceneEntity::GetTransformedBoundingBox() const
+AxisAlignedBox3 SceneEntity::GetWorldBoundingBox() const
 {
 	if (mTransform->IsIdentity()) return mBox;
@@ -166,12 +167,10 @@
 
 
-Vector3 SceneEntity::GetCenter() const
+Vector3 SceneEntity::GetWorldCenter() const
 {
 	if (mTransform->IsIdentity())
 		return mCenter;
 
-	Matrix4x4 mat = mTransform->GetMatrix();
-
-	return mat * mCenter;
+	return mTransform->GetMatrix() *  mCenter;
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Triangle3.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Triangle3.h	(revision 2957)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Triangle3.h	(revision 3070)
@@ -21,5 +21,5 @@
 	Vector3 GetNormal() const;
 
-	Vector3 GetCenter() const;
+	Vector3 GetWorldCenter() const;
 
 	float GetSpatialAngle(const Vector3 &point) const;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Transform3.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Transform3.cpp	(revision 3034)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Transform3.cpp	(revision 3070)
@@ -7,5 +7,9 @@
 {
 
-CGparameter Transform3::sModelMatrixParam;
+
+Transform3::Transform3()
+{
+	Reset();
+}
 
 
@@ -13,10 +17,4 @@
 {
 	mIsIdentity = false;
-}
-
-
-Transform3::Transform3()
-{
-	Reset();
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3068)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3070)
@@ -71,4 +71,5 @@
 /// the renderable scene geometry
 SceneEntityContainer sceneEntities;
+SceneEntityContainer dynamicObjects;
 // traverses and renders the hierarchy
 RenderTraverser *traverser = NULL;
@@ -289,5 +290,5 @@
 void PrepareRenderQueue();
 /// loads the specified model
-void LoadModel(const string &model);
+void LoadModel(const string &model, SceneEntityContainer &entities);
 
 inline float KeyRotationAngle() { return keyRotation * elapsedTime * 1e-3f; }
@@ -450,5 +451,5 @@
 	//-- load the static scene geometry
 
-	LoadModel("city.dem");
+	LoadModel("city.dem", sceneEntities);
 
 
@@ -478,5 +479,5 @@
 	//-- setup the skydome model
 
-	LoadModel("sky.dem");
+	LoadModel("sky.dem", sceneEntities);
 	skyDome = sceneEntities.back();
 
@@ -494,23 +495,35 @@
 	visualization = new Visualization(bvh, camera, NULL, &state);
 
-
-	LoadModel("hbuddha.dem");
-	buddha = sceneEntities.back();
-
+	LoadModel("hbuddha.dem", dynamicObjects);
+	buddha = dynamicObjects.back();
+	dynamicObjects.clear();
 	Vector3 sceneCenter(470.398f, 240.364f, 182.5f);
 	Matrix4x4 transl = TranslationMatrix(sceneCenter);
-
 	buddha->GetTransform()->SetMatrix(transl);
 
-	bvh->AddDynamicObject(buddha);
-
+	Vector3 offs = Vector3::ZERO();
+
+	for (int i = 0; i < 10; ++ i)
+	{
+		SceneEntity *ent = new SceneEntity(*buddha);
+		resourceManager->AddSceneEntity(ent);
+
+		offs.x = RandomValue(.0f, 50.0f);
+		offs.y = RandomValue(.0f, 50.0f);
+
+		transl = TranslationMatrix(sceneCenter + offs);
+		Transform3 *transform = resourceManager->CreateTransform(transl);
+
+		ent->SetTransform(transform);
+		dynamicObjects.push_back(ent);
+	}
+	
+	bvh->AddDynamicObjects(dynamicObjects);
 
 	// this function assign the render queue bucket ids of the materials in beforehand
 	// => probably a little less overhead for new parts of the scene that are not yet assigned
 	PrepareRenderQueue();
-	
 	/// forward rendering is the default
 	state.SetRenderTechnique(FORWARD);
-
 	// frame time is restarted every frame
 	frameTimer.Start();
@@ -2004,9 +2017,9 @@
 
 
-void LoadModel(const string &model)
+void LoadModel(const string &model, SceneEntityContainer &entities)
 {
 	const string filename = string(model_path + model);
 
-	if (resourceManager->Load(filename, sceneEntities))
+	if (resourceManager->Load(filename, entities))
 		cout << "model " << filename << " loaded" << endl;
 	else
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.cpp	(revision 3065)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/AxisAlignedBox3.cpp	(revision 3070)
@@ -1505,4 +1505,17 @@
 
 
-}
-
+int AxisAlignedBox3::MajorAxis() const
+{
+	const Vector3 sizeVec = mMax - mMin;
+
+	int axis;
+
+	if (sizeVec.x > sizeVec.y) axis = (sizeVec.x > sizeVec.z) ? 0 : 2;
+	else axis = (sizeVec.y > sizeVec.z) ? 1 : 2;
+
+	return axis;
+}
+
+
+}
+
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h	(revision 3042)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/common.h	(revision 3070)
@@ -505,6 +505,7 @@
 typedef std::vector<ShaderProgram *> ShaderContainer;
 typedef std::vector<Technique *> TechniqueContainer;
+
 typedef std::vector<Vector3> VertexArray;
-
+typedef std::vector<LODLevel> LODLevelArray;
 
 typedef std::pair<float, float> Texcoord2;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/SimpleTri.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/SimpleTri.cpp	(revision 3012)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/SimpleTri.cpp	(revision 3070)
@@ -28,5 +28,5 @@
 
 
-SimpleVec SimpleTri::GetCenter() const 
+SimpleVec SimpleTri::GetWorldCenter() const 
 {
 	return (mVertices[0] + mVertices[1] + mVertices[2]) / 3.0f;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/SimpleTri.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/SimpleTri.h	(revision 3012)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/Converter/SimpleTri.h	(revision 3070)
@@ -15,5 +15,5 @@
 	SimpleVec GetNormal() const;
 
-	SimpleVec GetCenter() const;
+	SimpleVec GetWorldCenter() const;
 
 	float GetSpatialAngle(const SimpleVec &point) const;
