Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h	(revision 1170)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTree.h	(revision 1173)
@@ -27,5 +27,4 @@
 #include <stack>
 
-//#include "OgreKdTreeHierarchyInterface.h"
 
 
@@ -264,7 +263,4 @@
 			*/
 			bool isNodeVisible(void) { return mVisible; };
-			/** Gets this node's parent (NULL if this is the root).
-			*/	
-			KdTree::Node *getParent(void) { return mParent; };
 			/** Frame id when this octree was last rendered. 
 			@return last rendered frame id
@@ -275,9 +271,13 @@
 			*/
 			void setLastRendered(unsigned int frameid) { mLastRendered = frameid; };
-
-			/* do we need this? */
-			/** Returns real extent of the octree, i.e., the merged extent of the bounding boxes. 
+			/** Gets this node's parent (NULL if this is the root).
+			*/	
+			KdTree::Branch *getParent(void) { return mParent; };
+			/** Returns real extent of the kdtree, i.e., the merged extent of the bounding boxes. 
 			*/
-			//AxisAlignedBox _getWorldAABB(void) const = 0;
+			AxisAlignedBox _getWorldAABB(void) const { return mWorldAABB; };
+			/** Updates bound of the real aabb of kdtree
+			*/
+			virtual void _updateBounds() = 0;
 
 
@@ -290,6 +290,6 @@
 			// for the CHC hierarchy interface
 			/** the real extent of the node. */
-			//AxisAlignedBox mWorldAABB;
-
+			AxisAlignedBox mWorldAABB;
+			
 			unsigned int mLastRendered;
 			unsigned int mLastVisited;
@@ -323,4 +323,20 @@
 			// a branch never has geometry
 			virtual bool hasGeometry() const { return false; };
+
+			// branches do not posses geometry => just merge child aabbs
+			virtual void _updateBounds()
+			{
+				// reset box
+				mWorldAABB.setNull();
+
+				if (mLeft)
+					mWorldAABB.merge(mLeft->_getWorldAABB());
+				if (mRight)
+					mWorldAABB.merge(mRight->_getWorldAABB());
+
+				// update parent recursively
+				if (mParent)
+					mParent->_updateBounds();
+			}
 			
 			Node * mLeft;
@@ -347,4 +363,7 @@
 			// a leaf has geometry when it has renderables
 			virtual bool hasGeometry() const { return !mKdRenderables.empty(); };
+
+			// update the world aabb based on the contained geometry
+			virtual void _updateBounds();
 
 			virtual void remove(KdRenderable * rend)
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdRenderable.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdRenderable.h	(revision 1163)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdRenderable.h	(revision 1173)
@@ -12,4 +12,5 @@
 
 #include "OgreKdTree.h"
+#include "HierarchyInterface.h"
 
 namespace Ogre
@@ -33,4 +34,7 @@
 		// put all objects this element holds in the renedering queue
 		virtual void queueObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters) = 0;
+
+		// place all entities in geometry queue (for CHC)
+		virtual void getGeometryList(GtpVisibility::GeometryVector *geometryList) = 0;
 
 		// return a bounding box enclosing all objects
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h	(revision 1170)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneManager.h	(revision 1173)
@@ -28,5 +28,4 @@
 	public:
 		KdTreeSceneManager(const String& name, GtpVisibility::VisibilityManager *vm);
-		//KdTreeSceneManager(const String& name, int maxdepth);
 		~KdTreeSceneManager(void);
 
@@ -34,8 +33,9 @@
 		virtual SceneNode* createSceneNode(void);
 		virtual SceneNode* createSceneNode(const String& name);
-		void init( int maxdepth );
-		void walkTree(KdTree * node, Camera *cam);
 
 		virtual void _findVisibleObjects(Camera *cam, bool onlyShadowCasters);
+
+		virtual void _renderNodes(const KdRenderableList& nodelist, Camera * cam,
+			bool onlyShadowCasters, int leavePassesInQueue);
 
 		virtual void setShowBoxes(bool showboxes);
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneNode.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneNode.h	(revision 1163)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreKdTreeSceneNode.h	(revision 1173)
@@ -37,4 +37,7 @@
 		virtual void queueObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters);
 
+		// place all entities in geometry queue (for CHC)
+		virtual void getGeometryList(GtpVisibility::GeometryVector *geometryList);
+
 		// return a bounding box enclosing all objects
 		virtual AxisAlignedBox getBoundingBox() const;
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp	(revision 1170)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneManager.cpp	(revision 1173)
@@ -347,4 +347,25 @@
 	}
 
+	// 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();
+#endif
+		KdRenderableList::const_iterator it = nodelist.begin();
+		KdRenderableList::const_iterator end = nodelist.end();
+		while (it != end)
+		{
+			(*it)->queueObjects(cam, getRenderQueue(), onlyShadowCasters);
+			it++;
+		}
+
+		SceneManager::_renderVisibleObjects();
+
+	}
+
 	//-----------------------------------------------------------------------
 	//-----------------------------------------------------------------------
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeHierarchyInterface.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeHierarchyInterface.cpp	(revision 1170)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeHierarchyInterface.cpp	(revision 1173)
@@ -8,4 +8,5 @@
 */
 
+#include "OgreKdRenderable.h"
 #include "OgreKdTreeSceneManager.h"
 #include "OgreKdTreeHierarchyInterface.h"
