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