Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ViewCellsTree.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ViewCellsTree.cpp	(revision 3242)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ViewCellsTree.cpp	(revision 3242)
@@ -0,0 +1,115 @@
+#include "ViewCellsTree.h"
+#include "Timer/PerfTimer.h"
+#include <stack>
+
+using namespace std;
+
+
+namespace CHCDemoEngine
+{
+
+ViewCell *ViewCellsTree::GetViewCell(const Vector3 &point) const
+{
+	ViewCellsTreeNode *node = root;
+
+	while (!node->IsLeaf()) 
+	{
+		if (point[node->axis] < node->position)
+			node = node->back;
+		else
+			node = node->front;
+	}
+
+	return node->viewCell;
+}
+
+
+bool ViewCellsTree::LoadFromFile(const string &filename)
+{
+	cout << ("Info: Loading view cells from file '" + filename + "'" );
+
+	FILE *fr = fopen(filename.c_str(), "rb");
+
+	if (fr == NULL) {
+		Message("Error: Cannot open file for reading");
+		return false;
+	}
+
+	bool result = _LoadFromFile(fr);
+
+	Debug << "Info: done. " << endl;
+	fclose(fr);
+
+	return result;
+}
+
+
+bool ViewCellsTree::_LoadFromFile(FILE *fr)
+{
+	int buffer[256]; 
+	fread(buffer, sizeof(int), 3, fr);
+
+	if (buffer[0] != MAGIC) {
+		Message( "Error: Wrong file type");
+		return false;
+	}
+
+	if (buffer[1] != (int)(1000*VIEWCELLS_VERSION)) {
+		Message( "Error: Wrong viewcells version" );
+		return false;
+	}
+
+	// get the bounding box
+	fread(&box, sizeof(AxisAlignedBox3), 1, fr);
+
+	stack<ViewCellsTreeNode **> nodeStack;
+
+	nodeStack.push(&root);
+
+	while(!nodeStack.empty()) {
+		ViewCellsTreeNode *&node = *nodeStack.top();
+		nodeStack.pop();
+		node = new ViewCellsTreeNode;
+		fread(&node->axis, sizeof(int), 1, fr);
+		if (!node->IsLeaf()) {
+			fread(&node->position, sizeof(float), 1, fr);
+			nodeStack.push(&node->front);
+			nodeStack.push(&node->back);
+		}
+	}
+
+	return true;
+}
+
+
+void ViewCellsTree::_ExportToFile(FILE *file)
+{
+	int buffer[256];
+	int i=0;
+	buffer[i++] = MAGIC;
+	buffer[i++] = VIEWCELLS_VERSION*1000;
+
+	fwrite(buffer, sizeof(int), i, file);
+
+	fwrite(&mMaxDepth, sizeof(float), 1, file);
+
+	fwrite(&box, sizeof(AxisAlignedBox3), 1, file);
+
+	stack<ViewCellsTreeNode *> nodeStack;
+
+	nodeStack.push(root);
+
+	while (!nodeStack.empty()) {
+		ViewCellsTreeNode *node = nodeStack.top();
+		nodeStack.pop();
+
+		fwrite(&node->axis, sizeof(int), 1, file);
+		if (!node->IsLeaf()) {
+			fwrite(&node->position, sizeof(float), 1, file);
+			nodeStack.push(node->front);
+			nodeStack.push(node->back);
+		}
+	}
+}
+
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Pvs.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Pvs.h	(revision 3242)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Pvs.h	(revision 3242)
@@ -0,0 +1,152 @@
+#ifndef __PVS_H
+#define __PVS_H
+
+	
+namespace CHCDemoEngine
+{
+
+/** Template class representing the Potentially Visible Set (PVS) 
+	mainly from a view cell, but also e.g., from objects.
+*/
+class Pvs
+{
+
+public:
+
+	Pvs(): mEntries() {
+
+		entries.set_deleted_key(-1);
+		entries.set_empty_key(-2);
+
+	};
+
+	int GetSize() const {
+		return (int)entries.size();
+	}
+
+
+	bool Empty() const {
+		return entries.empty();
+	}
+
+	/** Adds object to PVS.
+	@returns contribution of sample (0 or 1)
+	*/
+	bool Insert(const int id, const float time = 0.0f) {
+
+		pair<PVS_ITERATOR, bool> result = entries.insert(pair<int, float>(id,time));
+
+		return result.second;
+	}
+
+	bool Find(const int id) {
+		PVS_ITERATOR it;
+		return Find(id, it);
+	}
+
+	bool Find(const int id, PVS_ITERATOR &it) {
+		it = entries.find(id);
+
+		// already in map
+		return (it != entries.end());
+	}
+
+	void Clear() {
+		entries.clear();
+	}
+
+	static void Merge(Pvs &mergedPvs,
+		const Pvs &a, 
+		const Pvs &b)
+	{
+		mergedPvs.entries.insert(a.entries.begin(), a.entries.end());
+		mergedPvs.entries.insert(b.entries.begin(), b.entries.end());
+	}
+
+	// just an estimate - could not find proper reference how to
+	// calculate memory occupied by hash_map and hash_set!
+	int GetMemoryUsage() const {
+
+		return sizeof(Pvs) + sizeof(HASH_SET::value_type)*entries.bucket_count();
+	}
+
+protected:
+	/// hash table of PVS entries
+	HASH_SET entries; 
+
+};
+
+
+/** Iterator over a hash pvs.
+*/
+class PvsIterator
+{
+protected:
+
+	CONST_PVS_ITERATOR itCurrent;
+	CONST_PVS_ITERATOR itEnd;
+
+public:
+
+	PvsIterator() {}
+
+	PvsIterator(Pvs &pvs):
+	itCurrent(pvs.entries.begin()), itEnd(pvs.entries.end())
+	{
+	}
+
+	bool HasMoreEntries() const 
+	{
+		return (itCurrent != itEnd);
+	}
+
+	void Next() {
+		++itCurrent;
+	}
+
+	int Current() const {
+
+		return (*itCurrent).first;
+
+	}
+	float CurrentTime() const {
+
+		return (*itCurrent).second;
+
+	}
+
+};
+
+#if 0
+// iterator of the PVS at the given time stamp
+// onnly works properly in PVS_TIME_STAMPS is defined
+// otherwise behaves the same as PvsIterator
+
+class PvsTimeIterator : public PvsIterator
+{
+protected:
+	float time;
+public:
+
+	PvsTimeIterator(Pvs &pvs, const float _time):
+	  PvsIterator(pvs), time(_time)
+	  {
+		  // find the first entry satisfying the time constraint
+		  for (;HasMoreEntries(); ++itCurrent)
+			  if ((*itCurrent).second <= time)
+				  break;
+	  }
+
+	  void Next() {
+		  for (++itCurrent; HasMoreEntries(); ++itCurrent)
+			  if ((*itCurrent).second <= time)
+				  break;
+	  }
+
+};
+
+#endif
+}
+
+#endif
+
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/VisibilitySolutionLoader.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/VisibilitySolutionLoader.h	(revision 3242)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/VisibilitySolutionLoader.h	(revision 3242)
@@ -0,0 +1,30 @@
+#ifndef _VISIBILITYSOLUTIONLOADER_H
+#define _VISIBILITYSOLUTIONLOADER_H
+
+
+class ViewCellsTree;
+	
+namespace CHCDemoEngine
+{
+
+/** Loads a preprocessed visibility solution.
+*/
+class VisibilitySolutionLoader
+{
+public:
+
+	VisibilitySolutionLoader();
+
+	~VisibilitySolutionLoader();
+
+	bool Load(const std::string &filename
+		      ViewCellsTree *viewCells);
+
+protected:
+
+	int mNumNodes;
+};
+
+}
+
+#endif
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhLoader.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhLoader.cpp	(revision 3239)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/BvhLoader.cpp	(revision 3242)
@@ -82,4 +82,6 @@
 	bvh->mNumNodes = 3;
 
+	cout << "*******************\nbox: " << root->mBox << " area: " << root->mArea << endl;
+
 	tQueue.push(root);
 	
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/VisibilitySolutionLoader.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/VisibilitySolutionLoader.cpp	(revision 3242)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/VisibilitySolutionLoader.cpp	(revision 3242)
@@ -0,0 +1,16 @@
+#include "VisibilitySolutionLoader.h"
+
+
+using namespace std;
+
+	
+namespace CHCDemoEngine
+{
+
+bool VisibilitySolutionLoader::Load(const std::string &filename
+									ViewCellsTree *viewCells)
+{
+	return true;
+}
+
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3235)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.h	(revision 3242)
@@ -36,8 +36,58 @@
 		and a buffer holding the difference of the pixel positions from the last frame.
 
-		Set useToneMapping to true if tone mapping should be applied
-		Set useAntiAliasing true if some basic edge antialiasing should be performed
 		If a shadowMap is specified that is not NULL, the shadow mapped shading algorithm is applied.
-
+	*/
+	void Render(FrameBufferObject *fbo, 
+				DirectionalLight *light,
+				ShadowMap *shadowMap = NULL
+				);
+
+	
+	enum SAMPLING_METHOD {SAMPLING_POISSON, SAMPLING_QUADRATIC, SAMPLING_DEFAULT};
+	/** Use ssao or ssao + color bleeding
+	*/
+	enum SHADING_METHOD {DEFAULT, SSAO, GI};
+	/** Set the samplig method for the indirect illumination
+	*/
+	void SetSamplingMethod(SAMPLING_METHOD s);
+	/** Set the shading method (SSAO, SSAO + color bleeding
+	*/
+	void SetShadingMethod(SHADING_METHOD s);
+	/** Sort the samples in order to provide faster texture accesses.
+	*/
+	//void SetSortSamples(bool sortSamples);
+	/** Sets ssao sample intensity.
+	*/
+	void SetSampleIntensity(float sampleIntensity);
+	/** Sets ssao kernel radius.
+	*/
+	void SetKernelRadius(float kernelRadius);
+	/** Sets ssao filter radius.
+	*/
+	void SetSsaoFilterRadius(float radius);
+	/** Passes the number of pixels that are visible from the sun.
+	*/
+	void SetSunVisiblePixels(int visiblePixels);
+	/** If true temporal coherence is used for ssao
+	*/
+	void SetUseTemporalCoherence(bool temporal);
+	/** if set to something other than -1 the current frame is stored on disc
+		using the specified frame number
+	*/
+	void SetSaveFrame(const std::string &suffix, int frameNumber);
+	/** Sets the maximal visible distance.
+	*/
+	void SetMaxDistance(float maxDist);
+	/**	Enables / disables toneMapping
+	*/
+	void SetUseToneMapping(bool toneMapping);
+	
+	/** Enable antiAliasing if some basic edge antialiasing should be performed
+	*/
+	void SetUseAntiAliasing(bool antiAliasing);
+	/** Enables / disables depth of field.
+	*/
+	void SetUseDepthOfField(bool dof);
+	/**
 		The temporal coherence factor is the maximal number of ssao samples that are accumulated
 		without losing any prior sample information.
@@ -46,47 +96,5 @@
 		1000 samples a flickering cannot be seen.
 	*/
-	void Render(FrameBufferObject *fbo, 
-				float tempCohFactor, 
-				DirectionalLight *light,
-				bool useToneMapping,
-				bool useAntiAliasing,
-				ShadowMap *shadowMap = NULL
-				);
-
-	
-	enum SAMPLING_METHOD {SAMPLING_POISSON, SAMPLING_QUADRATIC, SAMPLING_DEFAULT};
-	/** Use ssao or ssao + color bleeding
-	*/
-	enum SHADING_METHOD {DEFAULT, SSAO, GI};
-	/** Set the samplig method for the indirect illumination
-	*/
-	void SetSamplingMethod(SAMPLING_METHOD s);
-	/** Set the shading method (SSAO, SSAO + color bleeding
-	*/
-	void SetShadingMethod(SHADING_METHOD s);
-	/** Sort the samples so texture access is faster
-	*/
-	void SetSortSamples(bool sortSamples);
-	/** Sets ssao sample intensity.
-	*/
-	void SetSampleIntensity(float sampleIntensity);
-	/** Sets ssao kernel radius.
-	*/
-	void SetKernelRadius(float kernelRadius);
-	/** Sets ssao filter radius.
-	*/
-	void SetSsaoFilterRadius(float radius);
-	/** Sets the number of visible pixels of the sun
-	*/
-	void SetSunVisiblePixels(int visiblePixels);
-	/** If true tem poral coherence is used for ssao
-	*/
-	void SetUseTemporalCoherence(bool temporal);
-	/** if set to something other than -1 the current frame is stored on disc
-		using the specified frame number
-	*/
-	void SetSaveFrame(const std::string &suffix, int frameNumber);
-
-	void SetMaxDistance(float maxDist);
+	void SetTemporalCoherenceFactorForSsao(float factor);
 
 
@@ -116,4 +124,5 @@
 
 	void CombineSsao(FrameBufferObject *fbo);
+
 	void CombineIllum(FrameBufferObject *fbo);
 	/** Does some basic antialiasing (searches for edges using a edge detector,
@@ -210,4 +219,9 @@
 
 	float mMaxDistance;
+
+	float mTempCohFactor;
+	bool mUseToneMapping;
+	bool mUseAntiAliasing;
+	bool mUseDepthOfField;	  
 };
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3238)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/chcdemo.cpp	(revision 3242)
@@ -381,5 +381,4 @@
 #endif
 
-	cout << "=== reading environment file ===" << endl << endl;
 
 	int returnCode = 0;
@@ -582,9 +581,9 @@
 
 
-	int cityEntities = LoadModel("vienna_full_hp.dem", dynamicObjects);
+/*	int cityEntities = LoadModel("vienna_full_hp.dem", dynamicObjects);
 	
 	for (int i = (int)dynamicObjects.size() - cityEntities; i < (int)dynamicObjects.size(); ++ i)
 		dynamicObjects[i]->GetTransform()->SetMatrix(transl);
-
+*/
 
 	///////////
@@ -1295,5 +1294,9 @@
 		deferredShader->SetSsaoFilterRadius(ssaoFilterRadius);
 		deferredShader->SetUseTemporalCoherence(useTemporalCoherence);
-		deferredShader->SetSortSamples(sortSamples);
+		//deferredShader->SetSortSamples(sortSamples);
+		deferredShader->SetTemporalCoherenceFactorForSsao(ssaoTempCohFactor);
+		deferredShader->SetUseToneMapping(useHDR);
+		deferredShader->SetUseAntiAliasing(useAntiAliasing);
+
 
 		if (recordFrames && replayPath)
@@ -1307,5 +1310,5 @@
 
 		ShadowMap *sm = showShadowMap ? shadowMap : NULL;
-		deferredShader->Render(fbo, ssaoTempCohFactor, light, useHDR, useAntiAliasing, sm);
+		deferredShader->Render(fbo, light, sm);
 	}
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3235)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/DeferredRenderer.cpp	(revision 3242)
@@ -302,5 +302,9 @@
 mSavedFrameNumber(-1),
 mSavedFrameSuffix(""),
