Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h	(revision 1177)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h	(revision 1182)
@@ -276,5 +276,5 @@
 			/** Returns real extent of the kdtree, i.e., the merged extent of the bounding boxes. 
 			*/
-			AxisAlignedBox _getWorldAABB(void) const { return mWorldAABB; };
+			AxisAlignedBox _getWorldAABB(void) const { return mAABB; };
 			/** Updates bound of the real aabb of kdtree
 			*/
@@ -424,6 +424,22 @@
 		friend class KdTreeHierarchyInterface;
 
+		typedef KdTree::Node * NodePtr;
+		typedef KdTree::Branch * BranchPtr;
 		typedef KdTree::Leaf * LeafPtr;
 		typedef std::set<LeafPtr> LeafSet;
+
+		typedef struct Stats_
+		{
+			unsigned int mNumNodes;
+			unsigned int mNumLeaves;
+			unsigned int mNumSceneNodes;
+
+			void clear(void)
+			{
+				mNumNodes = 0;
+				mNumLeaves = 0;
+				mNumSceneNodes = 0;
+			};
+		} Stats;
 
 		enum RenderMethod
@@ -446,6 +462,8 @@
 
 		// DEBUG
-		void dump();
-		void calcCost();
+		void dump(void);
+		Real calcCost(void);
+
+		NodePtr getRoot(void) const { return mKdRoot; };
 
 		// insert a new scene node into an existing kd-tree
@@ -461,6 +479,7 @@
 
 		// self-explanatory ...
-		int getMaxDepth() { return mMaxDepth; };
-		AxisAlignedBox getBox() { if (mKdRoot) return mKdRoot->mAABB; else return AxisAlignedBox(); };
+		int getMaxDepth(void) { return mMaxDepth; };
+		Stats getStats(void) const { return mStats; };
+		AxisAlignedBox getBox(void) { if (mKdRoot) return mKdRoot->mAABB; else return AxisAlignedBox(); };
 		void setBuildMethod(BuildMethod bm) { mBuildMethod = bm; }
 	protected:
@@ -501,4 +520,7 @@
 		Log * mBuildLog;
 
+		// statistical information
+		Stats mStats;
+
 		// DEBUG
 		void KdTree::dump(KdTree::Node * node);
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h	(revision 1177)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h	(revision 1182)
@@ -32,4 +32,9 @@
 		virtual const String& getTypeName(void) const;
 
+
+		/************************************************************************/
+		/* Functions overridden form SceneManager for KdTree                    */
+		/************************************************************************/
+
 		/** Override from SceneManager to create SceneNodes as instance of KdTreeSceneNode
 		*/
@@ -39,20 +44,89 @@
 		virtual SceneNode* createSceneNode(const String& name);
 
+		/** Override from Scenemanager, employ kd-tree based culling or CHC
+		*/
+		virtual void _findVisibleObjects(Camera *cam, bool onlyShadowCasters);
+
+		virtual bool setOption(const String& strKey, const void* pValue);
+		virtual bool getOption(const String& strKey, void* pDestValue);
+
+		bool getOptionValues(const String & key, StringVector &refValueList);
+		bool getOptionKeys(StringVector &refKeys);
+
+		/** Overide from scene manager to destroy kdtree properly (before the scene graph is destroyed)
+		*/
+		virtual void clearScene()
+		{
+			// DEBUG
+			//if (mKdTree)
+			//	mKdTree->dump();
+
+			// must happen before actual scene is cleared
+			OGRE_DELETE(mKdTree);
+
+			SceneManager::clearScene();
+		}
+
+		/************************************************************************/
+		/* Functions overridden from SceneManager for CHC                       */
+		/************************************************************************/
+
 		/** Override from SceneManager so that sub entities can be assigned an id for item buffer.
 		*/
 		Entity* createEntity(const String& entityName, const String& meshName);
 
+		/** Override from scene manager to set up culling manager
+		*/
+		virtual void _updateSceneGraph(Camera* cam);
+
+		/** Override from SceneManager, employ normal rendering or CHC
+		*/
+		virtual void _renderVisibleObjects();
+
+		/** Override pass so we can do the z-fail pass.
+		*/
+		const Pass* _setPass(Pass* pass);
+
+		/** Render a queue group. 
+		Override so we can handle delayed rendering of transparent objects
+		*/
+		void renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, 
+			QueuedRenderableCollection::OrganisationMode om);
+
+		/** Override from scene manager
+		*/
+		void _renderQueueGroupObjects(RenderQueueGroup* pGroup,
+			QueuedRenderableCollection::OrganisationMode om);
+
+		/** Override from SceneManager so we can skip all but first pass for depth pass. 
+		*/
+		bool validatePassForRendering(Pass* pass);
+
+		/** Override from SceneManager because idontknow
+		*/
+		void renderAdditiveStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup,
+			QueuedRenderableCollection::OrganisationMode om);
+		void renderModulativeStencilShadowedQueueGroupObjects(RenderQueueGroup* pGroup,
+			QueuedRenderableCollection::OrganisationMode om);
+
+
+		/************************************************************************/
+		/* Functions which are specific to the KdTree                           */
+		/************************************************************************/
+		
 		/** Update the KdTree with the node (more or less disabled now)
 		*/
 		virtual void _updateNode(KdTreeSceneNode *node); // TODO: 
 
-		/** Override from scene manager to st up culling manager
-		*/
-		virtual void _updateSceneGraph(Camera* cam);
-		/** Override from Scenemanager, employ kd-tree based culling
-			or CHC
-		*/
-		virtual void _findVisibleObjects(Camera *cam, bool onlyShadowCasters);
-		//virtual void _renderVisibleObjects();
+		/** Show or hide the bounding boxes of KdTree nodes - obsolete, use options
+		*/
+		virtual void setShowBoxes(bool showboxes);
+		/** Tell if show boxes is enabled - obsolete, use options
+		*/
+		virtual bool getShowBoxes(void) const;
+
+		/************************************************************************/
+		/* Functions for CHC                                                    */
+		/************************************************************************/
 
 		/** Render a list of scenenodes
@@ -61,13 +135,4 @@
 			bool onlyShadowCasters, int leavePassesInQueue);
 
-		virtual void setShowBoxes(bool showboxes);
-		virtual bool getShowBoxes(void) const;
-
-		virtual bool setOption(const String& strKey, const void* pValue);
-		virtual bool getOption(const String& strKey, void* pDestValue);
-
-		bool getOptionValues(const String & key, StringVector &refValueList);
-		bool getOptionKeys(StringVector &refKeys);
-
 		/** Sets the visibility manager.
 		@param visManager the visibility manager
@@ -86,57 +151,99 @@
 		KdTreeHierarchyInterface *GetHierarchyInterface();
 
-
-		///** Render a queue group. 
-		//Override so we can handle delayed rendering of transparent objects
-		//*/
-		//void renderBasicQueueGroupObjects(RenderQueueGroup* pGroup, 
-		//	QueuedRenderableCollection::OrganisationMode om);
-
-		///** Writes out stats into the Ogre log file.
-		//*/
-		//void WriteLog();
-
-		///** Override pass so we can do the z-fail pass. 
-		//*/
-		//const Pass* _setPass(Pass* pass);
-
-		///** Override from SceneManager so we can skip all but first pass for depth pass. 
-		//*/
-		//bool validatePassForRendering(Pass* pass);
-
-		virtual void clearScene()
-		{
-			// DEBUG must happen before scene is cleared
-			// might be a solution to detach problem
-			//if (mKdTree)
-			//	mKdTree->dump();
-			
-			OGRE_DELETE(mKdTree);
-
-			SceneManager::clearScene();
-		}
+		/** Creates material for depth pass, e.g., a pass that only fills the depth buffer. 
+		*/
+		void InitDepthPass();
+		/** Creates material for item buffer. 
+		*/
+		void InitItemBufferPass();
+		/** Fills render queue so that a visualization can be rendered. 
+		*/
+		void PrepareVisualization(Camera *cam);
+		/** Initialises necessary parameters for hierarchical visibility culling.
+		*/
+		void InitVisibilityCulling(Camera *cam);
+
+		/** Writes out stats into the Ogre log file.
+		*/
+		void WriteLog();
+
+
 
 	protected:
+		/************************************************************************/
+		/* CHC-specific options & members                                       */
+		/************************************************************************/
+		// pointer to the visibility manager
 		GtpVisibility::VisibilityManager *mVisibilityManager;
 
