Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreOctreeHierarchyInterface.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreOctreeHierarchyInterface.h	(revision 2292)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgreOctreeHierarchyInterface.h	(revision 2306)
@@ -63,4 +63,8 @@
 					   GtpVisibility::HierarchyNodeContainer &nodes);
 
+	void PullUpLastVisited(GtpVisibility::HierarchyNode *node, const int frameId) const;
+	void DetermineVisibilityRatio(GtpVisibility::HierarchyNode *node) const;
+	float GetNodeVisibilityRatio(GtpVisibility::HierarchyNode *node) const;
+
 protected:
 
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgrePlatformHierarchyInterface.h
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgrePlatformHierarchyInterface.h	(revision 2280)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/include/OgrePlatformHierarchyInterface.h	(revision 2306)
@@ -26,5 +26,6 @@
 {
 public:
-	/** Construction taking the current scene manager and the current rendersystem as argument
+	/** Construction taking the current scene manager and the 
+		current rendersystem as argument
 		@param sm current scene manager
 		@param rsys current render system 
@@ -36,5 +37,5 @@
 		@return the next occlusion query
 	*/
-	GtpVisibility::OcclusionQuery *GetNextOcclusionQuery();
+	virtual GtpVisibility::OcclusionQuery *GetNextOcclusionQuery();
 		
 	/** Sets the current camera used for the rendering.
@@ -124,4 +125,9 @@
 									 bool includeChildren) = 0;
 
+	void PullUpLastVisited(GtpVisibility::HierarchyNode *node, const int frameId) const {}
+	void DetermineVisibilityRatio(GtpVisibility::HierarchyNode *node) const {}
+
+	float GetNodeVisibilityRatio(GtpVisibility::HierarchyNode *node) const { return 1.0f;}
+
 protected:
 	/** Renders the given geometry 
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOctreeHierarchyInterface.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOctreeHierarchyInterface.cpp	(revision 2292)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOctreeHierarchyInterface.cpp	(revision 2306)
@@ -31,20 +31,17 @@
 		Octree *nextChild;
 
-		if ((nextChild = octree->mChildren[0][0][0]) != NULL)
-			mDistanceQueue->push(nextChild);
-		if ((nextChild = octree->mChildren[0][0][1]) != NULL)
-			mDistanceQueue->push(nextChild);
-		if ((nextChild = octree->mChildren[0][1][0]) != NULL)
-			mDistanceQueue->push(nextChild);
-		if ((nextChild = octree->mChildren[0][1][1]) != NULL)
-           	mDistanceQueue->push(nextChild);
-		if ((nextChild = octree->mChildren[1][0][0]) != NULL)
-			mDistanceQueue->push(nextChild);
-		if ((nextChild = octree->mChildren[1][0][1]) != NULL)
-			mDistanceQueue->push(nextChild);
-		if ((nextChild = octree->mChildren[1][1][0]) != NULL)
-			mDistanceQueue->push(nextChild);
-		if ((nextChild = octree->mChildren[1][1][1]) != NULL)
-			mDistanceQueue->push(nextChild);
+		for (int z = 0; z < 2; ++ z)
+		{	
+			for (int y = 0; y < 2; ++ y)
+			{
+				for (int x = 0; x < 2; ++ x)
+				{
+					nextChild = octree->mChildren[x][y][z];
+	
+					if (nextChild)
+                        GetQueue()->push(nextChild);
+				}
+            }
+        }
 	}
 }
@@ -63,4 +60,109 @@
 	nodes.reserve(8);
 
+	for (int z = 0; z < 2; ++ z)
+	{	
+		for (int y = 0; y < 2; ++ y)
+		{
+			for (int x = 0; x < 2; ++ x)
+			{
+				if ((child = octree->mChildren[x][y][z]) != NULL)
+				{
+					nodes.push_back(child);
+				}
+			}
+		}
+	}
+
+	if (nodes.empty())
+		return NULL;
+
+	int r = (int)(((float)rand() / RAND_MAX) * ((float)nodes.size() - 0.5f));
+
+	return GetRandomLeaf(nodes[r]);
+}
+//-----------------------------------------------------------------------
+bool OctreeHierarchyInterface::IsLeaf(GtpVisibility::HierarchyNode *node) const
+{
+	Octree *octree = static_cast<Octree *>(node);
+
+	// HACK: if there are subtrees, they are empty => we are not interested in them
+	return octree->numNodes() == (int)octree->mNodes.size();
+}
+//-----------------------------------------------------------------------
+bool OctreeHierarchyInterface::HasGeometry(GtpVisibility::HierarchyNode *node) const
+{
+	return !(static_cast<Octree *>(node))->mNodes.empty();
+}
+//-----------------------------------------------------------------------
+float OctreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const
+{
+	const Vector3 bmin = static_cast<Octree *>(node)->mBox.getMinimum();
+	const Vector3 bmax = static_cast<Octree *>(node)->mBox.getMaximum();
+
+	const Vector3 pos = (bmax - bmin) * 0.5f + bmin;
+	
+	return (mCameraPosition - pos).squaredLength();
+}
+//-----------------------------------------------------------------------
+void OctreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node, 
+											  const bool visible) const
+{
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	static_cast<Octree *>(node)->setOctreeVisible(visible);
+#endif
+}
+//-----------------------------------------------------------------------
+void OctreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node, 
+											  const unsigned int frameId) const
+{
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	static_cast<Octree *>(node)->setLastVisited(frameId);
+#endif
+}
+//-----------------------------------------------------------------------
+void OctreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) const
+{		
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	Octree *octant = static_cast<Octree *>(node);
+
+	while (octant && !octant->isOctreeVisible())
+	{
+		octant->setOctreeVisible(true);
+		octant = octant->getParent();
+	}
+#endif
+}
+//-----------------------------------------------------------------------
+void OctreeHierarchyInterface::PullUpLastVisited(GtpVisibility::HierarchyNode *node, const int frameId) const
+{		
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	Octree *octant = static_cast<Octree *>(node);
+
+	while (octant && (octant->lastVisited() != frameId))
+	{
+		octant->setLastVisited(frameId);
+		octant = octant->getParent();
+	}
+#endif
+}
+//-----------------------------------------------------------------------
+void OctreeHierarchyInterface::DetermineFullVisibility(GtpVisibility::HierarchyNode *node) const
+{		
+	Octree *octant = static_cast<Octree *>(node);
+
+	// node not visited in this frame => no change
+	if (octant->lastVisited() != mFrameId) 
+		return;
+
+	// leaf node: terminate recursion
+	if (IsLeaf(node))
+	{
+		octant->setOctreeFullyVisible(octant->isOctreeVisible());	
+		return;
+	}
+
+	octant->setOctreeFullyVisible(true);
+	Octree *nextChild;
+	
 	for (int i = 0; i < 8; ++ i)
 	{
@@ -68,76 +170,42 @@
 		int y = (i & 2) / 2;
 		int z = i & 1;
-	
-		if ((child = octree->mChildren[x][y][z]) != NULL)
+
+		nextChild = octant->mChildren[x][y][z];
+
+		if (!nextChild)
+			continue;
+		
+		// recursive traversal
+		DetermineFullVisibility(nextChild);
+		
+		// this leaf is not fully visible
+		if (!nextChild->isOctreeFullyVisible())
 		{
-			nodes.push_back(child);
+			octant->setOctreeFullyVisible(false);
 		}
 	}
-
-	if (nodes.empty())
-		return NULL;
-
-	int r = (int)(((float)rand() / RAND_MAX) * ((float)nodes.size() - 0.5f));
-
-	return GetRandomLeaf(nodes[r]);
-}
-//-----------------------------------------------------------------------
-bool OctreeHierarchyInterface::IsLeaf(GtpVisibility::HierarchyNode *node) const
-{
-	Octree *octree = static_cast<Octree *>(node);
-
-	// HACK: if there are subtrees, they are empty => we are not interested in them
-	return octree->numNodes() == (int)octree->mNodes.size();
-}
-//-----------------------------------------------------------------------
-bool OctreeHierarchyInterface::HasGeometry(GtpVisibility::HierarchyNode *node) const
-{
-	return !(static_cast<Octree *>(node))->mNodes.empty();
-}
-//-----------------------------------------------------------------------
-float OctreeHierarchyInterface::GetSquaredDistance(GtpVisibility::HierarchyNode *node) const
-{
-	const Vector3 bmin = static_cast<Octree *>(node)->mBox.getMinimum();
-	const Vector3 bmax = static_cast<Octree *>(node)->mBox.getMaximum();
-
-	const Vector3 pos = (bmax - bmin) * 0.5f + bmin;
-	
-	return (mCameraPosition - pos).squaredLength();
-}
-//-----------------------------------------------------------------------
-void OctreeHierarchyInterface::SetNodeVisible(GtpVisibility::HierarchyNode *node, 
-											  const bool visible) const
-{
-#ifdef GTP_VISIBILITY_MODIFIED_OGRE
-	static_cast<Octree *>(node)->setOctreeVisible(visible);
-#endif
-}
-//-----------------------------------------------------------------------
-void OctreeHierarchyInterface::SetLastVisited(GtpVisibility::HierarchyNode *node, 
-											  const unsigned int frameId) const
-{
-#ifdef GTP_VISIBILITY_MODIFIED_OGRE
-	static_cast<Octree *>(node)->setLastVisited(frameId);
-#endif
-}
-//-----------------------------------------------------------------------
-void OctreeHierarchyInterface::PullUpVisibility(GtpVisibility::HierarchyNode *node) const
+}
+//-----------------------------------------------------------------------
+void OctreeHierarchyInterface::DetermineVisibilityRatio(GtpVisibility::HierarchyNode *node) const
 {		
-#ifdef GTP_VISIBILITY_MODIFIED_OGRE
-	Octree *octant = static_cast<Octree *>(node);
-
-	while (octant && !octant->isOctreeVisible())
-	{
-		octant->setOctreeVisible(true);
-		octant = octant->getParent();
-	}
-#endif
-}
-//-----------------------------------------------------------------------
-/*void OctreeHierarchyInterface::PullUpFullVisibility(GtpVisibility::HierarchyNode *node) const
-{		
-#ifdef GTP_VISIBILITY_MODIFIED_OGRE
-	Octree *octant = static_cast<Octree *>(node);
-
+	Octree *octant = static_cast<Octree *>(node);
+
+	// node not visited in this frame => no change
+	if (octant->lastVisited() != mFrameId)
+		return;
+	
+	// leaf node: terminate recursion
+	if (IsLeaf(node))
+	{
+		octant->setNumLeaves(1);	
+		octant->setNumVisibleLeaves(octant->isOctreeVisible() ? 1 : 0);	
+		return;
+	}
+
+	int numVisibleLeaves = 0;
+	int numLeaves = 0;
+
+	Octree *nextChild;
+	
 	for (int i = 0; i < 8; ++ i)
 	{
@@ -145,51 +213,20 @@
 		int y = (i & 2) / 2;
 		int z = i & 1;
+
+		nextChild = octant->mChildren[x][y][z];
+
+		if (!nextChild)
+			continue;
 		
-		if ((nextChild = octant->mChildren[x][y][z]) != NULL)
-		{
-			DetermineFullVisibility(nextChild);
-			// this leaf is not fully visible => break
-			if (!nextChild->isOctreeFullyVisible())
-				octant->setOctreeFullyVisible(false);
-		}
-	}
-
-	while (octant && !octant->isOctreeVisible())
-	{
-		octant->setOctreeVisible(true);
-		octant = octant->getParent();
-	}
-#endif
-}*/
-//-----------------------------------------------------------------------
-void OctreeHierarchyInterface::DetermineFullVisibility(GtpVisibility::HierarchyNode *node) const
-{		
-	Octree *octant = static_cast<Octree *>(node);
-
-	// leaf node: terminate recursion
-	if (IsLeaf(node))
-	{
-		octant->setOctreeFullyVisible(octant->isOctreeVisible());	
-		return;
-	}
-
-	octant->setOctreeFullyVisible(true);
-	
-	Octree *nextChild;
-	
-	for (int i = 0; i < 8; ++ i)
-	{
-		int x = (i & 4) / 4;
-		int y = (i & 2) / 2;
-		int z = i & 1;
+		// recursive traversal
+		DetermineVisibilityRatio(nextChild);
 		
-		if ((nextChild = octant->mChildren[x][y][z]) != NULL)
-		{
-			DetermineFullVisibility(nextChild);
-			// this leaf is not fully visible => break
-			if (!nextChild->isOctreeFullyVisible())
-				octant->setOctreeFullyVisible(false);
-		}
-	}
+		// this leaf is not fully visible
+		numLeaves += nextChild->getNumLeaves();
+		numVisibleLeaves += nextChild->getNumVisibleLeaves();
+	}
+
+	octant->setNumLeaves(numLeaves);
+	octant->setNumVisibleLeaves(numVisibleLeaves);
 }
 //-----------------------------------------------------------------------
