#ifndef _HavranRayCaster_H__ #define _HavranRayCaster_H__ #include "RayCaster.h" #include "Containers.h" #include #ifdef USE_HAVRAN_RAYCASTER #include "ktbconf.h" #include "raypack.h" #endif // USE_HAVRAN_RAYCASTER namespace GtpVisibilityPreprocessor { class Intersectable; class VssRay; class KdTree; class Ray; class SimpleRayContainer; class AxisAlignedBox3; class Vector3; struct VssRayContainer; class Preprocessor; struct SimpleRay; class CKTB; // This macro should be undefined when testing ray tracing // by casting rays from file or using camera #define _PROCESS_RAY /** This class provides an interface for ray casting. */ class HavranRayCaster: public RayCaster { public: /** Default constructor initialising e.g., KD tree */ HavranRayCaster(const Preprocessor &preprocessor); virtual ~HavranRayCaster(); void Build(ObjectContainer &objlist); int Type() const { return HAVRAN_RAYCASTER; } virtual int CastRay( const SimpleRay &simpleRay, VssRayContainer &vssRays, const AxisAlignedBox3 &box, const bool castDoubleRay, const bool pruneInvalidRays = true ); virtual void CastRays16(SimpleRayContainer &rays, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRay, const bool pruneInvalidRays = true ); virtual void CastRays16(SimpleRayContainer &rays, int offset, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRay, const bool pruneInvalidRays = true ); void CastSimpleForwardRays(SimpleRayContainer &rays, const AxisAlignedBox3 &sbox ); virtual void CastRays( SimpleRayContainer &rays, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRay, const bool pruneInvalidRays = true); // 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[]); #ifdef _USE_HAVRAN_SSE // Just for testing concept virtual void CastRaysPacket2x2(RayPacket2x2 &raysPack, bool castDoubleRay, const bool pruneInvalidRays = true); #endif bool ExportBinTree(const string &filename); bool ImportBinTree(const string &filename, ObjectContainer &objects); protected: CKTB *mKtbtree; #ifdef _USE_HAVRAN_SSE static GALIGN16 RayPacket2x2 raypack; #endif }; // -------------------------------------------------------------------- // The implementation of ray caster with dynamic objects class HavranDynRayCaster: public HavranRayCaster { public: /** Default constructor initialising e.g., KD tree */ HavranDynRayCaster(const Preprocessor &preprocessor); virtual ~HavranDynRayCaster(); int Type() const { return HAVRAN_DYN_RAYCASTER; } virtual int CastRay(const SimpleRay &simpleRay, VssRayContainer &vssRays, const AxisAlignedBox3 &box, const bool castDoubleRay, const bool pruneInvalidRays = true ); virtual void CastRays16(SimpleRayContainer &rays, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRay, const bool pruneInvalidRays = true ); virtual void CastRays16(SimpleRayContainer &rays, int offset, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRay, const bool pruneInvalidRays = true ); virtual void CastSimpleForwardRays(SimpleRayContainer &rays, const AxisAlignedBox3 &sbox); virtual void CastRays(SimpleRayContainer &rays, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRay, const bool pruneInvalidRays = true); // 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[]); #ifdef _USE_HAVRAN_SSE // Just for testing concept virtual void CastRaysPacket2x2(RayPacket2x2 &raysPack, bool castDoubleRay, const bool pruneInvalidRays = true); #endif virtual void AddDynamicObjecs(const ObjectContainer &objects, const Matrix4x4 &m); virtual void UpdateDynamicObjects(const Matrix4x4 &m); virtual void DeleteDynamicObjects(); protected: // The kd-tree for dynamic objects CKTB *mDynKtbtree; #ifdef _USE_HAVRAN_SSE // This has to be aligned by 16 Bytes boundary - if HavranDynRayCaster // is aligned, then also this data entity below !!! static GALIGN16 RayPacket2x2 raypack_t; #endif ObjectContainer *dynobjects; bool dynamicFlag; Matrix4x4 matTr, matTr_inv; int result4_t[4]; float dist4_t[4]; SimpleRay sray_t; Vector3 orig[16]; Vector3 dirs[16]; float tdist[32]; Intersectable* objI[32]; Vector3 normal[32]; // This transforms the ray void ApplyTransform(SimpleRay &sray) { sray.mOrigin = matTr_inv * sray.mOrigin; sray.mDirection = RotateOnly(matTr_inv, sray.mDirection); // note that normalization to the unit size of the direction // is NOT computed -- this is what we want. } }; } // namespace #endif //#endif // _HavranRayCaster_H__