Index: /trunk/VUT/OcclusionCullingSceneManager/include/SceneTraverser.h
===================================================================
--- /trunk/VUT/OcclusionCullingSceneManager/include/SceneTraverser.h	(revision 56)
+++ /trunk/VUT/OcclusionCullingSceneManager/include/SceneTraverser.h	(revision 56)
@@ -0,0 +1,134 @@
+#ifndef _OcclusionCullingSceneTraverser_H__
+#define _OcclusionCullingSceneTraverser_H__
+
+#include "OgreSceneNode.h"
+#include "OgreSceneManager.h"
+#include "OgrePrerequisites.h"
+#include "OgreSolidHalfBoundingBox.h"
+#include "OgreCamera.h"
+#include "OgreRenderSystem.h"
+#include <queue>
+
+using namespace std;
+
+namespace Ogre {
+	/**
+		This class implements the compare operator for the priority queue.
+		a lower distance has a higher value in the queue
+	*/
+	template <typename T> class myless
+	{
+	public:
+		myless(Camera *cam) { mCamera = cam; }
+		//bool operator() (HierarchyNode *v1, HierarchyNode *v2) const
+		bool operator() (T v1, T v2) const
+		{
+			return v1->getSquaredViewDepth(mCamera) > v2->getSquaredViewDepth(mCamera);
+		}
+	private:
+		Camera *mCamera;
+	};
+
+	typedef pair<SceneNode *, HardwareOcclusionQuery *> QueryPair;
+	typedef priority_queue<SceneNode *, vector<SceneNode *>, myless<vector<SceneNode *>::value_type> > PriorityQueue;
+	typedef queue<QueryPair> QueryQueue;
+	/**
+		Class which implements a scene mangager which uses occlusion queries for culling occluded objects
+	*/
+	class SceneTraverser
+	{
+	public:
+		/** Construction taking the current scene manager and the current rendersystem as argument
+		@param sm current scene manager
+		@param rsys current render system 
+		*/
+		SceneTraverser(SceneManager *sm, RenderSystem *rsys);
+		~SceneTraverser();
+	
+		/** Sets pointer to the current scene manager.
+		@param the scene manager */
+		void setSceneManager( SceneManager *sm );
+		
+		/** Sets pointer to the current render system 
+		@param the rendersystem */
+		void setRenderSystem( RenderSystem *rsys );
+		
+		/** Sets the root of the scene hierarchy. */
+		void setSceneRoot(SceneNode *root);
+
+		/** Doing some necessary preprocessing.
+		@comment e.g., initialises occlusion queries */
+		//void preprocess( void );
+
+	protected:
+	
+		/** returns true if current node is leaf of the hierarchy */
+		bool isLeaf( ) = 0;
+		
+		void traverseNode( HierarchyNode *node);
+		/** Renders current scene node 
+		@param cam current camera
+		@param node current scene node to be rendered
+		*/
+		void renderNode( HierarchyNode *node);
+			
+		/** Issue a occlusion query for this node. 
+			@param box the axis aligned bounding box of the node
+			@wasVisible if the node was visible in previous frame
+		*/
+		HardwareOcclusionQuery *issueOcclusionQuery( AxisAlignedBox *box, bool wasVisible );
+		/** Returns next available occlusion query or creates new one.
+		@return the next occlusion query
+		*/
+		HardwareOcclusionQuery *getNextOcclusionQuery(void);
+		/** Pulls up the visibility from the child node. 
+		@param the child node 
+		*/
+		void pullUpVisibility(SceneNode *node);
+		/** delete all previously defined occlusion queries */
+		void deleteQueries();
+		/** Renders bounding box of specified node.
+		@param box the bounding box of the scene node to be rendered */
+		void renderBoundingBox( AxisAlignedBox *box );
+		/** Returns one half of the bounding box.
+		@param half the half index of the bouding box (0 or 1)
+		*/
+		SolidHalfBoundingBox *getSolidHalfBoundingBox( int half );
+
+		/** Initialises the distance queue. */
+		virtual void initDistanceQueue(Camera *cam);
+		
+		std::vector<HardwareOcclusionQuery *> mOcclusionQueries;
+		// two halfes of a aabb
+		SolidHalfBoundingBox *mHalfBoundingBox[2];	
+
+		int mCurrentAlgorithm;
+
+		unsigned int mFrameId;
+		unsigned int mVisibilityThreshold;
+		
+		SceneManager *mSceneManager;
+		RenderSystem *mRenderSystem;
+	
+		int mCurrentTestIdx;
+		int mQueryMode;
+
+		unsigned int mNumQueries;
+
+		//--- statistics
+		unsigned int mNumSceneNodes;
+		unsigned int mNumTraversedNodes;
+		unsigned int mNumQueryCulledNodes;
+		unsigned int mNumFrustumCulledNodes;
+		unsigned int mNumRenderedGeometry;
+		unsigned int mNumRenderedNodes;
+		
+	private:
+		// the scene root
+		HierarchyNode *mHierarchyRoot;
+		// we use a priority queue ordered by distance
+		PriorityQueue *mDistanceQueue; 
+	};
+
+}
+#endif // SCENETRAVERSER_H
Index: /trunk/VUT/OcclusionCullingSceneManager/scripts/Plugin_OcclusionCullingSceneManager.vcproj
===================================================================
--- /trunk/VUT/OcclusionCullingSceneManager/scripts/Plugin_OcclusionCullingSceneManager.vcproj	(revision 45)
+++ /trunk/VUT/OcclusionCullingSceneManager/scripts/Plugin_OcclusionCullingSceneManager.vcproj	(revision 56)
@@ -159,4 +159,7 @@
 				RelativePath="..\src\OgreSolidHalfBoundingBox.cpp">
 			</File>