-mMaxDistance(1e6f)
+mMaxDistance(1e6f),
+mTempCohFactor(.0f),
+mUseToneMapping(false),
+mUseAntiAliasing(false),
+mUseDepthOfField(false)
 {
 	///////////
@@ -537,8 +541,5 @@
 
 void DeferredRenderer::Render(FrameBufferObject *fbo, 
-							  float tempCohFactor,
 							  DirectionalLight *light,
-							  bool useToneMapping,
-							  bool useAntiAliasing,
 							  ShadowMap *shadowMap
 							  )
@@ -562,9 +563,9 @@
 	{
 	case SSAO:
-		ComputeSsao(fbo, tempCohFactor);
+		ComputeSsao(fbo, mTempCohFactor);
 		CombineSsao(fbo);
 		break;
 	case GI:
-		ComputeGlobIllum(fbo, tempCohFactor);
+		ComputeGlobIllum(fbo, mTempCohFactor);
 		CombineIllum(fbo);
 		break;
@@ -574,8 +575,11 @@
 	}
 
-	/// do depth of field
-	DepthOfField(fbo);
-
-	if (useToneMapping)
+	/// depth of field
+	if (mUseDepthOfField)
+	{
+		DepthOfField(fbo);
+	}
+
+	if (mUseToneMapping)
 	{
 		float imageKey, whiteLum, middleGrey;
@@ -593,5 +597,5 @@
 	// multisampling is difficult / costly with deferred shading
 	// at least do some edge blurring 
-	if (useAntiAliasing) AntiAliasing(fbo, light, displayAfterAA); 
+	if (mUseAntiAliasing) AntiAliasing(fbo, light, displayAfterAA); 
 	
 	/// store the current frame
@@ -599,5 +603,5 @@
 
 	// if it hasn't been done yet => just output the latest buffer
-	if (!useAntiAliasing || !displayAfterAA)
+	if (!mUseAntiAliasing || !displayAfterAA)
 		Output(fbo); 
 
@@ -1266,5 +1270,5 @@
 								  )
 {
-	// light source not visible
+	// light source visible?
 	if (!mSunVisiblePixels) return;
 
@@ -1437,8 +1441,8 @@
 
 
-void DeferredRenderer::SetSortSamples(bool sortSamples) 
+/*void DeferredRenderer::SetSortSamples(bool sortSamples) 
 {
 	mSortSamples = sortSamples; 
-}
+}*/
 
 
@@ -1452,4 +1456,28 @@
 {
 	mMaxDistance = maxDist;
+}
+
+
+void DeferredRenderer::SetUseToneMapping(bool toneMapping)
+{
+	mUseToneMapping = toneMapping;
+}
+	
+
+void DeferredRenderer::SetUseAntiAliasing(bool antiAliasing)
+{
+	mUseAntiAliasing = antiAliasing;
+}
+
+
+void DeferredRenderer::SetUseDepthOfField(bool dof)
+{
+	mUseDepthOfField = dof;
+}
+
+
+void DeferredRenderer::SetTemporalCoherenceFactorForSsao(float factor)
+{
+	mTempCohFactor = factor;
 }
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Pvs.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Pvs.cpp	(revision 3242)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/Pvs.cpp	(revision 3242)
@@ -0,0 +1,64 @@
+#include "Pvs.h"
+#include "Timer/PerfTimer.h"
+#include "common.h"
+#include <iostream>
+
+
+namespace CHCDemoEngine
+{
+
+void TestPvsPerformance()
+{
+	//  Pvs pvs(15000);
+	const int prange=10000;
+	Pvs pvs[prange+1];
+	// test PVS performance
+	const int num = 100000000;
+	const int range = 50000;
+	PerfTimer timer;
+	timer.Entry();
+
+	for (int i=0; i < num; i++)
+	{
+		int id = (int)Random(range);
+		int pid = (5*num)%prange;
+		pvs[pid].Insert(id, (float)i);
+		if (i%1000000 == 0) {
+			cout<<i/1000000<<" M"<<endl;
+			cout<<"size = "<<pvs[pid].GetSize()/(1000*1000)<<"M"<<endl;
+			//	  cout << "bucket_count: " << pvs.entries.bucket_count() << endl;
+		}
+	}
+	timer.Exit();
+
+
+	cout<<"Pvs insert speed = "<<num/float(1000*1000*timer.TotalTime())<<
+		"M entries/s\n";
+	cout<<"Memory usage "<<pvs[0].GetMemoryUsage()<<" bytes"<<endl;
+
+	int counter = 0;
+	timer.Entry();
+	PvsIterator it(pvs[0]);
+	for (; it.HasMoreEntries(); it.Next()) 
+	{
+		++ counter;
+	}
+	timer.Exit();
+
+	cout<<"Pvs count = "<<counter<<endl;
+	cout<<"Pvs iteration speed = "<<pvs[0].GetSize()/float(1000*1000*timer.TotalTime())<<
+		"M entries/s\n";
+
+	counter = 0;
+	timer.Entry();
+	PvsTimeIterator tit(pvs[0], 400);
+	for (; tit.HasMoreEntries(); tit.Next()) {
+		counter++;
+	}
+	timer.Exit();
+	cout<<"Pvs time count = "<<counter<<endl;
+	cout<<"Pvs iteration speed = "<<pvs[0].GetSize()/(1024*1024*timer.TotalTime())<<
+		"M entries/s\n";
+}
+
+}
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ViewCellsTree.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ViewCellsTree.h	(revision 3242)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/src/ViewCellsTree.h	(revision 3242)
@@ -0,0 +1,96 @@
+#ifndef __VIEWCELLSTREE
+#define __VIEWCELLSTREE
+
+#include <vector>
+#include "Pvs.h"
+#include "AxisAlignedBox3.h"
+
+
+	
+namespace CHCDemoEngine
+{
+
+/** basic view cell structure
+*/
+struct ViewCell 
+{
+public:
+
+	ViewCell(): mPvs() {}
+
+protected:
+
+	// id of this viewcell
+	int mId;
+	// bounding box of the viewcell
+	AxisAlignedBox3 mBox;
+	// the pvs associated with the viewcell
+	Pvs mPvs;
+
+};
+
+
+struct ViewCellsTreeNode
+{
+	union 
+	{
+		// split position - 4B
+		float position;
+		// the viewcell associated with this node (NULL for non terminal nodes) - 4B
+		ViewCell *viewCell; 
+	};
+
+
+	ViewCellsTreeNode(): mAxis(-1), mViewCell(NULL) {}
+
+	bool IsLeaf() { return mAxis == -1; }
+
+	bool IsVirtualLeaf() { return mViewCell != NULL; }
+
+
+	///////////////////////
+
+	// children of the node - 8B
+	ViewCellsTreeNode *mBack, *mFront;
+
+	// kd tree split params
+	// split axis - 4B
+	int mAxis;
+};
+
+
+class ViewCellsTree
+{
+public:
+	
+	ViewCellsTree(): mRoot(NULL) {}
+
+	void SubdivideNode(ViewCellsTreeNode *node,
+                       const AxisAlignedBox3 &box,
+					   int depth);
+
+
+	int	CastLineSegment(const Vector3 &origin,
+                        const Vector3 &termination,
+						ViewCell **viewcells);
+
+	ViewCell *GetViewCell(const Vector3 &point) const;
+
+	bool LoadFromFile(const string &filename);
+
+
+protected:
+
+	bool _LoadFromFile(FILE *file);
+
+
+	////////////////////////
+
+	float mMaxDepth;
+	AxisAlignedBox3 mBox;
+	ViewCellsTreeNode *mRoot;
+};
+
+}
+
+#endif
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 3238)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/FriendlyCulling.vcproj	(revision 3242)
@@ -503,4 +503,8 @@
 				</File>
 				<File
+					RelativePath=".\src\Pvs.h"
+					>
+				</File>
+				<File
 					RelativePath=".\src\RenderQueue.h"
 					>
@@ -540,4 +544,12 @@
 				<File
 					RelativePath=".\src\Transform3.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\ViewCellsTree.h"
+					>
+				</File>
+				<File
+					RelativePath=".\src\VisibilitySolutionLoader.h"
 					>
 				</File>
@@ -639,4 +651,8 @@
 				</File>
 				<File
+					RelativePath=".\src\Pvs.cpp"
+					>
+				</File>
+				<File
 					RelativePath=".\src\RenderQueue.cpp"
 					>
@@ -730,4 +746,12 @@
 				<File
 					RelativePath=".\src\Transform3.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\ViewCellsTree.cpp"
+					>
+				</File>
+				<File
+					RelativePath=".\src\VisibilitySolutionLoader.cpp"
 					>
 				</File>
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3238)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/default.env	(revision 3242)
@@ -7,5 +7,5 @@
 # misc stuff
 