@@ -51,22 +52,49 @@
 void KdTreeHierarchyInterface::RenderNode(GtpVisibility::HierarchyNode *node)
 {
-	/*** TODO ***/
+	KdTree::Node * kdnode = KDNODEPTR_CAST(node);
+	if (kdnode->lastRendered() != mFrameId)
+	{
+		kdnode->setLastRendered(mFrameId);
+		KdTreeSceneManager * ksm = static_cast<KdTreeSceneManager *>(mSceneManager);
+
+		// render only if the node is a leaf
+		if (kdnode->isLeaf())
+		{
+			ksm->_renderNodes(KDLEAFPTR_CAST(node)->mKdRenderables, mCamera, 
+				mOnlyShadowCasters, mLeavePassesInQueue);
+		}	
+
+		mVisibleNodes.push_back(node);
+	}
 }
 
 void KdTreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) const
 {
-	/*** TODO ***/
+	KdTree::Node * kdnode = KDNODEPTR_CAST(node);
+
+	while (kdnode && !kdnode->isNodeVisible())
+	{
+		kdnode->setNodeVisible(true);
+		kdnode = kdnode->getParent();
+	}
 }
 
 float KdTreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const
 {
-	/*** TODO ***/
-	return 0.0;
+	const Vector3 pos = KDNODEPTR_CAST(node)->mAABB.getCenter();
+	return (mCameraPosition - pos).squaredLength();
 }
 
 AxisAlignedBox * KdTreeHierarchyInterface::GetBoundingBox(GtpVisibility::HierarchyNode *node)
 {
-	/*** TODO ***/
-	return new AxisAlignedBox();
+	// reuse box if node is the same
+	// only create renderable bounding box for new node
+	if (node != mSavedNode)
+	{
+		mSavedNode = node;
+		mBox = KDNODEPTR_CAST(node)->_getWorldAABB();
+	}
+
+	return &mBox;
 }
 
@@ -78,22 +106,20 @@
 void KdTreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node, const bool visible) const
 {
-	/*** TODO ***/
+	KDNODEPTR_CAST(node)->setNodeVisible(visible);
 }
 
 bool KdTreeHierarchyInterface::IsNodeVisible(GtpVisibility::HierarchyNode *node) const
 {
-	/*** TODO ***/
-	return true;
+	return KDNODEPTR_CAST(node)->isNodeVisible();
 }
 
 void KdTreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node, const unsigned int frameId) const
 {
-	/*** TODO ***/
+	KDNODEPTR_CAST(node)->setLastVisited(frameId);
 }
 
 unsigned int KdTreeHierarchyInterface::LastVisited(GtpVisibility::HierarchyNode *node) const
 {
-	/*** TODO ***/
-	return 0;
+	return KDNODEPTR_CAST(node)->lastVisited();
 }
 
@@ -101,5 +127,17 @@
 												   GtpVisibility::CullingType type) const
 {
-	/*** TODO ***/
+	WireBoundingBox *box = KDNODEPTR_CAST(node)->getWireBoundingBox();
+
+	if (type == GtpVisibility::FRUSTUM_CULLED)
+	{
+		box->setMaterial("FrustumCulledNodesMaterial");
+	}
+	else // type == GtpVisibility::QUERY_CULLED
+	{
+		box->setMaterial("QueryCulledNodesMaterial");
+	}
+
+	// TODO: maybe boxlist?
+	dynamic_cast<KdTreeSceneManager *>(mSceneManager)->getRenderQueue()->addRenderable(box);
 }
 
@@ -108,5 +146,16 @@
 												   bool includeChildren) 
 {
-	/*** TODO ***/
+	KdTree::Node * kdnode = KDNODEPTR_CAST(node);
+	if (kdnode->isLeaf())
+	{
+		KdTree::Leaf * kdleaf = KDLEAFPTR_CAST(node);
+		KdRenderableList::iterator it = kdleaf->mKdRenderables.begin();
+		KdRenderableList::iterator end = kdleaf->mKdRenderables.end();
+		while (it != end)
+		{
+			(*it)->getGeometryList(geometryList);
+			it++;
+		}
+	}
 }
 
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp	(revision 1163)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTreeSceneNode.cpp	(revision 1173)
@@ -140,4 +140,23 @@
 	}
 
+	void KdTreeSceneNode::getGeometryList(GtpVisibility::GeometryVector *geometryList)
+	{
+		SceneNode::ObjectIterator objIt = getAttachedObjectIterator();
+
+		while (objIt.hasMoreElements())
+		{
+			MovableObject *movable = objIt.getNext();
+
+			// we are interested only in the entities, i.e., instances of geometry
+			if (movable->getMovableType() == "Entity")
+			{
+				Entity *ent = static_cast<Entity *>(movable);
+				//std::stringstream d; d << "ent " << ent->getName(); 
+				//LogManager::getSingleton().logMessage(d.str());
+				geometryList->push_back(ent);
+			}
+		}
+	}
+
 	AxisAlignedBox KdTreeSceneNode::getBoundingBox() const
 	{
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp	(revision 1170)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreKdTree.cpp	(revision 1173)
@@ -1496,3 +1496,23 @@
 		mKdRenderables.clear();
 	}
-}
+
+	// update the world aabb based on the contained geometry
+	void KdTree::Leaf::_updateBounds()
+	{
+		// reset box
+		mWorldAABB.setNull();
+
+		// merge boxes from attached geometry
+		KdRenderableList::iterator it = mKdRenderables.begin();
+		KdRenderableList::iterator end = mKdRenderables.end();
+		while (it != end)
+		{
+			mWorldAABB.merge((*it)->getBoundingBox());
+			it++;
+		}
+
+		// update parent recursively
+		if (mParent)
+			mParent->_updateBounds();
+	}
+} // namespace Ogre
