Index: trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingSceneManager.cpp
===================================================================
--- trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingSceneManager.cpp	(revision 41)
+++ trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingSceneManager.cpp	(revision 42)
@@ -30,6 +30,28 @@
 	void OcclusionCullingSceneManager::_renderVisibleObjects( void )
 	{
-		mOcclusionCullingSceneTraverser->renderScene(mCameraInProgress, mSceneRoot);
+			//-- render background
+		clearSpecialCaseRenderQueues();
+		addSpecialCaseRenderQueue(RENDER_QUEUE_BACKGROUND);
+		addSpecialCaseRenderQueue(RENDER_QUEUE_SKIES_EARLY);
+	
+		setSpecialCaseRenderQueueMode(SceneManager::SCRQM_INCLUDE);
 		SceneManager::_renderVisibleObjects( );
+		_deleteRenderedQueueGroups();
+
+		//-- render visible objects (i.e., all but overlay)
+		clearSpecialCaseRenderQueues();
+		addSpecialCaseRenderQueue(RENDER_QUEUE_OVERLAY);
+		setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
+
+		mOcclusionCullingSceneTraverser->setSceneRoot(mSceneRoot);
+		mOcclusionCullingSceneTraverser->renderScene(mCameraInProgress);
+
+		_deleteRenderedQueueGroups();
+
+		//-- render overlay
+		clearSpecialCaseRenderQueues();
+		SceneManager::_renderVisibleObjects( );
+	
+		clearSpecialCaseRenderQueues();
 	}
 	//-----------------------------------------------------------------------
@@ -41,9 +63,9 @@
 	void OcclusionCullingSceneManager::_updateSceneGraph( Camera* cam )
 	{
-		mOcclusionCullingSceneTraverser->setNumSceneNodes(mSceneNodes.size());
-		mOcclusionCullingSceneTraverser->setNumQueries(mSceneNodes.size());
+		mOcclusionCullingSceneTraverser->setNumSceneNodes((int)mSceneNodes.size());
 		mOcclusionCullingSceneTraverser->setRenderSystem(mDestRenderSystem);
-
-        mOcclusionCullingSceneTraverser->preprocess();
+		
+		//mOcclusionCullingSceneTraverser->setNumQueries((int)mSceneNodes.size());
+        //mOcclusionCullingSceneTraverser->preprocess();
 		
 		SceneManager::_updateSceneGraph(cam);
Index: trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingSceneTraverser.cpp
===================================================================
--- trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingSceneTraverser.cpp	(revision 41)
+++ trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingSceneTraverser.cpp	(revision 42)
@@ -17,5 +17,5 @@
 	mQueryMode(MODE_RENDER), mNumSceneNodes(0), mCurrentAlgorithm(RENDER_COHERENT),
 	mNumQueries(0), mNumTraversedNodes(0), mNumQueryCulledNodes(0), mNumFrustumCulledNodes(0), 
-	mNumRenderedGeometry(0), mSceneManager(sm), mRenderSystem(rsys)
+	mNumRenderedGeometry(0), mSceneManager(sm), mRenderSystem(rsys), mSceneRoot(NULL)
 	{		
 		mHalfBoundingBox[0] = mHalfBoundingBox[1] = 0;
@@ -28,8 +28,11 @@
 
 		deleteQueries();
+
+		if(mDistanceQueue)
+			delete mDistanceQueue;
 		//SceneManager::~SceneManager();
 	}
 	//-----------------------------------------------------------------------
-	void OcclusionCullingSceneTraverser::renderScene( Camera *cam, SceneNode *root )
+	void OcclusionCullingSceneTraverser::renderScene( Camera *cam )
 	{
 		mNumTraversedNodes = 0;
@@ -38,7 +41,7 @@
 		mNumRenderedGeometry = 0;
 		
-		mDistanceQueue = new PriorityQueue(myless<SceneNode *>(cam));
-		mDistanceQueue->push(root);
 		mCurrentTestIdx = 0;
+
+		initDistanceQueue(cam);
 
 //mCurrentAlgorithm = RENDER_CULL_FRUSTUM;
@@ -59,6 +62,4 @@
 		}	
 		
-		delete mDistanceQueue;
-
 		mFrameId ++;
 	}
