#ifndef _SamplingStategy_H__ #define _SamplingStategy_H__ #include // #include "common.h" #include "Halton.h" namespace GtpVisibilityPreprocessor { class Vector2; class Vector3; class VssRay; class Preprocessor; struct SimpleRay; class SimpleRayContainer; class ViewCell; struct VssRayContainer; /** This class generates a specific sampling strategy. */ class SamplingStrategy { public: /** Sample rays of particular type */ enum { DUMMY_DISTRIBUTION = 0, DIRECTION_BASED_DISTRIBUTION, OBJECT_BASED_DISTRIBUTION, DIRECTION_BOX_BASED_DISTRIBUTION, SPATIAL_BOX_BASED_DISTRIBUTION, VSS_BASED_DISTRIBUTION, RSS_BASED_DISTRIBUTION, RSS_SILHOUETTE_BASED_DISTRIBUTION, OBJECT_DIRECTION_BASED_DISTRIBUTION, OBJECTS_INTERIOR_DISTRIBUTION, REVERSE_OBJECT_BASED_DISTRIBUTION, VIEWCELL_BORDER_BASED_DISTRIBUTION, VIEWSPACE_BORDER_BASED_DISTRIBUTION, REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION, GLOBAL_LINES_DISTRIBUTION, GVS, MUTATION_BASED_DISTRIBUTION, HW_GLOBAL_LINES_DISTRIBUTION, VIEWCELL_BASED_DISTRIBUTION }; /** Default constructor */ SamplingStrategy(Preprocessor &preprocessor); virtual ~SamplingStrategy(); /** Each strategy has to implement this function. @returns true if generated valid sample. */ virtual int GenerateSamples(const int number, SimpleRayContainer &rays); virtual bool GenerateSample(SimpleRay &ray) = 0; // true if the strategy keeps pointers to rays and thus they should get deleted // outside, in that case the strategy has to use reference counting and deleting the rays // by itself if the number of references drops to zero virtual bool RequiresRays() { return false; } virtual void Update(VssRayContainer &vssRays) {} friend bool LowerRatio(const SamplingStrategy *a, const SamplingStrategy *b) { return a->mRatio < b->mRatio; } public: /// variables usefull for mixed distribution sampling int mType; int mRays; float mContribution; int mTotalRays; int mGeneratedRays; float mTotalContribution; float mTime; float mRatio; protected: //static HaltonSequence sHalton; Preprocessor &mPreprocessor; }; class ObjectBasedDistribution: public SamplingStrategy { public: ObjectBasedDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor) { mType = OBJECT_BASED_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); static HaltonSequence sHalton; }; class ReverseObjectBasedDistribution: public SamplingStrategy { public: ReverseObjectBasedDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor) { mType = REVERSE_OBJECT_BASED_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); }; class ObjectDirectionBasedDistribution: public SamplingStrategy { public: ObjectDirectionBasedDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor) { mType = OBJECT_DIRECTION_BASED_DISTRIBUTION; } private: static HaltonSequence sHalton; virtual bool GenerateSample(SimpleRay &ray); }; class DirectionBasedDistribution: public SamplingStrategy { public: DirectionBasedDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor){ mType = DIRECTION_BASED_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); static HaltonSequence sHalton; }; class DirectionBoxBasedDistribution: public SamplingStrategy { public: DirectionBoxBasedDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor){ mType = DIRECTION_BOX_BASED_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); }; class SpatialBoxBasedDistribution: public SamplingStrategy { public: SpatialBoxBasedDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor){ mType = SPATIAL_BOX_BASED_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); static HaltonSequence sHalton; }; class ViewSpaceBorderBasedDistribution: public SamplingStrategy { public: ViewSpaceBorderBasedDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor){ mType = VIEWSPACE_BORDER_BASED_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); }; class ReverseViewSpaceBorderBasedDistribution: public SamplingStrategy { public: ReverseViewSpaceBorderBasedDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor){ mType = REVERSE_VIEWSPACE_BORDER_BASED_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); }; class ViewCellBorderBasedDistribution: public SamplingStrategy { public: ViewCellBorderBasedDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor) { mType = VIEWCELL_BORDER_BASED_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); }; class GlobalLinesDistribution: public SamplingStrategy { public: GlobalLinesDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor) { mType = GLOBAL_LINES_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); static HaltonSequence sHalton; }; class HwGlobalLinesDistribution: public SamplingStrategy { public: HwGlobalLinesDistribution(Preprocessor &preprocessor); private: virtual bool GenerateSample(SimpleRay &ray); static HaltonSequence sHalton; }; class ViewCellBasedDistribution: public SamplingStrategy { public: ViewCellBasedDistribution(Preprocessor &preprocessor, ViewCell *viewCell) : SamplingStrategy(preprocessor), mViewCell(viewCell) { mType = VIEWCELL_BASED_DISTRIBUTION; } private: virtual bool GenerateSample(SimpleRay &ray); ViewCell *mViewCell; static HaltonSequence sHalton; }; class MixtureDistribution: public SamplingStrategy { public: // container for the distributions std::vector mDistributions; MixtureDistribution(Preprocessor &preprocessor): SamplingStrategy(preprocessor) { } // has to called before first usage void Init(); // equalize distribution contributions void Reset(); // add contributions of the sample to the strategies void ComputeContributions(VssRayContainer &vssRays); // update distributions with new rays // warning: some rays can get deleted (if maintained internally by the // particular distribution)! void UpdateDistributions(VssRayContainer &vssRays); void UpdateRatios(); // construct distribution mixture from a string describing the required distributions bool Construct(char *str); virtual bool RequiresRays() { for (int i=0; i < (int)mDistributions.size(); i++) if (mDistributions[i]->RequiresRays()) return true; return false; } virtual int GenerateSamples(const int number, SimpleRayContainer &rays); private: // Generate a new sample according to a mixture distribution virtual bool GenerateSample(SimpleRay &ray); // halton sequence generator for deciding between distributions static HaltonSequence sHalton; }; }; #endif