-filename=city
+filename=vienna_full_hp
 useLODs=1
 # shadow map size
@@ -61,5 +61,6 @@
 
 # the used render method (forward, forward + depth pass, deferred, deferred + depth pass
-renderMethod=2
+#renderMethod=2
+renderMethod=0
 
 #modelPath=data/city/model/
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/VisibilitySolutionConverter.h
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/VisibilitySolutionConverter.h	(revision 3241)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/VisibilitySolutionConverter.h	(revision 3242)
@@ -68,7 +68,5 @@
 struct BvhLeaf: public BvhNode
 {
-	Geometry *geometry;
-
-	BvhLeaf(): BvhNode(), geometry(NULL) {}
+	BvhLeaf(): BvhNode() {}
 };
 
@@ -141,6 +139,7 @@
 
 	void UpdateLeafBox(BvhLeaf *leaf);
-
-	void UpdateNodeBox(BvhNode *node);
+	/** Prepare bvh for exporting.
+	*/
+	void UpdateBvh(BvhNode *node);
 
 
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/main.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/main.cpp	(revision 3238)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/main.cpp	(revision 3242)
@@ -23,6 +23,7 @@
 	}
 	
-	//std::cin.get();
 	cout << "conversion successful" << endl;
+
+	std::cin.get();
 
 	return 0;