@@ -85,5 +86,5 @@
 				if(visiblePixels > mVisibilityThreshold)
 				{
-					pullUpVisibility(node);
+					pullUpVisibility(cam, node);
 					traverseNode(cam, node);
 				}
@@ -100,8 +101,20 @@
 				mDistanceQueue->pop();
 				
+				bool intersects = false;
 				//TODO: Isvisible also checked inside scenenode::findvisibleobjects
-				if(!cam->isVisible(node->_getWorldAABB()))
+				if(!cam->isVisible(node->_getWorldAABB(), intersects))
 				{
                     mNumFrustumCulledNodes ++;
+					continue;
+				}
+
+				// if intersects near plane => skip occlusion query because wrong results possible
+				if(intersects)
+				{
+					// update node's visited flag
+					node->setLastVisited(mFrameId);
+					pullUpVisibility(cam, node);			
+					traverseNode(cam, node);
+
 					continue;
 				}
@@ -152,8 +165,4 @@
 			if(!cam->isVisible(node->_getWorldAABB()))
 			{			
-				char msg2[100];
-				sprintf(msg2,"no, invisible\n");
-				OutputDebugString(msg2);
-
 				mNumFrustumCulledNodes ++;
 				continue;
@@ -164,8 +173,4 @@
 			node->setNodeVisible(true);
 			traverseNode(cam, node);
-
-			char msg2[100];
-			sprintf(msg2,"yes, visible\n");
-			OutputDebugString(msg2);
 		}
 	}	
@@ -182,8 +187,18 @@
 			node->setLastVisited(mFrameId);
 
+			bool intersects = false;
 			//TODO: Isvisible also checked inside scenenode::findvisibleobjects
-			if(!cam->isVisible(node->_getWorldAABB()))
+			if(!cam->isVisible(node->_getWorldAABB(), intersects))
 			{
 				mNumFrustumCulledNodes ++;
+				continue;
+			}
+
+			// if intersects near plane => skip occlusion query because wrong results possible
+			if(intersects)
+			{
+				node->setNodeVisible(true);
+				traverseNode(cam, node);
+
 				continue;
 			}
@@ -198,4 +213,5 @@
 			if(visiblePixels > mVisibilityThreshold)
 			{
+				node->setNodeVisible(true);
 				traverseNode(cam, node);
 			}
@@ -215,10 +231,6 @@
 		//setRenderingMode(MODE_RENDER);
 
-		char msg2[100];
-		sprintf(msg2,"this is query %d of overall %d\n", mCurrentTestIdx, mNumQueries);
-		OutputDebugString(msg2);
-
 		// get next available test id
-		HardwareOcclusionQuery *query = mOcclusionQueries[mCurrentTestIdx++];
+		HardwareOcclusionQuery *query = getNextOcclusionQuery();
 
 		//-- the actual query test
@@ -275,5 +287,5 @@
 	}
 	//-----------------------------------------------------------------------
-	void OcclusionCullingSceneTraverser::preprocess( void )
+/*	void OcclusionCullingSceneTraverser::preprocess( void )
 	{
 		//-- initialise occlusion queries.
@@ -284,5 +296,5 @@
 			mOcclusionQueries.push_back(mRenderSystem->createHardwareOcclusionQuery());
 		}	
-	}
+	}*/
 	//-----------------------------------------------------------------------
 	void OcclusionCullingSceneTraverser::setSceneManager( SceneManager *sm )
@@ -316,10 +328,16 @@
 	}
 	//-----------------------------------------------------------------------
