#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 OcclusionCullingSceneTraverser { public: /** Construction taking the current scene manager and the current rendersystem as argument @param sm current scene manager @param rsys current render system */ OcclusionCullingSceneTraverser(SceneManager *sm, RenderSystem *rsys); ~OcclusionCullingSceneTraverser(); enum {RENDER_CULL_FRUSTUM, RENDER_STOP_AND_WAIT, RENDER_COHERENT, NUM_RENDERMODES}; /** Renders the scene with the specified algorithm @comment The algorithm type can be set with the parameter "Algorithm" and setOption. The algorithm is one of: RENDER_CULL_FRUSTUM: renders the scene with view frustum culling only RENDER_STOP_AND_WAIT: renders the scene with the hierarchical stop and wait algorithm RENDER_COHERENT: renders the scene with the coherent hierarchical algorithm @param cam current camera */ void renderScene( Camera *cam ); /** Sets the given option for the scene traverser. @remarks Options are: "Algorithm", int *; */ bool setOption( const String &, const void * ); /** Gets the given option for the scene traverser. @remarks See setOption */ bool getOption( const String &, void * ); bool getOptionKeys( StringVector &refKeys ); /** 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 current number of scene nodes in the scene. @param num number of scene nodes */ void setNumSceneNodes(int num ); /** Sets the root of the scene hierarchy. */ void setSceneRoot(SceneNode *root); /** Sets the required number of occlusion queries. @param num number occlusion queries */ //void setNumQueries( int num ); /** Doing some necessary preprocessing. @comment e.g., initialises occlusion queries */ //void preprocess( void ); protected: /** query mode (= without color) or RENDER_MODE */ enum {MODE_QUERY, MODE_RENDER}; /** returns true if node is leaf of the hierarchy */ bool isLeaf( SceneNode *node ); //HACK //unsigned int countSceneNodes(SceneNode *node); void traverseNode( Camera *cam, SceneNode *node ); /** Renders current scene node @param cam current camera @param node current scene node to be rendered */ void renderSceneNode( Camera *cam, SceneNode *node); /** Sets rendering mode, e.g. query mode or render mode*/ void setRenderingMode( int mode ); /** Renders the scene with view frustum culling only. */ virtual void renderCullFrustum( Camera *cam ); /** Renders the scene with the hierarchical stop and wait algorithm. */ virtual void renderStopAndWait( Camera *cam ); /** Renders the scene with the coherent hierarchical algorithm and the query queye. */ virtual void renderCoherentWithQueue( Camera *cam ); /** 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 nodes. */ void pullUpVisibility( Camera *cam, 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; private: // the scene root SceneNode *mSceneRoot; // we use a priority queue ordered by distance PriorityQueue *mDistanceQueue; }; } #endif // OCCLUSIONCULLINGSCENEMANAGER_H