Index: GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/VisibilitySolutionConverter.cpp
===================================================================
--- GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/VisibilitySolutionConverter.cpp	(revision 3241)
+++ GTP/trunk/App/Demos/Vis/FriendlyCulling/VisibilitySolutionConverter/VisibilitySolutionConverter.cpp	(revision 3242)
@@ -246,5 +246,7 @@
 
 	// update bvh bounding boxes with loaded geometry
-	UpdateNodeBox(mRoot);
+	UpdateBvh(mRoot);
+
+	cout << "bvh: " << mRoot->first << " " << mRoot->last << " bb: " << mRoot->box << endl;
 
 	cout << "writing scene" << endl;
@@ -331,6 +333,6 @@
 				default:
 					sscanf(str + 1, "%f %f %f", &x, &y, &z);
-					//const float scale = 5e-3f;
-					const float scale = 0.1f;
+					const float scale = 1.0f;
+					//const float scale = 0.1f;
 					tempVertices.push_back(CHCDemoEngine::Vector3(x * scale, y * scale, z * scale));
 					//cout <<"v " << x << " " << y << " "<< z << " ";
@@ -395,5 +397,5 @@
 
 					sscanf(str + 1, "%f %f %f", &x, &y, &z);
-					const float scale = 0.1f;
+					const float scale = 1.0f;
 					vertices.push_back(CHCDemoEngine::Vector3(x * scale, y * scale, z * scale));
 					break;