-	void OcclusionCullingSceneTraverser::pullUpVisibility( SceneNode *node )
+	void OcclusionCullingSceneTraverser::pullUpVisibility( Camera *cam, SceneNode *node )
 	{
 		while(node && !node->isNodeVisible())
 		{
+			// if we come across some renderable geometry => render it
+			if(node->numAttachedObjects() > 0)
+			{
+				renderSceneNode(cam, node);
+			}
+
 			node->setNodeVisible(true);
-			node = static_cast<SceneNode *>(node->getParent());
+			node = node->getParentSceneNode();
 		}
 	}
@@ -327,5 +345,5 @@
 	void OcclusionCullingSceneTraverser::deleteQueries( void )
 	{
-		for(unsigned int i=0; i < mOcclusionQueries.size(); i++)
+		for(unsigned int i=0; i < (unsigned int)mOcclusionQueries.size(); i++)
 			delete mOcclusionQueries[i];
 
@@ -363,4 +381,35 @@
 
 		return mHalfBoundingBox[half];	
+	}
+	//-----------------------------------------------------------------------
+	void OcclusionCullingSceneTraverser::setNumSceneNodes(int num)
+	{
+		mNumSceneNodes = num;
+	}
+	//-----------------------------------------------------------------------
+	/*void OcclusionCullingSceneTraverser::setNumQueries(int num)
+	{
+		mNumQueries = num;
+	}*/
+	//-----------------------------------------------------------------------
+	void OcclusionCullingSceneTraverser::setSceneRoot(SceneNode *root)
+	{
+		mSceneRoot = root;
+	}
+	//-----------------------------------------------------------------------
+	void OcclusionCullingSceneTraverser::initDistanceQueue(Camera *cam)
+	{
+		mDistanceQueue = new PriorityQueue(myless<SceneNode *>(cam));
+		mDistanceQueue->push(mSceneRoot);
+	}
+	//-----------------------------------------------------------------------
+	HardwareOcclusionQuery *OcclusionCullingSceneTraverser::getNextOcclusionQuery(void)
+	{
+		if(mCurrentTestIdx == mOcclusionQueries.size())
+		{
+			mOcclusionQueries.push_back(mRenderSystem->createHardwareOcclusionQuery());
+		}
+		
+		return mOcclusionQueries[mCurrentTestIdx ++];
 	}
 	//-----------------------------------------------------------------------
@@ -428,13 +477,3 @@
 		return true;
 	}
-	//-----------------------------------------------------------------------
-	void OcclusionCullingSceneTraverser::setNumSceneNodes(int num)
-	{
-		mNumSceneNodes = num;
-	}
-	//-----------------------------------------------------------------------
-	void OcclusionCullingSceneTraverser::setNumQueries(int num)
-	{
-		mNumQueries = num;
-	}
 }	
Index: trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneManager.cpp
===================================================================
--- trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneManager.cpp	(revision 41)
+++ trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneManager.cpp	(revision 42)
@@ -16,10 +16,9 @@
 		mOcclusionCullingTerrainSceneTraverser = 
 			new OcclusionCullingTerrainSceneTraverser(this, mDestRenderSystem);
-			//new OcclusionCullingSceneTraverser(this, mDestRenderSystem);
 
 		//mDisplayNodes = true;
 		//mShowBoundingBoxes = true;
 		mShowBoxes = true;
-		mMaxDepth = 20;
+		//mMaxDepth = 20;
 	}
 	//-----------------------------------------------------------------------
@@ -45,7 +44,7 @@
 		setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
 
-		mOcclusionCullingTerrainSceneTraverser->renderScene(mCameraInProgress, mOctree);
-		//mOcclusionCullingTerrainSceneTraverser->renderScene(mCameraInProgress, mTerrainRoot);
-		//mOcclusionCullingTerrainSceneTraverser->renderScene(mCameraInProgress, mSceneRoot);
+		mOcclusionCullingTerrainSceneTraverser->setSceneRoot(mOctree);
+		mOcclusionCullingTerrainSceneTraverser->renderScene(mCameraInProgress);
+		
 		_deleteRenderedQueueGroups();
 
