/* ----------------------------------------------------------------------------- This source file is part of the GameTools Project http://www.gametools.org Author: Martin Szydlowski ----------------------------------------------------------------------------- */ #ifndef _OgreBihRenderable_H__ #define _OgreBihRenderable_H__ #include "OgreBiHierarchy.h" namespace Ogre { // interface which must be implemented by all objects which desire to be // placed in the kd-tree class BihRenderable { public: BihRenderable():mSide(BihPlaneEvent::PES_BOTH), mClassified(false), mLastQueued(0), mBiHierarchy(0) { setDecided(0,false); setDecided(1,false); setDecided(2,false); }; virtual ~BihRenderable() { if (mBiHierarchy) mBiHierarchy->remove(this); } // gather the information required for the creation of the kd-tree virtual void computeScene(BihPlaneEventList& events, AxisAlignedBox& aabb, int& nObjects, bool includeChildren = true) = 0; // put all objects this element holds in the renedering queue virtual void queueObjects(Camera* cam, RenderQueue* queue, bool onlyShadowCasters) = 0; // place all entities in geometry queue (for CHC) virtual void getGeometryList(GeometryVector *geometryList) = 0; // return a bounding box enclosing all objects virtual AxisAlignedBox getBoundingBox() const = 0; // TODO: reconsider getters/setters !!! inline bool isClassified() { return mClassified; }; inline void setClassified(bool q) { mClassified = q; }; inline isDecided(int w) { return mDecided[w]; }; inline void setDecided(int w,bool b) { mDecided[w] = b; }; inline BihPlaneEvent::Side getSide() { return mSide; }; inline void setSide(BihPlaneEvent::Side s) { mSide = s; }; inline void setActualSide(int d,BihPlaneEvent::Side s) { mActualSide[d] = s; }; inline void FinalizeSide(int d) { mFinalSide[d]=mActualSide[d]; }; inline BihPlaneEvent::Side GetFinalSide(int d) { return mFinalSide[d]; }; // funcions for attachment/detachment of renderables to/from the kd-tree inline bool isAttached() { return mLeaves.size() != 0; }; // the following functions should work in O(log N) inline bool isAttached(BiHierarchy::LeafPtr leaf) { return mLeaves.find(leaf) != mLeaves.end(); }; inline bool attachTo(BiHierarchy::LeafPtr leaf, BiHierarchy * BiHierarchy) { if (mBiHierarchy == 0 || mBiHierarchy == BiHierarchy) mBiHierarchy = BiHierarchy; else return false; BiHierarchy::LeafSet::_Pairib p = mLeaves.insert(leaf); return p.second; }; inline bool detachFrom(BiHierarchy::LeafPtr leaf) { bool success = (mLeaves.erase(leaf) == 1); if (mLeaves.size() == 0) mBiHierarchy = 0; return success; }; inline bool isQueued(unsigned long currentFrame, Camera * currentCam) { if (mLastQueued == currentFrame && mLastCam == currentCam) { return true; } else { mLastQueued = currentFrame; mLastCam = currentCam; return false; } }; BiHierarchy::LeafSet& getLeaves() { return mLeaves; }; protected: // number of the frame in which this renderable was last queued for rendering unsigned long mLastQueued; // the camera for which this renderable was last queued for rendering Camera * mLastCam; // BiHierarchy to which this renderable is attached BiHierarchy * mBiHierarchy; // BiHierarchy leaves which overlap this renderable BiHierarchy::LeafSet mLeaves; // Flag for the SAH determining the "cheaper" side of the split plane BihPlaneEvent::Side mSide; BihPlaneEvent::Side mFinalSide[3]; BihPlaneEvent::Side mActualSide[3]; // Flag for the SAH which marks if this renderable was already placed in the list after a split bool mClassified; bool mDecided[3]; }; // class BihRenderable } // namespace Ogre #endif // _OgreBihRenderable_H__