@@ -558,4 +560,14 @@
 	vector<TexCoord> _texCoords;
 
+	CHCDemoEngine::AxisAlignedBox3 testBox;
+	testBox.Initialize();
+
+	for (int i = 0; i < vertices.size(); ++ i)
+	{
+		testBox.Include(vertices[i]);
+	}
+
+	cout << "testbox: " << testBox << endl;
+
 	mGeometry.reserve(mBvhLeaves.size());
 
@@ -580,5 +592,8 @@
 		LoadShape(_vertices, _normals, _texCoords);
 		
-		node->geometry = mGeometry.back();
+		// we store geometry in our bvh => change first and last pointer
+		// fromt triangles to geometry
+		node->first = (int)mGeometry.size() - 1;
+		node->last = (int)mGeometry.size() - 1;
 
 		_vertices.clear();
@@ -639,5 +654,5 @@
 	leaf->box.Initialize();
 
-	Geometry *geom = leaf->geometry;
+	Geometry *geom = mGeometry[leaf->first];
 
 	for (size_t i = 0; i < geom->mVertexCount; ++ i)
@@ -842,5 +857,5 @@
 	int nodeType;
 
-	if (!node->IsLeaf())
+	if (node->IsLeaf())
 		nodeType = TYPE_LEAF;
 	else 