@@ -61,15 +60,15 @@
 		// must be empty because objects are found and rendered in an interleaved fashion
 		// in _renderVisibibleObjects 
+		//char *msg = "now finding visible objects\n"; OutputDebugString(msg);
 	}
 	//-----------------------------------------------------------------------
 	void OcclusionCullingTerrainSceneManager::_updateSceneGraph(Camera* cam)
 	{
-     	mOcclusionCullingTerrainSceneTraverser->setNumSceneNodes(mSceneNodes.size());
-		//HACK
-		mOcclusionCullingTerrainSceneTraverser->setNumQueries(countOctreeSize(mOctree));
+		//char *msg = "now updating scenegraph\n"; OutputDebugString(msg);
+     	mOcclusionCullingTerrainSceneTraverser->setNumSceneNodes((int)mSceneNodes.size());
 		mOcclusionCullingTerrainSceneTraverser->setRenderSystem(mDestRenderSystem);
+        //mOcclusionCullingTerrainSceneTraverser->preprocess();
+		mOcclusionCullingTerrainSceneTraverser->setNumOctreeNodes(mNumOctreeNodes);
 
-        mOcclusionCullingTerrainSceneTraverser->preprocess();
-		
 		TerrainSceneManager::_updateSceneGraph(cam);
 	}
@@ -132,17 +131,17 @@
 	}
 	//-----------------------------------------------------------------------
-	unsigned int OcclusionCullingTerrainSceneManager::countOctreeSize(Octree *root)
+	/*unsigned int OcclusionCullingTerrainSceneManager::countNumOctrees(Octree *root)
 	{
 		unsigned int result = 1;
 				
-		for(int i=0; i<8; i++)
+		for(int i=0; i<8; ++i)
 		{
 			Octree *nextChild = root->mChildren[(i & 4) >> 2][(i & 2) >> 1][i & 1];
 		
 			if(nextChild != 0)
-				result += countOctreeSize(nextChild);
+				result += countNumOctrees(nextChild);
 		}
 		
 		return result;
-	}
+	}*/
 }	
Index: trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingDotSceneManager.cpp
===================================================================
--- trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingDotSceneManager.cpp	(revision 39)
+++ trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingDotSceneManager.cpp	(revision 42)
@@ -41,5 +41,6 @@
 		setSpecialCaseRenderQueueMode(SceneManager::SCRQM_EXCLUDE);
 
-		mOcclusionCullingSceneTraverser->renderScene(mCameraInProgress, mSceneRoot);
+		mOcclusionCullingSceneTraverser->setSceneRoot(mSceneRoot);
+		mOcclusionCullingSceneTraverser->renderScene(mCameraInProgress);
 		_deleteRenderedQueueGroups();
 
