#ifndef _ReverserGvs_H__ #define _ReverseGvs_H__ #include // #include "common.h" #include "Halton.h" namespace GtpVisibilityPreprocessor { class Vector2; class Vector3; class VssRay; class Preprocessor; struct SimpleRay; class SimpleRayContainer; struct VssRayContainer; /** This algorithm can be best described as Reverse Guided Visibility Sampling. We exchange the roles of objects (triangles in gvs) and view cells, in order to make Gvs feasible for global sampling (where all view cells are updated in parallel). Algorithm idea: We loop through the objects (instead of the view cells). For each object, there s a directional random sampling step, which will find some view cells. This is again dual to Gvs. The view cells found in the first step are used as a seed in order to grow visibility regions towards neighbouring view cells. We use guided samples from the object towards these neighbouring view cells. Subsequently the algorithm would explore the boundaries of the view cells where the object can still be seen. This is dual to the border sampling step of Gvs. There will also be a reverse sampling step. We take a new point on the object, abd connect it to a view cell found invisible by the border sampling. This would only make sense if the objects are reasonable large. The new algorithm would fully explore the global nature of the sampling. The progressive quality of the algorithm could be more emphasised by looping through the objects in some kind of importance fashion, where the importance comes from an initial estimate of the #view cells the object can be seen from. */ class ReverseGvs: public SamplingStrategy { public: ReverseGvs(Preprocessor &preprocessor); virtual void Update(VssRayContainer &vssRays); virtual bool RequiresRays() { return true; } private: virtual bool GenerateSample(SimpleRay &ray); bool GenerateMutation(const int index, SimpleRay &ray); bool GenerateMutationCandidate(const int index, SimpleRay &ray, Intersectable *object, const AxisAlignedBox3 &box ); struct RayEntry { // halton sequence for generatin gmutations of this ray VssRay *mRay; short mMutations; short mUnsuccessfulMutations; // Halton<4> mHalton; HaltonSequence mHalton; float mImportance; float mCdf; Vector3 mutatedOrigin; Vector3 mutatedTermination; float GetSamplingFactor() const { return mMutations/mImportance; } friend bool operator<(const RayEntry &a, const RayEntry &b) { return a.GetSamplingFactor() > b.GetSamplingFactor(); } RayEntry() {} RayEntry(VssRay *r):mRay(r), mMutations(0), mUnsuccessfulMutations(0), mHalton(), mImportance(1.0f) { ResetReverseMutation(); } void ResetReverseMutation() { mutatedOrigin = mutatedTermination = Vector3(0,0,0); } bool HasReverseMutation() const { return !(mutatedOrigin == mutatedTermination); } void SetReverseMutation(const Vector3 &a, const Vector3 &b) { mutatedOrigin = a; mutatedTermination = b; } }; Vector3 ComputeOriginMutation(const VssRay &ray, const Vector3 &U, const Vector3 &V, const Vector2 vr2, const float radius ); Vector3 ComputeTerminationMutation(const VssRay &ray, const Vector3 &U, const Vector3 &V, const Vector2 vr2, const float radius ); Vector3 ComputeSilhouetteTerminationMutation(const VssRay &ray, const Vector3 &origin, const AxisAlignedBox3 &box, const Vector3 &U, const Vector3 &V, const float radius ); bool ComputeReverseMutation( const VssRay &oldRay, const VssRay &newRay, Vector3 &origin, Vector3 &termination ); RayEntry &GetEntry(const int index); vector mRays; int mBufferStart; int mLastIndex; int mMaxRays; float mMutationRadiusOrigin; float mMutationRadiusTermination; bool mUseReverseSamples; float mReverseSamplesDistance; bool mUseSilhouetteSamples; int mSilhouetteSearchSteps; float mSilhouetteProb; bool mUsePassImportance; bool mUseUnsuccCountImportance; }; } #endif