#ifndef __MUTUAL_VISIBILITY_H #define __MUTUAL_VISIBILITY_H #include "Vector3.h" #include "Ray.h" class Intersectable; class AxisAlignedBox3; struct SimpleRay { Vector3 mOrigin; Vector3 mDirection; }; struct RaySample { /// true if the sample really intersects both boxes float mMinT; float mMaxT; /// intersections of the sample with the scene vector mIntersections; bool IsValid() const { return mMaxT > 0.0; } }; 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); } // 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; }; enum { VISIBLE, INVISIBLE }; class MutualVisibilitySampler { public: KdTree *mKdTree; AxisAlignedBox3 mSource; AxisAlignedBox3 mTarget; float mSolidAngleThreshold; MutualVisibilitySampler(KdTree *kdTree, AxisAlignedBox3 &source, AxisAlignedBox3 &target, const float solidAngleThreshold); int ComputeVisibility(); void ConstructInitialSamples( const AxisAlignedBox3 &source, const AxisAlignedBox3 &target, vector &samples ); void AddInitialSamples( 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 ExportSamples(vector &samples); }; int ComputeBoxVisibility(KdTree *kdTree, AxisAlignedBox3 &source, AxisAlignedBox3 &target, float solidAngleThreshold); #endif