+		// the hierarchy interface for CHC
 		KdTreeHierarchyInterface *mHierarchyInterface;
 
-		/// consecutive number for sub-entities
+		// if hierarchical culling is currently in use
+		bool mIsHierarchicalCulling;
+
+		// if a visualization of the hierarchical culling is shown
+		bool mShowVisualization;
+		
+		// if the culled nodes are indicated in the visualization
+		bool mVisualizeCulledNodes;
+
+		// consecutive number for sub-entities
 		int mCurrentEntityId;
 
-		/// flag for passes which should not be deleted from queue during first traversal
+		// flag for passes which should not be deleted from queue during first traversal
 		int mLeavePassesInQueue;
+
+		// if symbols for the nodes are shown in the visualization
+		bool mRenderNodesForViz;
+		// if content of the nodes is shown in the visualization
+		bool mRenderNodesContentForViz;
+		/// render transparents after the hierarchical traversal
+		bool mDelayRenderTransparents;
 		
+		// if transparent object are considered for item buffer visibility
+		bool mRenderTransparentsForItemBuffer;
+		// Always execute the vertex program of a pass, e.g., for the depth pass or item buffer
+		bool mExecuteVertexProgramForAllPasses;
+
+		// the depth pass (no lighting, just filling the depth buffer)
+		Pass *mDepthPass;
+		// use a depth pass (i.e., fill only the depth buffer in the first pass)
+		bool mUseDepthPass;
+		// flag indicating if we currently render the depth pass
+		bool mIsDepthPassPhase;
+		// if depth write should be enabled
+		bool mEnableDepthWrite;
+		// if transparents are skipped during rendering
+		bool mSkipTransparents;
+
+		// the item buffer pass (render items color-coded)
+		Pass *mItemBufferPass;
+		// if we use an item buffer for rendering (i.e., object ids as color codes
+		bool mUseItemBuffer;
+		// if we currently render the item buffer 
+		bool mIsItemBufferPhase;
+
+		/************************************************************************/
+		/* Kd-Tree specific options & members                                   */
+		/************************************************************************/
+		// maximum depth of the kdtree
 		int mMaxDepth;
 
+		// the kdtree which holds the scene
 		KdTree *mKdTree;
 
+		// if bounding boxes of kdtree nodes are shown
 		bool mShowBoxes;
 
+		// the method/algorithm used when rendering the scene
 		KdTree::RenderMethod mRenderMethod;
 
+		// the method of building the tree
 		KdTree::BuildMethod mBuildMethod;
 #ifdef KDTREE_DEBUG
+		// bounding boxes of kd nodes will be highlighted on this level of the kd tree
 		int mHighlighLevel;
+		// if all bounding boxes shall be displayed, not only the highlighted level
 		bool mShowAllBoxes;
 #endif
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp	(revision 1177)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp	(revision 1182)
@@ -10,4 +10,5 @@
 #include <OgreCamera.h>
 #include <OgreSubEntity.h>
+#include <OgreMaterialManager.h>
 #include "OgreKdTreeSceneManager.h"
 #include "OgreKdTreeSceneNode.h"
