#ifndef __MUTUAL_VISIBILITY_H #define __MUTUAL_VISIBILITY_H #include "Vector3.h" #include "Ray.h" namespace GtpVisibilityPreprocessor { class Intersectable; class AxisAlignedBox3; class SceneGraph; struct RaySample { /// true if the sample really intersects both boxes float mMinT; float mMaxT; RaySample():mMinT(-1.0f), mMaxT(-1.0f) {} /// intersections of the sample with the scene vector mIntersections; void SetInvalid() { mMinT = 0.0f; mMaxT = -1.0f; } bool IsValid() const { return mMaxT > 0.0f; } bool IsProcessed() const { return mMinT != mMaxT; } }; struct RayShaft { public: /// evaluted sampling error float mError; /// depth in recursion int mDepth; /// The source triangle Rectangle3 mSource; /// The target triangle Rectangle3 mTarget; RaySample mSamples[4]; void ComputeError(); RayShaft() {} RayShaft ( const Rectangle3 &source, const Rectangle3 &target) { Init(source, target); } bool IsValid() const { return mSamples[0].IsValid() && mSamples[1].IsValid() && mSamples[2].IsValid() && mSamples[3].IsValid(); } // initial triangle sample void Init( const Rectangle3 &source, const Rectangle3 &target); Vector3 GetIntersectionPoint(const int rayIndex, const int depth) const; void GetRay(const int rayIndex, Vector3 &origin, Vector3 &direction) const; void GetRaySegment(const int i, Ray &ray) const; }; enum { VISIBLE, INVISIBLE }; class MutualVisibilitySampler { public: SceneGraph *mSceneGraph; KdTree *mKdTree; AxisAlignedBox3 mSource; AxisAlignedBox3 mTarget; float mSolidAngleThreshold; bool mUseBoxes; MutualVisibilitySampler( SceneGraph *sceneGraph, KdTree *kdTree, const AxisAlignedBox3 &source, const AxisAlignedBox3 &target, const float solidAngleThreshold ); int ComputeVisibility(); void ConstructInitialSamples(const AxisAlignedBox3 &source, const AxisAlignedBox3 &target, vector &samples ); void ConstructInitialSamples2( const AxisAlignedBox3 &source, const AxisAlignedBox3 &target, vector &samples ); void ConstructInitialSamples3( const AxisAlignedBox3 &source, const AxisAlignedBox3 &target, vector &samples ); void AddInitialSamples( const Rectangle3 &sourceRect, const Rectangle3 &targetRect, vector &samples ); void AddInitialSamples2( const Rectangle3 &sourceRect, const Rectangle3 &targetRect, vector &samples ); // the split sample method contains a methodology to create new samples // or terminate the sampling bool SplitSample( const RayShaft &source, RayShaft &sample1, RayShaft &sample2 ); void PerformSplit( const RayShaft &sample, const bool splitSource, const int axis, RayShaft &sample1, RayShaft &sample2 ); bool SampleTerminationCriteriaMet( const RayShaft &sample); float GetSpatialAngle(const RayShaft &sample, const Vector3 &point ); int CastRays(RayShaft &shaft); void ComputeError(RayShaft &sample); void ExportShafts(vector &samples, const bool singleFile); }; int ComputeBoxVisibility(SceneGraph *sceneGraph, KdTree *kdTree, const AxisAlignedBox3 &source, const AxisAlignedBox3 &target, const float solidAngleThreshold); } #endif