@@ -249,5 +286,16 @@
 {
 #ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	//return static_cast<Octree *>(node)->getVisibilityRatio() > 0.9f;
 	return static_cast<Octree *>(node)->isOctreeFullyVisible();
+#else
+	return true;
+#endif
+}
+//-----------------------------------------------------------------------
+float OctreeHierarchyInterface::GetNodeVisibilityRatio(GtpVisibility::HierarchyNode *node) const
+{
+#ifdef GTP_VISIBILITY_MODIFIED_OGRE
+	return static_cast<Octree *>(node)->getVisibilityRatio();
+	//return static_cast<Octree *>(node)->isOctreeFullyVisible();
 #else
 	return true;
@@ -329,13 +377,15 @@
 			Octree *octree = static_cast<Octree *>(node);
 			
-			for (int i = 0; i < 8; ++ i)
-			{
-				int x = (i & 4) / 4;
-				int y = (i & 2) / 2;
-				int z = i & 1;
-	
-				if ((child = octree->mChildren[x][y][z]) != NULL)
+			for (int z = 0; z < 2; ++ z)
+			{	
+				for (int y = 0; y < 2; ++ y)
 				{
-					tStack.push(child);
+					for (int x = 0; x < 2; ++ x)
+					{
+						if ((child = octree->mChildren[x][y][z]) != NULL)
+						{
+							tStack.push(child);
+						}
+					}
 				}
 			}
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgrePlatformHierarchyInterface.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgrePlatformHierarchyInterface.cpp	(revision 2278)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgrePlatformHierarchyInterface.cpp	(revision 2306)
@@ -141,5 +141,6 @@
 }
 //-----------------------------------------------------------------------
-void PlatformHierarchyInterface::InitTraversal(Camera *cam, Camera *cullCam, 
+void PlatformHierarchyInterface::InitTraversal(Camera *cam, 
+											   Camera *cullCam, 
 											   int leavePassesInQueue)
 {