@@ -856,21 +871,26 @@
 
 	stream.write(reinterpret_cast<char *>(&bMin), sizeof(CHCDemoEngine::Vector3));
-	stream.write(reinterpret_cast<char *>(&bMin), sizeof(CHCDemoEngine::Vector3));
-}
-
-
-void VisibilitySolutionConverter::UpdateNodeBox(BvhNode *node)
+	stream.write(reinterpret_cast<char *>(&bMax), sizeof(CHCDemoEngine::Vector3));
+}
+
+
+void VisibilitySolutionConverter::UpdateBvh(BvhNode *node)
 {
 	if (!node->IsLeaf())
 	{
 		BvhInterior *interior = (BvhInterior *)node;
+
+		UpdateBvh(interior->front);
+		UpdateBvh(interior->back);
+
+		interior->first = min(interior->front->first, interior->back->first);
+		interior->last = max(interior->front->last, interior->back->last);
+		
 		node->box = Union(interior->front->box, interior->back->box);
-
-		UpdateNodeBox(interior->front);
-		UpdateNodeBox(interior->back);
 	}
 	else
 	{
 		UpdateLeafBox((BvhLeaf *)node);
+		//cout << "bb: " << node->box << endl;
 	}
 }
@@ -883,6 +903,4 @@
 
 	if (!stream.is_open()) return NULL;
-
-	cout << "loading bvh" << endl;
 
 	WriteNextNode(stream, mRoot);