@@ -21,472 +22,1051 @@
 namespace Ogre
 {
-	KdTreeSceneManager::KdTreeSceneManager(const String& name, GtpVisibility::VisibilityManager *vm):
-		SceneManager(name), 
-		mVisibilityManager(vm), 
-		mKdTree(0), 
-		mMaxDepth(KDTREE_MAX_DEPTH),
-		mShowBoxes(false),
+
+KdTreeSceneManager::KdTreeSceneManager(const String& name, GtpVisibility::VisibilityManager *vm):
+SceneManager(name), 
+mVisibilityManager(vm), 
+mKdTree(0), 
+mMaxDepth(KDTREE_MAX_DEPTH),
+mShowBoxes(false),
 #ifdef KDTREE_DEBUG
-		mHighlighLevel(0),
-		mShowAllBoxes(false),
+mHighlighLevel(0),
+mShowAllBoxes(false),
 #endif
-		mBuildMethod(KdTree::KDBM_PRIORITYQUEUE),
-		mRenderMethod(KdTree::KDRM_INTERNAL),
-		mLeavePassesInQueue(0),
-		mCurrentEntityId(1)
-	{
-		// Replace root node with my node
-		OGRE_DELETE(mSceneRoot);
-
-		mSceneRoot = new KdTreeSceneNode(this, "root node");
-		mSceneRoot->_notifyRootNode();
-
-		mHierarchyInterface = new KdTreeHierarchyInterface(this, mDestRenderSystem);
-	}
-
-	KdTreeSceneManager::~KdTreeSceneManager(void)
-	{
-		delete mKdTree;
-	}
-
-	const String& KdTreeSceneManager::getTypeName(void) const
-	{
-		return KdTreeSceneManagerFactory::FACTORY_TYPE_NAME;
-	}
-
-	void KdTreeSceneManager::setShowBoxes(bool showboxes)
-	{
-		mShowBoxes = showboxes;
-	}
-
-	bool KdTreeSceneManager::getShowBoxes(void) const
-	{
-		return mShowBoxes;
-	}
-
-	bool KdTreeSceneManager::setOption(const String& strKey, const void* pValue)
-	{
-		// change max depth of the kdtree
-		// rebuild the tree if already exists
-		if (strKey == "KdTreeMaxDepth")
-		{
-			int maxdepth = *static_cast<const int *>(pValue);
-
-			// no negative depth, plz!
-			if (maxdepth < 0)
-			{
-				return false;
-			}
+mBuildMethod(KdTree::KDBM_PRIORITYQUEUE),
+mRenderMethod(KdTree::KDRM_INTERNAL),
+mShowVisualization(false),
+mRenderNodesForViz(false),
+mRenderNodesContentForViz(false),
+mVisualizeCulledNodes(false),
+mLeavePassesInQueue(0),
+mDelayRenderTransparents(true),
+mUseDepthPass(false),
+mIsDepthPassPhase(false),
+mUseItemBuffer(false),
+mIsItemBufferPhase(false),
+mCurrentEntityId(1),
+mEnableDepthWrite(true),
+mSkipTransparents(false),
+mRenderTransparentsForItemBuffer(true),
+mExecuteVertexProgramForAllPasses(false),
+mIsHierarchicalCulling(false)
+{
+// Replace root node with my node
+OGRE_DELETE(mSceneRoot);
+
+mSceneRoot = new KdTreeSceneNode(this, "root node");
+mSceneRoot->_notifyRootNode();
+
+mHierarchyInterface = new KdTreeHierarchyInterface(this, mDestRenderSystem);
+}
+
+KdTreeSceneManager::~KdTreeSceneManager(void)
+{
+	delete mHierarchyInterface;
+	delete mKdTree;
+}
+
+const String& KdTreeSceneManager::getTypeName(void) const
+{
+	return KdTreeSceneManagerFactory::FACTORY_TYPE_NAME;
+}
+
+void KdTreeSceneManager::setShowBoxes(bool showboxes)
+{
+	mShowBoxes = showboxes;
+}
+
+bool KdTreeSceneManager::getShowBoxes(void) const
+{
+	return mShowBoxes;
+}
+
+bool KdTreeSceneManager::setOption(const String& strKey, const void* pValue)
+{
+	// change max depth of the kdtree
+	// rebuild the tree if already exists
+	if (strKey == "KdTreeMaxDepth")
+	{
+		int maxdepth = *static_cast<const int *>(pValue);
+
+		// no negative depth, plz!
+		if (maxdepth < 0)
+		{
+			return false;
+		}
+		else
+		{
+			mMaxDepth = maxdepth;
+#ifdef KDTREE_DEBUG
+			if (mHighlighLevel > mMaxDepth)
+				mHighlighLevel = mMaxDepth;
+#endif
+			return true;
+		}
+		return true;
+	}
+	else if (strKey == "KT")
+	{
+		Real kt = *static_cast<const Real *>(pValue);
+		if (kt > 0)
+		{
+			PlaneEvent::KT = kt;
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+	else if (strKey == "KI")
+	{
+		Real ki = *static_cast<const Real *>(pValue);
+		if (ki > 0)
+		{
+			PlaneEvent::KI = ki;
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+	else if (strKey == "RebuildKdTree")
+	{
+		OGRE_DELETE(mKdTree);
+		mKdTree = new KdTree(mMaxDepth);
+		mKdTree->setBuildMethod(mBuildMethod);
+		mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot));
+		return true;
+	}
+#ifdef KDTREE_DEBUG
+	else if (strKey == "HighlightLevel")
+	{
+		int hl = *static_cast<const int *>(pValue);
+		if (hl >= 0 && hl <= mMaxDepth)
+		{
+			mHighlighLevel = hl;
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+	else if (strKey == "ShowAllBoxes")
+	{
+		bool sa = *static_cast<const bool *>(pValue);
+		mShowAllBoxes = sa;
+		return true;
+	}
+#endif
+	else if (strKey == "BuildMethod")
+	{
+		String bm = *static_cast<const String *>(pValue);
+		if (bm == "PriorityQueue")
+		{
+			mBuildMethod = KdTree::KDBM_PRIORITYQUEUE;
+			return true;
+		}
+		else if (bm == "Recursive")
+		{
+			mBuildMethod = KdTree::KDBM_RECURSIVE;
+			return true;
+		}
+		else
+		{
+			return false;
+		}
+	}
+	else if (strKey == "RenderMethod")
+	{
+		String rm = *static_cast<const String *>(pValue);
+		if (rm == "INT")
+		{
+			mRenderMethod = KdTree::KDRM_INTERNAL;
+			return true;
+		}
+		else if (rm == "VFC")
+		{
+			mRenderMethod = KdTree::KDRM_GTP_VFC;
+			int cmt = GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING;
+			return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
+				.setOption("Algorithm", &cmt);
+		}
+		else if (rm == "SWC")
+		{
+			mRenderMethod = KdTree::KDRM_GTP_SWC;
+			int cmt = GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING;
+			return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
+				.setOption("Algorithm", &cmt);
+		}
+		else if (rm == "CHC")
+		{
+			mRenderMethod = KdTree::KDRM_GTP_CHC;
+			int cmt = GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING;
+			return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
+				.setOption("Algorithm", &cmt);
+		}
+		else
+		{
+			return false;
+		}
+	}
+	// little hack in case someone uses "Algorithm" option from VisOptMan directly
+	else if (strKey == "Algorithm")
+	{
+		bool success = VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
+			.setOption(strKey, pValue);
+		// change setting only if change in VisOptMan was successful
+		if (success)
+		{
+			int val = *static_cast<const int *>(pValue);
+			if (val == GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING)
+				mRenderMethod = KdTree::KDRM_GTP_VFC;
+			else if (val == GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING)
+				mRenderMethod = KdTree::KDRM_GTP_SWC;
+			else if (val == GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING)
+				mRenderMethod = KdTree::KDRM_GTP_CHC;
+			// default, should never happen
 			else
-			{
-				mMaxDepth = maxdepth;
+				mRenderMethod = KdTree::KDRM_INTERNAL;
+		}
+		return success;
+	}
+	else if (strKey == "ShowKdTree")
+	{
+		bool sk = *static_cast<const bool *>(pValue);
+		mShowBoxes = sk;
+		return true;
+	}
+
+	return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
+		.setOption(strKey, pValue) || SceneManager::setOption(strKey, pValue);
+}
+
+bool KdTreeSceneManager::getOption(const String& strKey, void* pDestValue)
+{
+	if (strKey == "KdTreeMaxDepth")
+	{
+		*static_cast<int *>(pDestValue) = mMaxDepth;
+		return true;
+	}
+	else if (strKey == "KT")
+	{
+		*static_cast<Real *>(pDestValue) = PlaneEvent::KT;
+		return true;
+	}
+	else if (strKey == "KI")
+	{
+		*static_cast<Real *>(pDestValue) = PlaneEvent::KI;
+		return true;
+	}
 #ifdef KDTREE_DEBUG
-				if (mHighlighLevel > mMaxDepth)
-					mHighlighLevel = mMaxDepth;
+	else if (strKey == "HighlightLevel")
+	{
+		*static_cast<int *>(pDestValue) = mHighlighLevel;
+		return true;
+	}
+	else if (strKey == "ShowAllBoxes")
+	{
+		*static_cast<bool *>(pDestValue) = mShowAllBoxes;
+		return true;
+	}
 #endif
-				return true;
-			}
-			return true;
-		}
-		else if (strKey == "KT")
-		{
-			Real kt = *static_cast<const Real *>(pValue);
-			if (kt > 0)
-			{
-				PlaneEvent::KT = kt;
-				return true;
-			}
-			else
-			{
-				return false;
-			}
-		}
-		else if (strKey == "KI")
-		{
-			Real ki = *static_cast<const Real *>(pValue);
-			if (ki > 0)
-			{
-				PlaneEvent::KI = ki;
-				return true;
-			}
-			else
-			{
-				return false;
-			}
-		}
-		else if (strKey == "RebuildKdTree")
-		{
-			OGRE_DELETE(mKdTree);
-			mKdTree = new KdTree(mMaxDepth);
-			mKdTree->setBuildMethod(mBuildMethod);
-			mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot));
-			return true;
-		}
+	else if (strKey == "BuildMethod")
+	{
+		if (mBuildMethod == KdTree::KDBM_PRIORITYQUEUE)
+		{
+			*static_cast<String *>(pDestValue) = "PriorityQueue";
+		}
+		else if (mBuildMethod == KdTree::KDBM_RECURSIVE)
+		{
+			*static_cast<String *>(pDestValue) = "Recursive";
+		}
+		return true;
+	}
+	else if (strKey == "RenderMethod")
+	{
+		if (mRenderMethod == KdTree::KDRM_INTERNAL)
+		{
+			*static_cast<String *>(pDestValue) = "INT";
+		}
+		else if (mRenderMethod == KdTree::KDRM_GTP_VFC)
+		{
+				*static_cast<String *>(pDestValue) = "VFC";
+		}
+		else if (mRenderMethod == KdTree::KDRM_GTP_SWC)
+		{
+				*static_cast<String *>(pDestValue) = "SWC";
+		}
+		else if (mRenderMethod == KdTree::KDRM_GTP_CHC)
+		{
+				*static_cast<String *>(pDestValue) = "CHC";
+		}
+		else
+		{
+			return false;
+		}
+		return true;
+	}
+	else if (strKey == "TreeBox")
+	{
+		if (mKdTree)
+			*static_cast<AxisAlignedBox *>(pDestValue) = mKdTree->getBox();
+		else
+			*static_cast<AxisAlignedBox *>(pDestValue) = AxisAlignedBox();
+	}
+
+	return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
+		.getOption(strKey, pDestValue) || SceneManager::getOption(strKey, pDestValue);
+}
+
+bool KdTreeSceneManager::getOptionKeys(StringVector &refKeys)
+{
+	refKeys.push_back("BuildMethod");
+	refKeys.push_back("KI");
+	refKeys.push_back("KT");
+	refKeys.push_back("KdTreeMaxDepth");
+	refKeys.push_back("RebuildKdTree");
+	refKeys.push_back("RenderMethod");
+	refKeys.push_back("ShowKdTree");
+	refKeys.push_back("TreeBox");
 #ifdef KDTREE_DEBUG
-		else if (strKey == "HighlightLevel")
-		{
-			int hl = *static_cast<const int *>(pValue);
-			if (hl >= 0 && hl <= mMaxDepth)
-			{
-				mHighlighLevel = hl;
-				return true;
-			}
-			else
-			{
-				return false;
-			}
-		}
-		else if (strKey == "ShowAllBoxes")
-		{
-			bool sa = *static_cast<const bool *>(pValue);
-			mShowAllBoxes = sa;
-			return true;
-		}
+	refKeys.push_back("HighlightLevel");
+	refKeys.push_back("ShowAllBoxes");
 #endif
-		else if (strKey == "BuildMethod")
-		{
-			String bm = *static_cast<const String *>(pValue);
-			if (bm == "PriorityQueue")
-			{
-				mBuildMethod = KdTree::KDBM_PRIORITYQUEUE;
-				return true;
-			}
-			else if (bm == "Recursive")
-			{
-				mBuildMethod = KdTree::KDBM_RECURSIVE;
-				return true;
-			}
-			else
-			{
-				return false;
-			}
-		}
-		else if (strKey == "RenderMethod")
-		{
-			String rm = *static_cast<const String *>(pValue);
-			if (rm == "INT")
-			{
-				mRenderMethod = KdTree::KDRM_INTERNAL;
-				return true;
-			}
-			else if (rm == "VFC")
-			{
-				mRenderMethod = KdTree::KDRM_GTP_VFC;
-				int cmt = GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING;
-				return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
-					.setOption("Algorithm", &cmt);
-			}
-			else if (rm == "SWC")
-			{
-				mRenderMethod = KdTree::KDRM_GTP_SWC;
-				int cmt = GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING;
-				return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
-					.setOption("Algorithm", &cmt);
-			}
-			else if (rm == "CHC")
-			{
-				mRenderMethod = KdTree::KDRM_GTP_CHC;
-				int cmt = GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING;
-				return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
-					.setOption("Algorithm", &cmt);
-			}
-			else
-			{
-				return false;
-			}
-		}
-		// little hack in case someone uses "Algorithm" option from VisOptMan directly
-		else if (strKey == "Algorithm")
-		{
-			bool success = VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
-				.setOption(strKey, pValue);
-			// change setting only if change in VisOptMan was successful
-			if (success)
-			{
-				int val = *static_cast<const int *>(pValue);
-				if (val == GtpVisibility::VisibilityEnvironment::FRUSTUM_CULLING)
-					mRenderMethod = KdTree::KDRM_GTP_VFC;
-				else if (val == GtpVisibility::VisibilityEnvironment::STOP_AND_WAIT_CULLING)
-					mRenderMethod = KdTree::KDRM_GTP_SWC;
-				else if (val == GtpVisibility::VisibilityEnvironment::COHERENT_HIERARCHICAL_CULLING)
-					mRenderMethod = KdTree::KDRM_GTP_CHC;
-				// default, should never happen
-				else
-					mRenderMethod = KdTree::KDRM_INTERNAL;
-			}
-			return success;
-		}
-		else if (strKey == "ShowKdTree")
-		{
-			bool sk = *static_cast<const bool *>(pValue);
-			mShowBoxes = sk;
-			return true;
-		}
-
-		return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
-			.setOption(strKey, pValue) || SceneManager::setOption(strKey, pValue);
-	}
-
-	bool KdTreeSceneManager::getOption(const String& strKey, void* pDestValue)
-	{
-		if (strKey == "KdTreeMaxDepth")
-		{
-			*static_cast<int *>(pDestValue) = mMaxDepth;
-			return true;
-		}
-		else if (strKey == "KT")
-		{
-			*static_cast<Real *>(pDestValue) = PlaneEvent::KT;
-			return true;
-		}
-		else if (strKey == "KI")
-		{
-			*static_cast<Real *>(pDestValue) = PlaneEvent::KI;
-			return true;
-		}
-#ifdef KDTREE_DEBUG
-		else if (strKey == "HighlightLevel")
-		{
-			*static_cast<int *>(pDestValue) = mHighlighLevel;
-			return true;
-		}
-		else if (strKey == "ShowAllBoxes")
-		{
-			*static_cast<bool *>(pDestValue) = mShowAllBoxes;
-			return true;
-		}
+	return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
+		.getOptionKeys(refKeys);
+}
+
+bool KdTreeSceneManager::getOptionValues(const String & key, StringVector &refValueList)
+{
+	return SceneManager::getOptionValues(key, refValueList);
+}
+
+void KdTreeSceneManager::setVisibilityManager(GtpVisibility::VisibilityManager *visManager)
+{
+	mVisibilityManager = visManager;
+}
+
+GtpVisibility::VisibilityManager * KdTreeSceneManager::getVisibilityManager()
+{
+	return mVisibilityManager;
+}
+
+GtpVisibility::VisibilityManager * KdTreeSceneManager::GetVisibilityManager()
+{
+	return mVisibilityManager;
+}
+
+KdTreeHierarchyInterface * KdTreeSceneManager::GetHierarchyInterface()
+{
+	return mHierarchyInterface;
+}
+
+SceneNode* KdTreeSceneManager::createSceneNode(void)
+{
+	SceneNode* sn = new KdTreeSceneNode(this);
+	assert(mSceneNodes.find(sn->getName()) == mSceneNodes.end());
+	mSceneNodes[sn->getName()] = sn;
+	return sn;
+}
+
+SceneNode* KdTreeSceneManager::createSceneNode(const String& name)
+{
+	// Check name not used
+	if (mSceneNodes.find(name) != mSceneNodes.end())
+	{
+		OGRE_EXCEPT(
+			Exception::ERR_DUPLICATE_ITEM,
+			"A scene node with the name " + name + " already exists",
+			"KdTreeSceneManager::createSceneNode" );
+	}
+
+	SceneNode* sn = new KdTreeSceneNode(this, name);
+	mSceneNodes[sn->getName()] = sn;
+	return sn;
+}
+
+Entity * KdTreeSceneManager::createEntity(const String& entityName, const String& meshName)
+{
+	Entity *ent = SceneManager::createEntity(entityName, meshName);
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
+	{
+		ent->getSubEntity(i)->setId(mCurrentEntityId);
+	}
+
+	// increase counter of entity id values
+	++ mCurrentEntityId;
 #endif
-		else if (strKey == "BuildMethod")
-		{
-			if (mBuildMethod == KdTree::KDBM_PRIORITYQUEUE)
-			{
-				*static_cast<String *>(pDestValue) = "PriorityQueue";
-			}
-			else if (mBuildMethod == KdTree::KDBM_RECURSIVE)
-			{
-				*static_cast<String *>(pDestValue) = "Recursive";
-			}
-			return true;
-		}
-		else if (strKey == "RenderMethod")
-		{
-			if (mRenderMethod == KdTree::KDRM_INTERNAL)
-			{
-				*static_cast<String *>(pDestValue) = "INT";
-			}
-			else if (mRenderMethod == KdTree::KDRM_GTP_VFC)
-			{
-					*static_cast<String *>(pDestValue) = "VFC";
-			}
-			else if (mRenderMethod == KdTree::KDRM_GTP_SWC)
-			{
-					*static_cast<String *>(pDestValue) = "SWC";
-			}
-			else if (mRenderMethod == KdTree::KDRM_GTP_CHC)
-			{
-					*static_cast<String *>(pDestValue) = "CHC";
-			}
-			else
-			{
-				return false;
-			}
-			return true;
-		}
-		else if (strKey == "TreeBox")
-		{
-			if (mKdTree)
-				*static_cast<AxisAlignedBox *>(pDestValue) = mKdTree->getBox();
-			else
-				*static_cast<AxisAlignedBox *>(pDestValue) = AxisAlignedBox();
-		}
-
-		return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
-			.getOption(strKey, pDestValue) || SceneManager::getOption(strKey, pDestValue);
-	}
-
-	bool KdTreeSceneManager::getOptionKeys(StringVector &refKeys)
-	{
-		refKeys.push_back("BuildMethod");
-		refKeys.push_back("KI");
-		refKeys.push_back("KT");
-		refKeys.push_back("KdTreeMaxDepth");
-		refKeys.push_back("RebuildKdTree");
-		refKeys.push_back("RenderMethod");
-		refKeys.push_back("ShowKdTree");
-		refKeys.push_back("TreeBox");
-#ifdef KDTREE_DEBUG
-		refKeys.push_back("HighlightLevel");
-		refKeys.push_back("ShowAllBoxes");
-#endif
-		return VisibilityOptionsManager(mVisibilityManager, mHierarchyInterface)
-			.getOptionKeys(refKeys);
-	}
-
-	bool KdTreeSceneManager::getOptionValues(const String & key, StringVector &refValueList)
-	{
-		return SceneManager::getOptionValues(key, refValueList);
-	}
-
-	void KdTreeSceneManager::setVisibilityManager(GtpVisibility::VisibilityManager *visManager)
-	{
-		mVisibilityManager = visManager;
-	}
-
-	GtpVisibility::VisibilityManager * KdTreeSceneManager::getVisibilityManager()
-	{
-		return mVisibilityManager;
-	}
-
-	GtpVisibility::VisibilityManager * KdTreeSceneManager::GetVisibilityManager()
-	{
-		return mVisibilityManager;
-	}
-
-	KdTreeHierarchyInterface * KdTreeSceneManager::GetHierarchyInterface()
-	{
-		return mHierarchyInterface;
-	}
-
-	SceneNode* KdTreeSceneManager::createSceneNode(void)
-	{
-		SceneNode* sn = new KdTreeSceneNode(this);
-		assert(mSceneNodes.find(sn->getName()) == mSceneNodes.end());
-		mSceneNodes[sn->getName()] = sn;
-		return sn;
-	}
-
-	SceneNode* KdTreeSceneManager::createSceneNode(const String& name)
-	{
-		// Check name not used
-		if (mSceneNodes.find(name) != mSceneNodes.end())
-		{
-			OGRE_EXCEPT(
-				Exception::ERR_DUPLICATE_ITEM,
-				"A scene node with the name " + name + " already exists",
-				"KdTreeSceneManager::createSceneNode" );
-		}
-
-		SceneNode* sn = new KdTreeSceneNode(this, name);
-		mSceneNodes[sn->getName()] = sn;
-		return sn;
-	}
-
-	Entity * KdTreeSceneManager::createEntity(const String& entityName, const String& meshName)
-	{
-		Entity *ent = SceneManager::createEntity(entityName, meshName);
-#ifdef GTP_VISIBILITY_MODIFIED_OGRE
-		for (int i = 0; i < (int)ent->getNumSubEntities(); ++i)
-		{
-			ent->getSubEntity(i)->setId(mCurrentEntityId);
-		}
-
-		// increase counter of entity id values
-		++ mCurrentEntityId;
-#endif
-		return ent;
-	}
-
-	// make sure it's called only for non-empty nodes .. avoids one uneccessary funciton call
-	void KdTreeSceneManager::_updateNode(KdTreeSceneNode *node)
-	{
-		//LogManager::getSingleton().logMessage("### _updateNode called for " + node->getName());
-
-		/* Rebuild kdtree when it was wiped out
-		 * Usually this happens only before the first frame
-		 * The initial AABB shall enclose all objects present
-		 * in the scene at the time of construction
-		 * TODO: find a more appropriate place for it,
-		 * e.g., before the first render call
-		 * teh stupid thing is I can't find any other place so far ...
-		 */
-		if (!mKdTree)
-		{
-			mKdTree = new KdTree(mMaxDepth);
-			mKdTree->setBuildMethod(mBuildMethod);
-			mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot));
-		}
-
-		// if the node is in the tree and _updateNode was called, then the node was moved/rotated/resized/wahtever
-		if (node->isAttached())
-		{
-			// TEST: perfomance when adding & removing for every frame
-			//mKdTree->remove(node);
-			//mKdTree->insert(node);
-		}
-		// there's a new node in town ... 
-		else
-		{			
-			// inserting single nodes yields sub-optimal results
-			// rebuilding tree takes too long
-			// "What now?", spoke Zeus ...
-
-			//mKdTree->insert(node);
-			
-			//delete mKdTree;
-			//mKdTree = new KdTree(mMaxDepth);
-			//mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot));
-		}
-
-	}
-
-	void KdTreeSceneManager::_updateSceneGraph(Camera* cam)
-	{
-		mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface);
-		mHierarchyInterface->SetRenderSystem(mDestRenderSystem);
-
-		SceneManager::_updateSceneGraph(cam);
-	}
-
-	void KdTreeSceneManager::_findVisibleObjects(Camera *cam, bool onlyShadowCasters)
+	return ent;
+}
+
+// make sure it's called only for non-empty nodes .. avoids one uneccessary funciton call
+void KdTreeSceneManager::_updateNode(KdTreeSceneNode *node)
+{
+	//LogManager::getSingleton().logMessage("### _updateNode called for " + node->getName());
+
+	/* Rebuild kdtree when it was wiped out
+		* Usually this happens only before the first frame
+		* The initial AABB shall enclose all objects present
+		* in the scene at the time of construction
+		* TODO: find a more appropriate place for it,
+		* e.g., before the first render call
+		* teh stupid thing is I can't find any other place so far ...
+		*/
+	if (!mKdTree)
+	{
+		mKdTree = new KdTree(mMaxDepth);
+		mKdTree->setBuildMethod(mBuildMethod);
+		mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot));
+	}
+
+	// if the node is in the tree and _updateNode was called, then the node was moved/rotated/resized/wahtever
+	if (node->isAttached())
+	{
+		// TEST: perfomance when adding & removing for every frame
+		//mKdTree->remove(node);
+		//mKdTree->insert(node);
+	}
+	// there's a new node in town ... 
+	else
+	{			
+		// inserting single nodes yields sub-optimal results
+		// rebuilding tree takes too long
+		// "What now?", spoke Zeus ...
+
+		//mKdTree->insert(node);
+		
+		//delete mKdTree;
+		//mKdTree = new KdTree(mMaxDepth);
+		//mKdTree->build(static_cast<KdTreeSceneNode *>(mSceneRoot));
+	}
+
+}
+
+void KdTreeSceneManager::_updateSceneGraph(Camera* cam)
+{
+	mVisibilityManager->GetCullingManager()->SetHierarchyInterface(mHierarchyInterface);
+	mHierarchyInterface->SetRenderSystem(mDestRenderSystem);
+
+	SceneManager::_updateSceneGraph(cam);
+}
+
+void KdTreeSceneManager::_findVisibleObjects(Camera *cam, bool onlyShadowCasters)
+{
+	if (mRenderMethod == KdTree::KDRM_INTERNAL)
 	{
 		getRenderQueue()->clear();
 		if (mKdTree)
 			mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mRenderMethod, mShowBoxes);
-		//SceneManager::_findVisibleObjects(cam, onlyShadowCasters);
-	}
-
-	// TODO: looks too easy, verify if it works 
-	void KdTreeSceneManager::_renderNodes(const KdRenderableList& nodelist, Camera * cam, 
-		bool onlyShadowCasters, int leavePassesInQueue)
-	{
+	}
+	else
+	{
+		//-- show visible scene nodes and octree bounding boxes from last frame
+		if (mShowVisualization)
+		{
+			PrepareVisualization(cam);
+		}
+		else 
+		{	
+			// for hierarchical culling, we interleave identification 
+			// and rendering of objects in _renderVisibibleObjects
+
+			// for the shadow pass we use only standard rendering
+			// because of low occlusion
+			if (mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE && 
+				mIlluminationStage == IRS_RENDER_TO_TEXTURE)
+			{
+				getRenderQueue()->clear();
+				if (mKdTree)
+					mKdTree->queueVisibleObjects(cam, getRenderQueue(), onlyShadowCasters, mRenderMethod, mShowBoxes);
+			}
+
+			// only shadow casters will be rendered in shadow texture pass
+			if (0) mHierarchyInterface->SetOnlyShadowCasters(onlyShadowCasters);
+
+
+			//-- apply view cell pvs - TODO
+			//updatePvs(cam);
+		}
+	}
+}
+
+void KdTreeSceneManager::_renderVisibleObjects()
+{
+	if (mRenderMethod == KdTree::KDRM_INTERNAL)
+	{
+		SceneManager::_renderVisibleObjects();
+	}
+	else
+	{
+		InitDepthPass(); 	  // create material for depth pass
+		InitItemBufferPass(); // create material for item buffer pass
+
+		// save ambient light to reset later
+		ColourValue savedAmbient = mAmbientLight;
+
+		//-- apply standard rendering for some modes (e.g., visualization, shadow pass)
+
+		if (mShowVisualization ||
+			(mShadowTechnique == SHADOWTYPE_TEXTURE_MODULATIVE && 
+			mIlluminationStage == IRS_RENDER_TO_TEXTURE))
+		{	
+			IlluminationRenderStage savedStage = mIlluminationStage; 
+
+			if (mShowVisualization) 
+			{
+				// disable illumination stage to prevent rendering shadows
+				mIlluminationStage = IRS_NONE;
+			}
+
+			// standard rendering for shadow maps because of performance
+			SceneManager::_renderVisibleObjects();
+
+			mIlluminationStage = savedStage;
+		}
+		else //-- the hierarchical culling algorithm
+		{
+			// this is also called in TerrainSceneManager: really
+			// necessary?
+			//mDestRenderSystem -> setLightingEnabled(false);
+
+			// don't render backgrounds for item buffer
+			if (mUseItemBuffer)
+			{
+				clearSpecialCaseRenderQueues();
+				getRenderQueue()->clear();
+			}
+
+			//-- hierarchical culling
+			// the objects of different layers (e.g., background, scene, 
+			// overlay) must be identified and rendered one after another
+
+			//-- render all early skies
+			clearSpecialCaseRenderQueues();
+			addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND);
+			addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY);
+			setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);
+
+			SceneManager::_renderVisibleObjects();
+
 #ifdef GTP_VISIBILITY_MODIFIED_OGRE
