#ifndef _RayCaster_H__ #define _RayCaster_H__ #include "Containers.h" #include #include #include "Vector3.h" #include "VssRay.h" #include "Timer/PerfTimer.h" // namespace GtpVisibilityPreprocessor { class Intersectable; class VssRay; class SimpleRayContainer; class AxisAlignedBox3; struct VssRayContainer; class Preprocessor; struct SimpleRay; class RayPacket2x2; /** This class provides an interface for ray casting. */ class RayCaster { public: enum { INTERNAL_RAYCASTER = 0, INTEL_RAYCASTER = 1, HAVRAN_RAYCASTER = 2, HAVRAN_DYN_RAYCASTER = 3 }; RayCaster(const Preprocessor &preprocessor); virtual ~RayCaster(); virtual int Type() const = 0; /** Wrapper for casting single ray. @returns ray or NULL if invalid */ VssRay *CastRay(const SimpleRay &simpleRay, const AxisAlignedBox3 &box, const bool castDoubleRay); virtual int CastRay(const SimpleRay &simpleRay, VssRayContainer &vssRays, const AxisAlignedBox3 &box, const bool castDoubleRay, const bool pruneInvalidRays = true) = 0; virtual void CastRays16(SimpleRayContainer &rays, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRay, const bool pruneInvalidRays = true) = 0; virtual void CastRays( SimpleRayContainer &rays, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRay, const bool pruneInvalidRays = true); virtual void CastSimpleForwardRays(SimpleRayContainer &rays, const AxisAlignedBox3 &sbox ) { return;} // Using packet of 4 rays supposing that these are coherent virtual void CastRaysPacket4(Vector3 origin4[], Vector3 direction4[], int result4[], float dist4[]) { } // Using packet of 4 rays supposing that these are coherent // We give a box to which each ray is clipped to before the // ray shooting is computed ! virtual void CastRaysPacket4(const Vector3 &minBox, const Vector3 &maxBox, const Vector3 origin4[], const Vector3 direction4[], int result4[], float dist4[]) { } // Just for testing concept virtual void CastRaysPacket2x2(RayPacket2x2 &raysPack, bool castDoubleRay, const bool pruneInvalidRays = true) { } virtual void AddDynamicObjecs(const ObjectContainer &objects, const Matrix4x4 &m) { } virtual void UpdateDynamicObjects(const Matrix4x4 &m) { } virtual void DeleteDynamicObjects() { } /*virtual void CastRaysEye4(SimpleRayContainer &rays, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRay, const bool pruneInvalidRays = true) = 0; */ // This sorts only rays by origin virtual void SortRays(SimpleRayContainer &rays); // This sorts the ray by origin and direction virtual void SortRays2(SimpleRayContainer &rays); VssRay *RequestRay(const Vector3 &origin, const Vector3 &termination, Intersectable *originObject, Intersectable *terminationObject, const int pass, const float pdf); // pool of vss rays to be used in one pass of the sampling struct VssRayPool { VssRayPool(): mRays(NULL), mIndex(0), mNumber(0) {} ~VssRayPool() { delete []mRays; } void Reserve(const int number) { DEL_PTR(mRays); mRays = new VssRay[number]; mNumber = number; } void Clear() { mIndex = 0; } VssRay *Alloc() { #if 1 // reset pool if (mIndex == mNumber) { std::cerr << "warning: ray pool too small! " << std::endl; mIndex = 0; } // raypool larger index => enlarge ray pool #else if (mNumber == mIndex) { cerr << "warning: ray pool too small! " << "reserving " << mNumber * 2 << " rays" << std::endl; Reserve(mNumber * 2); } #endif return mRays + mIndex ++; } protected: VssRay *mRays; int mIndex; int mNumber; }; VssRayPool mVssRayPool; void ReserveVssRayPool(const int n) { mVssRayPool.Reserve(n); } void InitPass() { mVssRayPool.Clear(); } PerfTimer rawCastTimer; protected: void _SortRays(SimpleRayContainer &rays, const int l, const int r, const int depth, float *box); void _SortRays2(SimpleRayContainer &rays, const int l, const int r, const int depth, float box[12]); struct Intersection { Intersection(): mObject(NULL), mFaceId(0) {} Intersection(const Vector3 &p, const Vector3 &n, Intersectable *o, const int f): mPoint(p), mNormal(n), mObject(o), mFaceId(f) {} Intersection(const Vector3 &p): mPoint(p), mObject(NULL), mFaceId(0) {} //////////// Vector3 mPoint; Vector3 mNormal; Intersectable *mObject; int mFaceId; }; int ProcessRay(const SimpleRay &ray, Intersection &hitA, Intersection &hitB, VssRayContainer &vssRays, const AxisAlignedBox3 &box, const bool castDoubleRay, const bool pruneInvalidRays = true); /** Checks if ray is valid. I.e., the ray is in valid view space. @note: clamps the ray to valid view space. */ bool ValidateRay(const Vector3 &origin, const Vector3 &direction, const AxisAlignedBox3 &box, Intersection &hit); bool ClipToViewSpaceBox(const Vector3 &origin, const Vector3 &termination, Vector3 &clippedOrigin, Vector3 &clippedTermination); const Preprocessor &mPreprocessor; #if 1 public: // Added by VH for debugging Intersection intersect; #endif }; } #endif