+			<File
+				RelativePath="..\src\SceneTraverser.cpp">
+			</File>
 		</Filter>
 		<Filter
@@ -174,4 +177,7 @@
 			<File
 				RelativePath="..\include\OgreSolidHalfBoundingBox.h">
+			</File>
+			<File
+				RelativePath="..\include\SceneTraverser.h">
 			</File>
 		</Filter>
Index: /trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneManager.cpp
===================================================================
--- /trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneManager.cpp	(revision 55)
+++ /trunk/VUT/OcclusionCullingSceneManager/src/OgreOcclusionCullingTerrainSceneManager.cpp	(revision 56)
@@ -89,17 +89,3 @@
 	}
 	//-----------------------------------------------------------------------
-	/*unsigned int OcclusionCullingTerrainSceneManager::countNumOctrees(Octree *root)
-	{
-		unsigned int result = 1;
-				
-		for(int i=0; i<8; ++i)
-		{
-			Octree *nextChild = root->mChildren[(i & 4) >> 2][(i & 2) >> 1][i & 1];
-		
-			if(nextChild != 0)
-				result += countNumOctrees(nextChild);
-		}
-		
-		return result;
-	}*/
 }	
Index: /trunk/VUT/OcclusionCullingSceneManager/src/SceneTraverser.cpp
===================================================================
--- /trunk/VUT/OcclusionCullingSceneManager/src/SceneTraverser.cpp	(revision 56)
+++ /trunk/VUT/OcclusionCullingSceneManager/src/SceneTraverser.cpp	(revision 56)
@@ -0,0 +1,235 @@
+#include "OgreOcclusionCullingSceneTraverser.h"
+#include "OgreMath.h"
+#include "OgreIteratorWrappers.h"
+#include "OgreCamera.h"
+#include "OgreHardwareOcclusionQuery.h"
+#include "OgreSolidHalfBoundingBox.h"
+
+
+#include <windows.h>
+
+namespace Ogre {
+	
+	//-----------------------------------------------------------------------
+	SceneTraverser::OcclusionCullingSceneTraverser(SceneManager *sm, RenderSystem *rsys): 
+	mFrameId(1), mDistanceQueue(NULL), mVisibilityThreshold(0), mCurrentTestIdx(0),
+	mNumSceneNodes(0), mNumTraversedNodes(0), mNumQueryCulledNodes(0), mNumFrustumCulledNodes(0), 
+	mNumRenderedNodes(0),mNumRenderedGeometry(0), mSceneManager(sm), mRenderSystem(rsys), mSceneRoot(NULL)
+	{		
+		mHalfBoundingBox[0] = mHalfBoundingBox[1] = 0;
+	}
+	//-----------------------------------------------------------------------
+	SceneTraverser::~OcclusionCullingSceneTraverser()
+	{		
+		if(mHalfBoundingBox[0]) delete mHalfBoundingBox[0];
+		if(mHalfBoundingBox[1]) delete mHalfBoundingBox[1];
+
+		deleteQueries();
+
+		if(mDistanceQueue)
+			delete mDistanceQueue;
+		//SceneManager::~SceneManager();
+	}
+	//-----------------------------------------------------------------------
+	void SceneTraverser::traverseNode( Camera *cam, HierarchyNode *node )
+	{
+		mNumTraversedNodes ++;
+		
+		if(node->numAttachedObjects() > 0)
+		{
+			renderSceneNode(cam, node);
+		}
+
+		// internal node: add children to priority queue for further processing
+		Node::ChildNodeIterator it = node->getChildIterator();
+					
+		while (it.hasMoreElements())			
+		{ 
+			SceneNode* sceneChild = static_cast<SceneNode*>(it.getNext());
+			mDistanceQueue->push(sceneChild);
+		}
+	}
+	//-----------------------------------------------------------------------
+	void SceneTraverser::renderSceneNode( Camera *cam, HierarchyNode *node )
+	{
+		if(node->lastRendered() != node->lastVisited())
+		{
+			node->setLastRendered(node->lastVisited());
+			mNumRenderedNodes ++;
+
+			mSceneManager->_renderSceneNode(cam, node);
+		}
+	}
+	//-----------------------------------------------------------------------
+	void SceneTraverser::setSceneManager( SceneManager *sm )
+	{
+		mSceneManager = sm;
+	}
+	//-----------------------------------------------------------------------
+	void SceneTraverser::setRenderSystem( RenderSystem *rsys )
+	{
+		mRenderSystem = rsys;
+	}
+	//-----------------------------------------------------------------------
+	bool SceneTraverser::isLeaf( SceneNode *node )
+	{
+		return (node->numChildren() == 0);
+	}
+	//-----------------------------------------------------------------------
+	void SceneTraverser::pullUpVisibility(SceneNode *node )
+	{
+		while(node && !node->isNodeVisible())
+		{
+			node->setNodeVisible(true);
+			node = node->getParentSceneNode();
+		}
+	}
+	//-----------------------------------------------------------------------
+	void SceneTraverser::deleteQueries( void )
+	{
+		for(unsigned int i=0; i < (unsigned int)mOcclusionQueries.size(); ++i)
+			delete mOcclusionQueries[i];
+
+		mOcclusionQueries.clear();
+	}
+	//-----------------------------------------------------------------------
+	void SceneTraverser::renderBoundingBox( AxisAlignedBox *box )
+	{
+		// Render two halfes of the bounding box (using triangle fans)
+		for(int half = 0; half < 2; half ++)
+		{
+			static Matrix4 xform[256];
+			//TODO: this should be full bounding box
+			SolidHalfBoundingBox *halfbox = getSolidHalfBoundingBox(half);
+			halfbox->setupBoundingBox(*box);
+			
+			/*mRenderSystem->_setWorldMatrix(Matrix4::IDENTITY);
+
+			halfbox->getWorldTransforms(xform);
+
+			int numMatrices = halfbox->getNumWorldTransforms();
+			if (numMatrices > 1)
+			{
+				mRenderSystem->_setWorldMatrices(xform, numMatrices);
+			}
+			else
+			{
+				mRenderSystem->_setWorldMatrix(*xform);
+			}
+			mRenderSystem->setClipPlanes(halfbox->getClipPlanes());
+
+			static RenderOperation ro;
+
+			mSceneManager->useRenderableViewProjMode(halfbox);
+			halfbox->getRenderOperation(ro);
+			ro.srcRenderable = halfbox; 
+			mRenderSystem->_render(ro);*/
+			
+			mSceneManager->myrenderSingleObject(getSolidHalfBoundingBox(half), 
+				getSolidHalfBoundingBox(half)->getTechnique()->getPass(0), true);
+		}
+	}
+	//-----------------------------------------------------------------------
+	SolidHalfBoundingBox *SceneTraverser::getSolidHalfBoundingBox( int half )
+	{
+		if(!mHalfBoundingBox[half])
+			mHalfBoundingBox[half] = new SolidHalfBoundingBox(half == 1);
+
+		return mHalfBoundingBox[half];	
+	}
+	//-----------------------------------------------------------------------
+	void OcclusionCullingSceneTraverser::setNumSceneNodes(int num)
+	{
+		mNumSceneNodes = num;
+	}
+	//-----------------------------------------------------------------------
+	void SceneTraverser::setSceneRoot(SceneNode *root)
+	{
+		mSceneRoot = root;
+	}
+	//-----------------------------------------------------------------------
+	void SceneTraverser::initDistanceQueue(Camera *cam)
+	{
+		mDistanceQueue = new PriorityQueue(myless<SceneNode *>(cam));
+		mDistanceQueue->push(mSceneRoot);
+	}
+	//-----------------------------------------------------------------------
+	HardwareOcclusionQuery *SceneTraverser::getNextOcclusionQuery(void)
+	{
+		if(mCurrentTestIdx == mOcclusionQueries.size())
+		{
+			mOcclusionQueries.push_back(mRenderSystem->createHardwareOcclusionQuery());
+		}
+		
+		return mOcclusionQueries[mCurrentTestIdx ++];
+	}
+	//-----------------------------------------------------------------------
+	bool OcclusionCullingSceneTraverser::setOption( const String & key, const void * val )
+	{
+		if ( key == "Algorithm" )
+		{
+			mCurrentAlgorithm = * static_cast < const int * > ( val );
+			return true;
+		}
+		if ( key == "Threshold" )
+		{
+			mVisibilityThreshold = * static_cast < const int * > ( val );
+			return true;
+		}
+
+		return false;
+	}
+	//-----------------------------------------------------------------------
+	bool SceneTraverser::getOption( const String & key, void *val )
+	{
+		if ( key == "Algorithm" )
+		{
+			* static_cast < int * > ( val ) = mCurrentAlgorithm;
+			return true;
+		}
+		if ( key == "Threshold" )
+		{
+			* static_cast < unsigned int * > ( val ) = mVisibilityThreshold;
+			return true;
+		}
+		if ( key == "NumSceneNodes" )
+		{
+			* static_cast < unsigned int * > ( val ) = mNumSceneNodes;
+			return true;
+		}
+		if ( key == "NumTraversedNodes" )
+		{
+			* static_cast < unsigned int * > ( val ) = mNumTraversedNodes;
+			return true;
+		}
+		if ( key == "NumQueryCulledNodes" )
+		{
+			* static_cast < unsigned int * > ( val ) = mNumQueryCulledNodes;
+			return true;
+		}
+		if ( key == "NumFrustumCulledNodes" )
+		{
+			* static_cast < unsigned int * > ( val ) = mNumFrustumCulledNodes;
+			return true;
+		}
+		if ( key == "NumRenderedNodes" )
+		{
+			* static_cast < unsigned int * > ( val ) = mNumRenderedNodes;
+			return true;
+		}
+		return false;
+	}
+	//-----------------------------------------------------------------------
+	bool SceneTraverser::getOptionKeys( StringVector & refKeys )
+	{
+		refKeys.push_back( "Algorithm" );
+		refKeys.push_back( "Threshold" );
+		refKeys.push_back( "NumSceneNodes" );
+		refKeys.push_back( "NumTraversedNodes" );
+		refKeys.push_back( "NumQueryCulledNodes" );
+		refKeys.push_back( "NumFrustumCulledNodes" );
+		refKeys.push_back( "mNumRenderedGeometry" );
+
+		return true;
+	}
+}	