-		_deleteRenderedQueueGroups(leavePassesInQueue); //try avoiding modified ogre code
+			// delete previously rendered content
+			_deleteRenderedQueueGroups();
+#endif
+
+			//-- prepare queue for visible objects (i.e., all but overlay and skies late)
+			clearSpecialCaseRenderQueues();
+			addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_LATE);
+			addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
+
+			// exclude this queues from hierarchical rendering
+			setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
+
+
+			// set all necessary parameters for 
+			// hierarchical visibility culling and rendering
+			InitVisibilityCulling(mCameraInProgress);
+
+
+			/** 
+			* the hierarchical culling algorithm
+			* for depth pass: we just find objects and update depth buffer
+			* for "delayed" rendering: we render some passes afterwards
+			* e.g., transparents, because they need front-to-back sorting
+			**/
+
+			mVisibilityManager->ApplyVisibilityCulling();
+
+			// delete remaining renderables from queue:
+			// all which are not in mLeavePassesInQueue)
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+			_deleteRenderedQueueGroups(mLeavePassesInQueue);
+#endif
+
+			//-- reset parameters
+			mIsDepthPassPhase = false;
+			mIsItemBufferPhase = false;
+			mSkipTransparents = false;
+			mIsHierarchicalCulling = false;
+
+			mLeavePassesInQueue = 0;
+
+#if 1	
+			// add visible nodes found by the visibility culling algorithm
+			if (mUseDepthPass)
+			{
+				//NodeList::const_iterator it, it_end = mVisible.end();
+
+				////getRenderQueue()->clear();
+				//for (it = mVisible.begin(); it != it_end; ++ it)
+				//{
+				//	(*it)->_addToRenderQueue(mCameraInProgress, getRenderQueue(), false);
+				//}
+			}
+#endif	
+			//-- now we can render all remaining queue objects
+			//-- used for depth pass, transparents, overlay
+			clearSpecialCaseRenderQueues();
+
+			SceneManager::_renderVisibleObjects();
+		} // hierarchical culling
+
+
+		// reset ambient light
+		setAmbientLight(savedAmbient);
+
+		getRenderQueue()->clear(); // finally clear render queue
+		if (0) OGRE_DELETE(mRenderQueue); // HACK: should rather only be cleared ...
+
+		if (0) WriteLog(); // write out stats
+	}
+}
+
+// TODO: looks too easy, verify if it works 
+void KdTreeSceneManager::_renderNodes(const KdRenderableList& nodelist, Camera * cam, 
+	bool onlyShadowCasters, int leavePassesInQueue)
+{
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	_deleteRenderedQueueGroups(leavePassesInQueue); //try avoiding modified ogre code
 #else
-		getRenderQueue()->clear();
+	getRenderQueue()->clear();
 #endif
-		KdRenderableList::const_iterator it = nodelist.begin();
-		KdRenderableList::const_iterator end = nodelist.end();
-		while (it != end)
-		{
-			(*it)->queueObjects(cam, getRenderQueue(), onlyShadowCasters);
-			it++;
-		}
-
-		SceneManager::_renderVisibleObjects();
-
-	}
-
-	//-----------------------------------------------------------------------
-	//-----------------------------------------------------------------------
-	const String KdTreeSceneManagerFactory::FACTORY_TYPE_NAME = "KdTreeSceneManager";
-	//-----------------------------------------------------------------------
-	void KdTreeSceneManagerFactory::initMetaData(void) const
-	{
-		mMetaData.typeName = FACTORY_TYPE_NAME;
-		mMetaData.description = "Scene manager that organises the scene based on a kd-tree";
-		mMetaData.sceneTypeMask = 0xFFFF; // support all types of scenes (hopefully)
-		mMetaData.worldGeometrySupported = false;
-	}
-	//-----------------------------------------------------------------------
-	SceneManager* KdTreeSceneManagerFactory::createInstance(
-		const String& instanceName)
-	{
-		return new KdTreeSceneManager(instanceName, visManager);
-	}
-	//-----------------------------------------------------------------------
-	void KdTreeSceneManagerFactory::destroyInstance(SceneManager* instance)
-	{
-		delete instance;
-	}
+	KdRenderableList::const_iterator it = nodelist.begin();
+	KdRenderableList::const_iterator end = nodelist.end();
+	while (it != end)
+	{
+		(*it)->queueObjects(cam, getRenderQueue(), onlyShadowCasters);
+		it++;
+	}
+
+	SceneManager::_renderVisibleObjects();
+
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManager::renderBasicQueueGroupObjects(RenderQueueGroup* pGroup,
+													  QueuedRenderableCollection::OrganisationMode om)
+{
+	// Basic render loop
+	// Iterate through priorities
+	RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
+
+	while (groupIt.hasMoreElements())
+	{
+		RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
+
+		// Sort the queue first
+		pPriorityGrp->sort(mCameraInProgress);
+
+		// Do solids
+		renderObjects(pPriorityGrp->getSolidsBasic(), om, true);
+
+		// for correct rendering, transparents must be rendered after hierarchical culling
+		// => do nothing
+
+		// Do transparents (always descending)
+		if (mRenderMethod == KdTree::KDRM_INTERNAL || !mSkipTransparents)
+		{
+			renderObjects(pPriorityGrp->getTransparents(), 
+				QueuedRenderableCollection::OM_SORT_DESCENDING, true);
+		}
+
+
+	}// for each priority
+}
+//-----------------------------------------------------------------------
+bool KdTreeSceneManager::validatePassForRendering(Pass* pass)
+{
+	if (mRenderMethod == KdTree::KDRM_INTERNAL)
+	{
+		return SceneManager::validatePassForRendering(pass);
+	}
+
+	// skip all but first pass if we are doing the depth pass
+	if ((mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() > 0))
+	{
+		return false;
+	}
+	// all but first pass
+	/*else if ((!mIsDepthPassPhase || mIsItemBufferPhase) && (pass->getIndex() != 0))
+	{
+	return false;
+	}*/
+
+	return SceneManager::validatePassForRendering(pass);
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManager::_renderQueueGroupObjects(RenderQueueGroup* pGroup, 
+												  QueuedRenderableCollection::OrganisationMode om)
+{
+	if (mRenderMethod == KdTree::KDRM_INTERNAL || !mIsItemBufferPhase)
+	{
+		SceneManager::_renderQueueGroupObjects(pGroup, om);
+		return;
+	}
+#ifdef  ITEM_BUFFER
+	//-- item buffer
+	//-- item buffer: render objects using false colors
+
+	// Iterate through priorities
+	RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
+
+	while (groupIt.hasMoreElements())
+	{
+		RenderItemBuffer(groupIt.getNext());
+	}
+#endif // ITEM_BUFFER
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManager::renderAdditiveStencilShadowedQueueGroupObjects(
+	RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om)
+{
+	// only render solid passes during hierarchical culling
+	if (mIsHierarchicalCulling)
+	{
+		RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
+		LightList lightList;
+
+		while (groupIt.hasMoreElements())
+		{
+			RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
+
+			// Sort the queue first
+			pPriorityGrp->sort(mCameraInProgress);
+
+			// Clear light list
+			lightList.clear();
+
+			// Render all the ambient passes first, no light iteration, no lights
+			/*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/
+			// mIlluminationStage = IRS_AMBIENT;
+
+			SceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, false, &lightList);
+			// Also render any objects which have receive shadows disabled
+			SceneManager::renderObjects(pPriorityGrp->getSolidsNoShadowReceive(), om, true);
+		}
+	}
+	else // render the rest of the passes
+	{
+		SceneManager::renderAdditiveStencilShadowedQueueGroupObjects(pGroup, om);
+	}
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManager::renderModulativeStencilShadowedQueueGroupObjects(
+	RenderQueueGroup* pGroup, QueuedRenderableCollection::OrganisationMode om)
+{
+	if (mIsHierarchicalCulling)
+	{
+		// Iterate through priorities
+		RenderQueueGroup::PriorityMapIterator groupIt = pGroup->getIterator();
+
+		while (groupIt.hasMoreElements())
+		{
+			RenderPriorityGroup* pPriorityGrp = groupIt.getNext();
+
+			// Sort the queue first
+			pPriorityGrp->sort(mCameraInProgress);
+
+			// Do (shadowable) solids
+			SceneManager::renderObjects(pPriorityGrp->getSolidsBasic(), om, true);
+		}
+	}
+	else
+	{
+		SceneManager::renderModulativeStencilShadowedQueueGroupObjects(pGroup, om);
+	}
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManager::InitDepthPass()
+{
+	MaterialPtr depthMat = MaterialManager::getSingleton().getByName("Visibility/DepthPass");
+
+	if (depthMat.isNull())
+	{
+		depthMat = MaterialManager::getSingleton().create(
+			"Visibility/DepthPass",
+			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
+
+		mDepthPass = depthMat->getTechnique(0)->getPass(0);
+		mDepthPass->setColourWriteEnabled(false);
+		mDepthPass->setDepthWriteEnabled(true);
+		mDepthPass->setLightingEnabled(false);
+	}
+	else
+	{
+		mDepthPass = depthMat->getTechnique(0)->getPass(0);
+	}
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManager::InitItemBufferPass()
+{
+	MaterialPtr itemBufferMat = MaterialManager::getSingleton().
+		getByName("Visibility/ItemBufferPass");
+
+	if (itemBufferMat.isNull())
+	{
+		// Init
+		itemBufferMat = MaterialManager::getSingleton().create("Visibility/ItemBufferPass",
+			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
+
+		mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
+		mItemBufferPass->setColourWriteEnabled(true);
+		mItemBufferPass->setDepthWriteEnabled(true);
+		mItemBufferPass->setLightingEnabled(true);
+		//mItemBufferPass->setLightingEnabled(false);
+	}
+	else
+	{
+		mItemBufferPass = itemBufferMat->getTechnique(0)->getPass(0);
+	}
+	//mItemBufferPass->setAmbient(1, 1, 0);
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManager::PrepareVisualization(Camera *cam)
+{
+	// add player camera for visualization purpose
+	try 
+	{
+		Camera *c;
+		if ((c = getCamera("PlayerCam")) != NULL)
+		{
+			getRenderQueue()->addRenderable(c);
+		}   
+	}
+	catch (...)
+	{
+		// ignore
+	}
+	// add bounding boxes of rendered objects
+	if (0)
+		//for (BoxList::iterator it = mBoxes.begin(); it != mBoxes.end(); ++it)
+		//{
+		//	getRenderQueue()->addRenderable(*it);
+		//}
+
+		if (mRenderNodesForViz || mRenderNodesContentForViz)
+		{
+			// HACK: change node material so it is better suited for visualization
+			MaterialPtr nodeMat = MaterialManager::getSingleton().getByName("Core/NodeMaterial");
+			nodeMat->setAmbient(1, 1, 0);
+			nodeMat->setLightingEnabled(true);
+			nodeMat->getTechnique(0)->getPass(0)->removeAllTextureUnitStates();
+
+			//for (NodeList::iterator it = mVisible.begin(); it != mVisible.end(); ++it)
+			//{
+			//	if (mRenderNodesForViz)
+			//	{
+			//		// render the leaf nodes
+			//		if ((*it)->numAttachedObjects() && 
+			//			!(*it)->numChildren() && 
+			//			((*it)->getAttachedObject(0)->getMovableType() == "Entity") &&
+			//			(*it)->getAttachedObject(0)->isVisible())
+			//		{
+			//			getRenderQueue()->addRenderable((*it));
+			//		}
+
+			//		// addbounding boxes instead of node itself
+			//		//(*it)->_addBoundingBoxToQueue(getRenderQueue());
+			//	}
+			//	// add renderables itself
+			//	if (mRenderNodesContentForViz) 
+			//	{
+			//		(*it)->_addToRenderQueue(cam, getRenderQueue(), false);
+			//	}
+			//}
+		}	
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManager::InitVisibilityCulling(Camera *cam)
+{
+	// reset culling manager stats
+	mVisibilityManager->GetCullingManager()->InitFrame(mVisualizeCulledNodes);
+
+	// set depth pass flag before rendering
+	mIsDepthPassPhase = mUseDepthPass;
+
+	mIsHierarchicalCulling = true; // during hierarchical culling
+
+	// item buffer needs full ambient lighting to use item colors as unique id
+	if (mUseItemBuffer) 
+	{
+		mIsItemBufferPhase = true;
+		setAmbientLight(ColourValue(1,1,1,1));
+	}
+
+
+	// set passes which are stored in render queue 
+	// for rendering AFTER hierarchical culling, i.e., passes which need 
+	// a special rendering order
+
+	mLeavePassesInQueue = 0;
+
+	// if we have the depth pass or use an item buffer, no passes are left in the queue
+	if (1 && !mUseDepthPass && !mUseItemBuffer)
+	{
+		if (mShadowTechnique == SHADOWTYPE_STENCIL_ADDITIVE)
+		{
+			// TODO: remove this pass because it should be processed during hierarchical culling
+			//mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
+
+			mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DECAL;
+			mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_DIFFUSE_SPECULAR;
+			mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
+
+			// just render ambient passes
+			/*** msz: no more IRS_AMBIENT, see OgreSceneManager.h ***/
+			// mIlluminationStage = IRS_AMBIENT; 
+			//getRenderQueue()->setSplitPassesByLightingType(true);
+		}
+
+		if (mShadowTechnique == SHADOWTYPE_STENCIL_MODULATIVE)
+		{
+			mLeavePassesInQueue |= RenderPriorityGroup::SOLID_PASSES_NOSHADOW;
+			mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
+		}
+
+		// transparents should be rendered after hierarchical culling to 
+		// provide front-to-back ordering
+		if (mDelayRenderTransparents)
+		{
+			mLeavePassesInQueue |= RenderPriorityGroup::TRANSPARENT_PASSES;
+		}
+	}
+
+	// skip rendering transparents during the hierarchical culling
+	// (because they will be rendered afterwards)
+	mSkipTransparents = 
+		(mIsDepthPassPhase || (mLeavePassesInQueue & RenderPriorityGroup::TRANSPARENT_PASSES));
+
+	// -- initialise interface for rendering traversal of the hierarchy
+	mHierarchyInterface->SetHierarchyRoot(mKdTree->getRoot());
+
+	// possible two cameras (one for culling, one for rendering)
+	mHierarchyInterface->InitTraversal(mCameraInProgress, 
+		/*mCullCamera ? getCamera("CullCamera") : */NULL,
+		mLeavePassesInQueue);
+
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManager::WriteLog()
+{
+	std::stringstream d;
+
+	d << "Depth pass: " << StringConverter::toString(mUseDepthPass) << ", "
+		<< "Delay transparents: " << StringConverter::toString(mDelayRenderTransparents) << ", "
+		<< "Use optimization: " << StringConverter::toString(mHierarchyInterface->GetTestGeometryForVisibleLeaves()) << ", "
+		<< "Algorithm type: " << mVisibilityManager->GetCullingManagerType() << ", "
+//		<< "Hierarchy nodes: " << mNumOctants << ", " 
+		<< "Traversed nodes: " << mHierarchyInterface->GetNumTraversedNodes() << ", "
+		<< "Rendered nodes: " << mHierarchyInterface->GetNumRenderedNodes() << ", "
+		<< "Query culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumQueryCulledNodes() << ", "
+		<< "Frustum culled nodes: " << mVisibilityManager->GetCullingManager()->GetNumFrustumCulledNodes() << ", "
+		<< "Queries issued: " << mVisibilityManager->GetCullingManager()->GetNumQueriesIssued() << ", "
+//		<< "Found objects: " << (int)mVisible.size() << "\n"
+		;
+
+	LogManager::getSingleton().logMessage(d.str());
+}
+//-----------------------------------------------------------------------
+const Pass *KdTreeSceneManager::_setPass(Pass* pass)
+{
+	if (mRenderMethod == KdTree::KDRM_INTERNAL)
+	{
+		return SceneManager::_setPass(pass);
+	}
+
+	// TODO: setting vertex program is not efficient
+	//Pass *usedPass = ((mIsDepthPassPhase && !pass->hasVertexProgram()) ? mDepthPass : pass); 
+
+	// set depth fill pass if we currently do not make an aabb occlusion query
+	const bool useDepthPass = 
+		(mIsDepthPassPhase && !mHierarchyInterface->IsBoundingBoxQuery());
+
+	Pass *usedPass = useDepthPass ? mDepthPass : pass;
+
+
+	const IlluminationRenderStage savedStage = mIlluminationStage; 
+
+	// set illumination stage to NONE so no shadow material is used 
+	// for depth pass or for occlusion query
+	if (mIsDepthPassPhase || mHierarchyInterface->IsBoundingBoxQuery())
+	{
+		mIlluminationStage = IRS_NONE;
+	}
+
+	// --- set vertex program of current pass in order to set correct depth
+	if (mExecuteVertexProgramForAllPasses && 
+		mIsDepthPassPhase && 
+		pass->hasVertexProgram())
+	{
+		// add vertex program of current pass to depth pass
+		mDepthPass->setVertexProgram(pass->getVertexProgramName());
+
+		if (mDepthPass->hasVertexProgram())
+		{
+			const GpuProgramPtr& prg = mDepthPass->getVertexProgram();
+			// Load this program if not done already
+			if (!prg->isLoaded())
+				prg->load();
+			// Copy params
+			mDepthPass->setVertexProgramParameters(pass->getVertexProgramParameters());
+		}
+	}
+	else if (mDepthPass->hasVertexProgram()) // reset vertex program
+	{
+		mDepthPass->setVertexProgram("");
+	}
+
+	// save old depth write: needed for item buffer
+	const bool IsDepthWrite = usedPass->getDepthWriteEnabled();
+
+	// global option which enables / disables depth writes
+	if (!mEnableDepthWrite)
+	{
+		usedPass->setDepthWriteEnabled(false);
+	}
+	//else if (mIsItemBufferPass) {usedPass = mItemBufferPass;}
+
+
+	//-- set actual pass here
+	const Pass *result = SceneManager::_setPass(usedPass);
+
+
+	// reset depth write
+	if (!mEnableDepthWrite)
+	{
+		usedPass->setDepthWriteEnabled(IsDepthWrite);
+	}
+
+	// reset illumination stage
+	mIlluminationStage = savedStage;
+
+	return result;
+}
+
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+const String KdTreeSceneManagerFactory::FACTORY_TYPE_NAME = "KdTreeSceneManager";
+//-----------------------------------------------------------------------
+void KdTreeSceneManagerFactory::initMetaData(void) const
+{
+	mMetaData.typeName = FACTORY_TYPE_NAME;
+	mMetaData.description = "Scene manager that organises the scene based on a kd-tree";
+	mMetaData.sceneTypeMask = 0xFFFF; // support all types of scenes (hopefully)
+	mMetaData.worldGeometrySupported = false;
+}
+//-----------------------------------------------------------------------
+SceneManager* KdTreeSceneManagerFactory::createInstance(
+	const String& instanceName)
+{
+	return new KdTreeSceneManager(instanceName, visManager);
+}
+//-----------------------------------------------------------------------
+void KdTreeSceneManagerFactory::destroyInstance(SceneManager* instance)
+{
+	delete instance;
+}
 
 } // namespace Ogre
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp	(revision 1173)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp	(revision 1182)
@@ -33,23 +33,4 @@
 		{
 			static_cast<KdTreeSceneManager *>(mCreator)->_updateNode(this);
-		}
-	}
-
-	void KdTreeSceneNode::forceComputeAABB(AxisAlignedBox& aabb) // OBSOLETE !!
-	{
-
-		// Update bounds from own attached objects
-		ObjectMap::iterator i;
-		for (i = mObjectsByName.begin(); i != mObjectsByName.end(); ++i)
-		{
-			// Merge world bounds of each object
-			aabb.merge(i->second->getWorldBoundingBox(true));
-		}
-		// Merge with children
-		ChildNodeMap::iterator child;
-		for (child = mChildren.begin(); child != mChildren.end(); ++child)
-		{
-			KdTreeSceneNode* sceneChild = static_cast<KdTreeSceneNode*>(child->second);
-			sceneChild->forceComputeAABB(aabb);
 		}
 	}
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp	(revision 1177)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp	(revision 1182)
@@ -332,5 +332,6 @@
 	{
 #ifdef KDTREE_DEBUG
-		try
+		MaterialPtr mp = MaterialManager::getSingleton().getByName("aabbHiLite");
+		if (mp.isNull())
 		{
 			ColourValue cv(0.0, 1.0, 0.0);
@@ -339,8 +340,15 @@
 			mp->setDiffuse(cv);
 		}
-		catch (Ogre::Exception&)
-		{
-			// SO FUCKING DON'T CARE !!!
-		}
+		//try
+		//{
+		//	ColourValue cv(0.0, 1.0, 0.0);
+		//	MaterialPtr mp = MaterialManager::getSingleton().create("aabbHiLite","General");
+		//	mp->setSelfIllumination(cv);
+		//	mp->setDiffuse(cv);
+		//}
+		//catch (Ogre::Exception&)
+		//{
+		//	// SO FUCKING DON'T CARE !!!
+		//}
 #endif
 		try
@@ -645,4 +653,6 @@
 		unsigned long t1, t2, t3, t4;
 		//AxisAlignedBox aabb;
+
+		mStats.clear();
 		
 		// data we want to collect
@@ -657,4 +667,5 @@
 		t3 = timer->getMicroseconds(); // DEBUG
 
+		mStats.mNumSceneNodes = nObjects;
 		// <DEBUG>
 		//lm->logMessage("# of perfect splits " + StringConverter::toString(events.size()));
@@ -685,11 +696,21 @@
 		t4 = timer->getMicroseconds(); // DEBUG
 
+		String method = "Invalid";
+		if (mBuildMethod == KDBM_RECURSIVE)
+			method = "Recursive";
+		else if (mBuildMethod == KDBM_PRIORITYQUEUE)
+			method = "Priority Queue";
+
 		mBuildLog->logMessage("######## SAH Statistics ########");
+		mBuildLog->logMessage("Build Method: " + method);
 		mBuildLog->logMessage("Time for events build: " + StringConverter::toString(t2 - t1) + "µs");
 		mBuildLog->logMessage("Time for events sort: " + StringConverter::toString(t3 - t2) + "µs");
 		mBuildLog->logMessage("Time for tree build: " + StringConverter::toString(t4 - t3) + "µs");
 		mBuildLog->logMessage("Total time: " + StringConverter::toString(t4 - t1) + "µs");
-		mBuildLog->logMessage("######## SAH Statistics ########");
-		calcCost();
+		mBuildLog->logMessage("Number of Objects: " + StringConverter::toString(mStats.mNumSceneNodes));
+		mBuildLog->logMessage("Number of Leaves: " + StringConverter::toString(mStats.mNumLeaves));
+		mBuildLog->logMessage("Number of Nodes: " + StringConverter::toString(mStats.mNumNodes));
+		mBuildLog->logMessage("Total cost: " + StringConverter::toString(calcCost()));
+		mBuildLog->logMessage("################################");
 	}
 
@@ -847,4 +868,7 @@
 				it++;
 			}
