Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/src/CoherentHierarchicalCullingManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/src/CoherentHierarchicalCullingManager.cpp	(revision 2184)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/src/CoherentHierarchicalCullingManager.cpp	(revision 2258)
@@ -12,6 +12,6 @@
 }
 //-----------------------------------------------------------------------
-CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager(const unsigned int 
-																	   assumedVisibility)
+CoherentHierarchicalCullingManager::CoherentHierarchicalCullingManager(
+														const unsigned int assumedVisibility)
 {
 	SetAssumedVisibility(assumedVisibility);
@@ -67,5 +67,4 @@
 		if (!mHierarchyInterface->GetQueue()->empty())
 		{
-			//Ogre::LogManager::getSingleton().logMessage("traversal");
 			HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
 			mHierarchyInterface->GetQueue()->pop();
@@ -96,7 +95,4 @@
 					DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
 
-				//if (mHierarchyInterface->LastVisited(node) >= mHierarchyInterface->GetFrameId())
-				//	Ogre::LogManager::getSingleton().logMessage("error");
-				
 				if (skipQuery)
 				{
@@ -115,5 +111,5 @@
 				// update node's visited flag
 				mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
-				//Ogre::LogManager::getSingleton().logMessage("here999");
+				
 				// skip testing previously visible nodes without geometry
 				if (issueQuery)
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/src/GtpVisibility.vcproj
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/src/GtpVisibility.vcproj	(revision 2183)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/src/GtpVisibility.vcproj	(revision 2258)
@@ -315,4 +315,7 @@
 			</File>
 			<File
+				RelativePath=".\RandomUpdateCullingManager.cpp">
+			</File>
+			<File
 				RelativePath="..\src\StopAndWaitCullingManager.cpp">
 			</File>
@@ -360,4 +363,7 @@
 			<File
 				RelativePath="..\include\QueryManager.h">
+			</File>
+			<File
+				RelativePath="..\include\RandomUpdateCullingManager.h">
 			</File>
 			<File
Index: GTP/trunk/Lib/Vis/OnlineCullingCHC/src/RandomUpdateCullingManager.cpp
===================================================================
--- GTP/trunk/Lib/Vis/OnlineCullingCHC/src/RandomUpdateCullingManager.cpp	(revision 2258)
+++ GTP/trunk/Lib/Vis/OnlineCullingCHC/src/RandomUpdateCullingManager.cpp	(revision 2258)
@@ -0,0 +1,187 @@
+#include "RandomUpdateCullingManager.h"
+#include <OgreLogManager.h>
+
+namespace GtpVisibility {
+
+//-----------------------------------------------------------------------
+RandomUpdateCullingManager::RandomUpdateCullingManager()
+{
+	SetAssumedVisibility(0);
+	// initialise random generator in case we use assumed visibility
+	srand(time(NULL));
+}
+//-----------------------------------------------------------------------
+RandomUpdateCullingManager::RandomUpdateCullingManager(
+			const unsigned int assumedVisibility)
+{
+	SetAssumedVisibility(assumedVisibility);
+	// initialise random generator in case we use assumed visibility
+	srand(time(NULL));
+}
+//-----------------------------------------------------------------------
+void RandomUpdateCullingManager::RenderScene()
+{
+	QueryQueue queryQueue;
+	unsigned int visiblePixels = 0;
+	
+	/////////////
+	//-- PART 1: process finished occlusion queries
+
+	while (!mHierarchyInterface->GetQueue()->empty() || !queryQueue.empty())
+	{
+		bool resultAvailable = false;
+
+		//-- only wait for result if there are no nodes to process
+		while (!queryQueue.empty() && 
+				queryQueue.front().second->GetQueryResult(visiblePixels, 
+				mHierarchyInterface->GetQueue()->empty()))
+		{
+        	HierarchyNode *node = queryQueue.front().first;
+			
+			queryQueue.pop();
+			
+			if (visiblePixels > mVisibilityThreshold)
+			{
+				// in case geometry is in interior node: 
+				// ensure that we only traverse once
+				if (!mHierarchyInterface->IsNodeVisible(node))
+				{
+					mHierarchyInterface->TraverseNode(node);
+				}
+
+				mHierarchyInterface->PullUpVisibility(node);
+			}
+			else
+			{	
+				mHierarchyInterface->SetNodeVisible(node, false);
+
+				++ mNumQueryCulledNodes;
+				
+				if (mVisualizeCulledNodes)
+				{
+					mHierarchyInterface->VisualizeCulledNode(node, QUERY_CULLED);
+				}
+			}
+		}
+		
+		//-- PART 2: hierarchical traversal
+		if (!mHierarchyInterface->GetQueue()->empty())
+		{
+			HierarchyNode *node = mHierarchyInterface->GetQueue()->top();
+			mHierarchyInterface->GetQueue()->pop();
+				
+			bool intersects = false;
+
+			if (!mHierarchyInterface->CheckFrustumVisible(node, intersects))
+			{
+				++ mNumFrustumCulledNodes;	
+				if (mVisualizeCulledNodes)
+				{
+					mHierarchyInterface->VisualizeCulledNode(node, FRUSTUM_CULLED);
+				}
+			}
+			//-- if node intersects near plane, skip query because wrong results possible
+			else if (intersects)
+			{
+				SkipQuery(node);
+			}
+			else
+			{
+				// identify previously visible nodes
+				const bool wasVisible = mHierarchyInterface->IsNodeVisible(node) && 
+					(mHierarchyInterface->LastVisited(node) == mHierarchyInterface->GetFrameId() - 1);
+				
+				// if we assume node to be visible in this frame => skip query 
+				const bool skipQuery = wasVisible && (mAssumedVisibility > 0) && 
+					DecideVisible(node) && mHierarchyInterface->HasGeometry(node);
+
+				if (skipQuery)
+				{
+					SkipQuery(node);
+					continue;
+				}
+				
+				if (mHierarchyInterface->IsNodeFullyVisible(node))
+				{
+					// node fully visible => test only random leaves
+					/*for (int i = 0; i < mRandomCandidates; ++ i)
+					{
+						HierarchyNode *randomLeaf = mHierarchyInterface->GetRandomLeaf(node);
+
+						mHierarchyInterface->SetNodeVisible(randomLeaf, false);
+
+						// update node's visited flag
+						mHierarchyInterface->SetLastVisited(randomLeaf, 
+															mHierarchyInterface->GetFrameId());
+
+						queryQueue.push(QueryPair(node, 
+							mHierarchyInterface->IssueNodeOcclusionQuery(node, wasVisible)));
+					}*/
+
+					continue;
+				}
+
+                // identify nodes that we cannot skip queries for
+				// geometry not only in leaves => test for renderable geometry
+				const bool issueQuery = !wasVisible || mHierarchyInterface->HasGeometry(node);
+							
+				// reset node's visibility classification
+				// set visibe if geometry in node => we only traverse the node once
+				mHierarchyInterface->SetNodeVisible(node, wasVisible && issueQuery);
+
+				// update node's visited flag
+				mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
+				
+
+				// skip testing previously visible nodes without geometry
+				if (issueQuery)
+				{
+					++ mNumQueriesIssued;
+					
+					queryQueue.push(QueryPair(node, mHierarchyInterface->
+						IssueNodeOcclusionQuery(node, wasVisible)));
+				}
+				
+				// always traverse a node if it was visible
+				if (wasVisible)
+				{
+					mHierarchyInterface->TraverseNode(node);
+				}
+			}
+		}
+	}
+}
+//-----------------------------------------------------------------------
+void RandomUpdateCullingManager::SetAssumedVisibility(const unsigned int assumedVisibility)
+{
+	mAssumedVisibility = assumedVisibility;
+	
+	mThreshold = 0;
+
+	if (mAssumedVisibility > 0)
+	{
+		mThreshold = RAND_MAX - RAND_MAX / mAssumedVisibility;
+		if (mAssumedVisibility > 100) // fix visibility
+			mThreshold = RAND_MAX;
+	}
+	//std::stringstream d; d << "*** setting assumed vis: " << mAssumedVisibility; Ogre::LogManager::getSingleton().logMessage(d.str());
+}
+//-----------------------------------------------------------------------
+inline bool RandomUpdateCullingManager::DecideVisible(HierarchyNode *node) const
+{
+	//bool result = rand() < mThreshold; std::stringstream d; d << "Assumed vis: " << mAssumedVisibility << ", result: " << result;
+	//Ogre::LogManager::getSingleton().logMessage(d.str()); return result;
+	
+	return rand() < mThreshold;
+}
+//-----------------------------------------------------------------------
+inline void RandomUpdateCullingManager::SkipQuery(HierarchyNode *node) const
+{
+	// -- set node to be visible in this frame, then traverse it
+	mHierarchyInterface->SetLastVisited(node, mHierarchyInterface->GetFrameId());
+	
+	mHierarchyInterface->PullUpVisibility(node);			
+	mHierarchyInterface->TraverseNode(node);
+}
+
+} // namespace GtpVisibility