@@ -59,8 +60,8 @@
 	void OcclusionCullingDotSceneManager::_updateSceneGraph(Camera* cam)
 	{
-		mOcclusionCullingSceneTraverser->setNumSceneNodes(mSceneNodes.size());
+		mOcclusionCullingSceneTraverser->setNumSceneNodes((int)mSceneNodes.size());
 		mOcclusionCullingSceneTraverser->setRenderSystem(mDestRenderSystem);
 
-        mOcclusionCullingSceneTraverser->preprocess();
+        //mOcclusionCullingSceneTraverser->preprocess();
 		
 		DotSceneManager::_updateSceneGraph(cam);
Index: trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneTraverser.cpp
===================================================================
--- trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneTraverser.cpp	(revision 41)
+++ trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneTraverser.cpp	(revision 42)
@@ -8,6 +8,12 @@
 	//-----------------------------------------------------------------------
 	OcclusionCullingTerrainSceneTraverser::OcclusionCullingTerrainSceneTraverser(SceneManager *sm, RenderSystem *rsys): 
-	OcclusionCullingSceneTraverser(sm, rsys)
-	{
+	OcclusionCullingSceneTraverser(sm, rsys), mOctreeSceneRoot(0), mOctreeDistanceQueue(0)
+	{
+	}
+	//-----------------------------------------------------------------------
+	OcclusionCullingTerrainSceneTraverser::~OcclusionCullingTerrainSceneTraverser()
+	{		
+		if(mOctreeDistanceQueue)
+			delete mOctreeDistanceQueue;
 	}
 	//-----------------------------------------------------------------------
@@ -16,6 +22,9 @@
 		mNumTraversedNodes ++;
 	
-		//if(octant->numNodes() > 0)
+		// if we come across some renderable geometry => render it
+		if(octant->numNodes() > 0)
+		{
 			renderOctant(cam, octant);
+		}
 
 		for(int i=0; i<8; i++)
@@ -23,42 +32,7 @@
 			Octree *nextChild = octant->mChildren[(i & 4) >> 2][(i & 2) >> 1][i & 1];
 		
-			if(nextChild != 0)
-				mDistanceQueue->push(nextChild);
-		}
-	}
-	//-----------------------------------------------------------------------
-	void OcclusionCullingTerrainSceneTraverser::renderScene( Camera *cam, Octree *root )
-		//TODO: Renderscene independent from hierarchynode => implement only once
-	{
-		mNumTraversedNodes = 0;
-		mNumQueryCulledNodes = 0;
-		mNumFrustumCulledNodes = 0;
-		mNumRenderedGeometry = 0;
-		
-		mDistanceQueue = new OctreePriorityQueue(octreeless<Octree *>(cam));
-		mDistanceQueue->push(root);
-		mCurrentTestIdx = 0;
-		
-//mCurrentAlgorithm = RENDER_CULL_FRUSTUM;
-		switch(mCurrentAlgorithm)
-		{
-			case RENDER_CULL_FRUSTUM:
-				renderCullFrustum(cam);
-		        break;
-			case RENDER_STOP_AND_WAIT:
-				renderStopAndWait(cam);
-				break;
-			case RENDER_COHERENT:
-				//renderCoherentWithQueue(cam);
-				renderStopAndWait(cam);
-				break;
-			default:
-				renderCullFrustum(cam);
-				break;
-		}	
-		
-		delete mDistanceQueue;
-
-		mFrameId ++;
+			if(nextChild)
+				mOctreeDistanceQueue->push(nextChild);
+		}
 	}
 	//-----------------------------------------------------------------------
@@ -67,8 +41,8 @@
 		AxisAlignedBox box;
 
