#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 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 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 QueryPair; typedef priority_queue, myless::value_type> > PriorityQueue; typedef queue 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 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