+			// update stats
+			++ mStats.mNumNodes;
+			++ mStats.mNumLeaves;
 			return leaf;
 		}
@@ -930,4 +954,7 @@
 				branch->mRight = recBuild(eventsRight, nBothS + nRightS, best.bright, branch);
 			}
+
+			// update stats
+			++ mStats.mNumNodes;
 
 			//assert(branch->mRight || branch->mLeft);
@@ -1008,4 +1035,7 @@
 				if (!topNode)
 					topNode = leaf;
+				// update stats
+				++ mStats.mNumNodes;
+				++ mStats.mNumLeaves;
 			}
 
@@ -1172,4 +1202,9 @@
 #endif
 				}
+				// cleanup
+				else
+				{
+					delete eventsLeft;
+				}
 				if (eventsRight->size() > 0)
 				{
@@ -1193,8 +1228,17 @@
 #endif
 				}
+				// cleanup
+				else
+				{
+					delete eventsRight;
+				}
 
 				newNode = branch;
 				if (!topNode)
 					topNode = branch;
+
+
+				// update stats
+				++ mStats.mNumNodes;
 			}
 
@@ -1385,12 +1429,10 @@
 	}
 
-	void KdTree::calcCost()
-	{
-		Real cost = 0;
+	Real KdTree::calcCost()
+	{
 		if (mKdRoot)
-			cost = calcCost(mKdRoot, PlaneEvent::surfaceArea(mKdRoot->mAABB));
-
-		//LogManager::getSingleton().logMessage("#@#@#@ One KdTree: " + StringConverter::toString(cost));
-		mBuildLog->logMessage("#@#@#@ One KdTree: " + StringConverter::toString(cost));
+			return calcCost(mKdRoot, PlaneEvent::surfaceArea(mKdRoot->mAABB));
+		else
+			return 0;
 	}
 