-		while(!mDistanceQueue->empty())
-		{
-			Octree *octant = mDistanceQueue->top();
-			mDistanceQueue->pop();
+		while(!mOctreeDistanceQueue->empty())
+		{
+			Octree *octant = mOctreeDistanceQueue->top();
+			mOctreeDistanceQueue->pop();
 	
 			// interesting for visualization purpose
@@ -76,5 +50,5 @@
 			octant->_getCullBounds(&box);
 			
-			if(static_cast<OctreeCamera *>(cam)->getVisibility(box) == OctreeCamera::NONE)
+			//if(static_cast<OctreeCamera *>(cam)->getVisibility(box) == OctreeCamera::NONE)
 			if(!cam->isVisible(box))
 			{
@@ -84,6 +58,6 @@
 
 			// update node's visited flag 
-			//TODO: octree->setLastVisited(mFrameId);
-			//TODO: octree->setNodeVisible(true);
+			octant->setLastVisited(mFrameId);
+			octant->setOctreeVisible(true);
 		
 			traverseOctant(cam, octant);
@@ -96,27 +70,29 @@
 		AxisAlignedBox box;
 
-		while(!mDistanceQueue->empty())
-		{
-			Octree *octant = mDistanceQueue->top();
-			mDistanceQueue->pop();
+		while(!mOctreeDistanceQueue->empty())
+		{
+			Octree *octant = mOctreeDistanceQueue->top();
+			mOctreeDistanceQueue->pop();
 		
 			// interesting for visualization purpose
-			//octant->setNodeVisible(false);
-			//octant->setLastVisited(mFrameId);
+			octant->setOctreeVisible(false);
+			octant->setLastVisited(mFrameId);
 
 			//TODO: Isvisible also checked inside scenenode::findvisibleobjects
 			octant->_getCullBounds(&box);
 
-			char msg[100]; 
-			Vector3 max = box.getMaximum();
-			Vector3 min = box.getMinimum();
-
-			sprintf(msg, "box max: %3.3f, %3.3f, %3.3f, min: %3.3f, %3.3f, %3.3f\n",max.x,max.y,max.z,min.x,min.y,min.z);
-			OutputDebugString(msg);
-
-			if(static_cast<OctreeCamera *>(cam)->getVisibility(box) == OctreeCamera::NONE)
-			//if(!cam->isVisible(box))
+			bool intersects = false;
+
+			//if(vis == OctreeCamera::NONE)
+			if(!cam->isVisible(box, intersects))
 			{
 				mNumFrustumCulledNodes ++;
+				continue;
+			}
+			// if intersects near plane => skip occlusion query because wrong results possible
+			if(intersects)
+			{
+				octant->setOctreeVisible(true);
+				traverseOctant(cam, octant);
 				continue;
 			}
@@ -127,10 +103,9 @@
 			// wait if result not available
 			query->pullOcclusionQuery(&visiblePixels);
-//traverseOctant(cam, octant);			
+			
 			// node visible
 			if(visiblePixels > mVisibilityThreshold)
 			{
 				traverseOctant(cam, octant);
-				//mNumQueryCulledNodes ++;
 			}
 			else
@@ -144,14 +119,165 @@
 	void OcclusionCullingTerrainSceneTraverser::renderCoherentWithQueue( Camera *cam )
 	{
-	}
-	//-----------------------------------------------------------------------
-	void OcclusionCullingTerrainSceneTraverser::pullUpVisibility( Octree *node )
-	{
-	}
-	//-----------------------------------------------------------------------
-	void OcclusionCullingTerrainSceneTraverser::renderOctant( Camera *cam, Octree *octree )
-	{
-		setRenderingMode(MODE_RENDER);
-		((OcclusionCullingTerrainSceneManager *)mSceneManager)->_renderOctant(cam, octree);
+		OctreeQueryQueue queryQueue;
+		AxisAlignedBox box;
+
+		//-- PART 1: process finished occlusion queries
+		while(!mOctreeDistanceQueue->empty() || !queryQueue.empty())
+		{
+			while(!queryQueue.empty() && 
+				  ((queryQueue.front().second)->resultAvailable() || mOctreeDistanceQueue->empty()))
+			{
+				Octree *octant = queryQueue.front().first;
+				HardwareOcclusionQuery *query = queryQueue.front().second;
+
+				queryQueue.pop();
+			
+				// wait until result available
+				unsigned int visiblePixels;
+				query->pullOcclusionQuery(&visiblePixels);
+
+				if(visiblePixels > mVisibilityThreshold)
+				{
+					pullUpVisibility(cam, octant);
+					traverseOctant(cam, octant);
+				}
+				else
+				{
+					mNumQueryCulledNodes ++;
+				}
+			}	
+
+			//-- PART 2: hierarchical traversal
+			if(!mOctreeDistanceQueue->empty())
+			{
+				Octree *octant = mOctreeDistanceQueue->top();
+				mOctreeDistanceQueue->pop();
+					
+				octant->_getCullBounds(&box);
+
+				bool intersects = false;
+				//TODO: Isvisible also checked inside scenenode::findvisibleobjects
+				if(!cam->isVisible(box, intersects))
+				{
+                    mNumFrustumCulledNodes ++;
+					continue;
+				}
+
+				// if intersects near plane => skip occlusion query because wrong results possible
+				if(intersects)
+				{
+					// update node's visited flag
+					octant->setLastVisited(mFrameId);
+					pullUpVisibility(cam, octant);			
+					traverseOctant(cam, octant);
+
+					continue;
+				}
+
+				// identify previously visible nodes
+				bool wasVisible = octant->isOctreeVisible() && (octant->lastVisited() == mFrameId - 1);
+					
+				// identify nodes that we cannot skip queries for
+				bool leafOrWasInvisible = !wasVisible || isLeaf(octant);
+
+				// reset node's visibility classification 
+				octant->setOctreeVisible(false);
+
+				// update node's visited flag
+				octant->setLastVisited(mFrameId);
+			
+				// skip testing previously visible interior nodes
+				if(leafOrWasInvisible)
+				{
+					HardwareOcclusionQuery *query = issueOcclusionQuery(&box, wasVisible);
+					queryQueue.push(OctreeQueryPair(octant, query));
+				}
+					
+				// always traverse a node if it was visible
+				if(wasVisible)
+				{
+					traverseOctant(cam, octant);
+				}
+				else
+				{
+					mNumFrustumCulledNodes ++;
+				}
+			}
+		}
+	}
+	//-----------------------------------------------------------------------
+	void OcclusionCullingTerrainSceneTraverser::pullUpVisibility( Camera *cam, Octree *octant )
+	{
+		while(octant && !octant->isOctreeVisible())
+		{
+			// if we come across some renderable geometry => render it
+			if(octant->numNodes() > 0)
+			{
+				renderOctant(cam, octant);
+			}
+
+			octant->setOctreeVisible(true);
+			octant = octant->getParent();
+		}
+	}
+	//-----------------------------------------------------------------------
+	void OcclusionCullingTerrainSceneTraverser::renderOctant( Camera *cam, Octree *octant )
+	{
+		if(octant->lastVisited() != octant->lastRendered())
+		{
+			setRenderingMode(MODE_RENDER);
+
+			octant->setLastRendered(octant->lastVisited());
+			((OcclusionCullingTerrainSceneManager *)mSceneManager)->_renderOctant(cam, octant);
+		}
+		else OutputDebugString("already rendered");
+	}
+	//-----------------------------------------------------------------------
+	void OcclusionCullingTerrainSceneTraverser::setSceneRoot(Octree *root)
+	{
+		mOctreeSceneRoot = root;
+	}
+	//-----------------------------------------------------------------------
+	void OcclusionCullingTerrainSceneTraverser::initDistanceQueue(Camera *cam)
+	{
+		if(mOctreeDistanceQueue)
+			delete mOctreeDistanceQueue;
+
+		mOctreeDistanceQueue = new OctreePriorityQueue(octreeless<Octree *>(cam));
+		mOctreeDistanceQueue->push(mOctreeSceneRoot);
+	}
+	//-----------------------------------------------------------------------
+	bool OcclusionCullingTerrainSceneTraverser::isLeaf(Octree *octant)
+	{
+		for(int i=0; i<8; i++)
+		{
+			if(octant->mChildren[(i & 4) >> 2][(i & 2) >> 1][i & 1])
+				return false;
+		}
+
+		return true;
+	}
+	//-----------------------------------------------------------------------
+	void OcclusionCullingTerrainSceneTraverser::setNumOctreeNodes(unsigned int num)
+	{
+		mNumOctreeNodes = num;
+	}
+	//-----------------------------------------------------------------------
+	bool OcclusionCullingTerrainSceneTraverser::getOption( const String & key, void *val )
+	{
+		if ( key == "NumOctreeNodes" )
+		{
+			* static_cast < unsigned int * > ( val ) = mNumOctreeNodes;
+			return true;
+		}
+
+		return OcclusionCullingSceneTraverser::getOption(key, val);
+	}
+	//-----------------------------------------------------------------------
+	bool OcclusionCullingTerrainSceneTraverser::getOptionKeys( StringVector & refKeys )
+	{
+		refKeys.push_back( "NumOctreeNodes" );
+		
+		return OcclusionCullingSceneTraverser::getOptionKeys(refKeys);		
 	}
 }	
