/* ----------------------------------------------------------------------------- This source file is part of the GameTools Project http://www.gametools.org Author: Martin Szydlowski ----------------------------------------------------------------------------- */ #ifndef _OgreBvhRenderable_H__ #define _OgreBvhRenderable_H__ #include "OgreBvHierarchy.h" namespace Ogre { // interface which must be implemented by all objects which desire to be // placed in the kd-tree class BvhRenderable { public: BvhRenderable():mSide(BvhPlaneEvent::PES_BOTH), mClassified(false), mLastQueued(0), mBvHierarchy(0) {}; virtual ~BvhRenderable() { if (mBvHierarchy) mBvHierarchy->remove(this); } // gather the information required for the creation of the kd-tree virtual void computeScene(BvhPlaneEventList& 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 BvhPlaneEvent::Side getSide() { return mSide; }; inline void setSide(BvhPlaneEvent::Side s) { mSide = s; }; // 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(BvHierarchy::LeafPtr leaf) { return mLeaves.find(leaf) != mLeaves.end(); }; inline bool attachTo(BvHierarchy::LeafPtr leaf, BvHierarchy * BvHierarchy) { if (mBvHierarchy == 0 || mBvHierarchy == BvHierarchy) mBvHierarchy = BvHierarchy; else return false; BvHierarchy::LeafSet::_Pairib p = mLeaves.insert(leaf); return p.second; }; inline bool detachFrom(BvHierarchy::LeafPtr leaf) { bool success = (mLeaves.erase(leaf) == 1); if (mLeaves.size() == 0) mBvHierarchy = 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; } }; BvHierarchy::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; // BvHierarchy to which this renderable is attached BvHierarchy * mBvHierarchy; // BvHierarchy leaves which overlap this renderable BvHierarchy::LeafSet mLeaves; // Flag for the SAH determining the "cheaper" side of the split plane BvhPlaneEvent::Side mSide; // Flag for the SAH which marks if this renderable was already placed in the list after a split bool mClassified; }; // class BvhRenderable } // namespace Ogre #endif // _OgreBvhRenderable_H__