#ifndef SUBDIVISIONCANDIDATE_H #define SUBDIVISIONCANDIDATE_H #include "FlexibleHeap.h" //using namespace std; namespace GtpVisibilityPreprocessor { class SubdivisionCandidate; typedef vector SubdivisionCandidateContainer; typedef FlexibleHeap SplitQueue; /** Candidate for a view space / object space split. */ class SubdivisionCandidate: public Heapable { public: enum {OBJECT_SPACE, VIEW_SPACE}; SubdivisionCandidate(): mRenderCostDecrease(0), mAvgRayContribution(0), mDirty(true) {} virtual ~SubdivisionCandidate() {}; /** Evaluate this subdivision candidate. */ virtual void EvalCandidate(bool computeSplitplane = true) = 0; /** Returns type of this subdivision candidate. */ virtual int Type() const = 0; /** Evaluate this candidate and put results into queue for further traversal. */ virtual bool Apply(SplitQueue &splitQueue, bool terminationCriteriaMet) = 0; /** Returns true of the global termination criteria of this split were met, false otherwise. */ virtual bool GlobalTerminationCriteriaMet() const = 0; /** Collects subdivision candidates that were affected by the application of this one. */ virtual void CollectDirtyCandidates(SubdivisionCandidateContainer &dirtyList, const bool onlyUnmailed) = 0; /** Set render cost decrease achieved through this split. */ inline void SetRenderCostDecrease(const float renderCostDecr) { mRenderCostDecrease = renderCostDecr; } inline float GetRenderCostDecrease() const { return mRenderCostDecrease; } /** The average ray contribution of this candidate . This is somewhat of a confidence value into the computed values. If it is high, there is likely to be a lot of undersampling. */ inline void SetAvgRayContribution(const float rayContri) { mAvgRayContribution = rayContri; } inline float GetAvgRayContribution() const { return mAvgRayContribution; } /** Position in queue. */ inline int GetPosition() const { return mPosition; } inline void SetSplitAxis(const int splitAxis) { mSplitAxis = splitAxis; } inline void SetMaxCostMisses(const int misses) { mMaxCostMisses = misses; } inline void SetPvsEntriesIncr(const int pvsEntriesIncr) { mPvsEntriesIncr = pvsEntriesIncr; } inline int GetSplitAxis() const { return mSplitAxis; } inline int GetMaxCostMisses() const { return mMaxCostMisses; } inline int GetPvsEntriesIncr() const { return mPvsEntriesIncr; } inline bool IsDirty() const { return mDirty; } inline void SetDirty(const bool dirty) { mDirty = dirty; } ////////// //-- mailing stuff static void NewMail(const int reserve = 1) { sMailId += sReservedMailboxes; sReservedMailboxes = reserve; } void Mail() { mMailbox = sMailId; } bool Mailed() const { return mMailbox == sMailId; } void Mail(const int mailbox) { mMailbox = sMailId + mailbox; } bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; } int IncMail() { return ++ mMailbox - sMailId; } // last mail id -> warning not thread safe! // both mailId and mailbox should be unique for each thread!!! static int sMailId; static int sReservedMailboxes; void *mEvaluationHack; protected: /// split axis of this plane (0, 1, 2, or 3 if non-axis-aligned) int mSplitAxis; /// the number of misses of max cost ratio until this split int mMaxCostMisses; /// render cost decrease achieved through this split float mRenderCostDecrease; /// the decrease of the number of pvs entries int mPvsEntriesIncr; /// the average ray contribution of this candidate float mAvgRayContribution; int mMailbox; bool mDirty; }; } // SUBDIVISIONCANDIDATE_H #endif