#include "RayCaster.h" #include "VssRay.h" #include "Ray.h" #include "Preprocessor.h" namespace GtpVisibilityPreprocessor { #define DEBUG_RAYCAST 0 #define EXACT_BOX_CLIPPING 1 RayCaster::RayCaster(const Preprocessor &preprocessor): mPreprocessor(preprocessor) { } RayCaster::~RayCaster() { } VssRay *RayCaster::CastRay(const SimpleRay &simpleRay, const AxisAlignedBox3 &box, const bool castDoubleRay) { VssRayContainer rays; CastRay(simpleRay, rays, box, castDoubleRay); if (!rays.empty()) return rays.back(); else return NULL; } /** Checks if ray is valid, (e.g., not in empty view space or outside the view space) */ bool RayCaster::ValidateRay(const Vector3 &origin, const Vector3 &direction, const AxisAlignedBox3 &box, Intersection &hit) { if (!hit.mObject) { // compute intersection with the scene bounding box #if EXACT_BOX_CLIPPING static Ray ray; mPreprocessor.SetupRay(ray, origin, direction); float tmin, tmax; if (box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax)) { hit.mPoint = ray.Extrap(tmax); } else { // cout<<" invalid hp "<= 0) { hit.mObject = NULL; return false; } } return true; } int RayCaster::ProcessRay(const SimpleRay &simpleRay, Intersection &hitA, Intersection &hitB, VssRayContainer &vssRays, const AxisAlignedBox3 &box, const bool castDoubleRay, const bool pruneInvalidRays) { int hits = 0; #if DEBUG_RAYCAST Debug<<"PR "; #endif if (pruneInvalidRays) { if (!hitA.mObject && !hitB.mObject) { return 0; } } const bool validA = ValidateRay(simpleRay.mOrigin, simpleRay.mDirection, box, hitA); if (!validA && pruneInvalidRays) { return 0; } const bool validB = castDoubleRay && ValidateRay(simpleRay.mOrigin, -simpleRay.mDirection, box, hitB); if (!validB && pruneInvalidRays) { return 0; } const bool validSample = !pruneInvalidRays || (hitA.mObject != hitB.mObject); if (validSample) { if (!pruneInvalidRays || hitA.mObject) { VssRay *vssRay = new VssRay( hitB.mPoint, hitA.mPoint, hitB.mObject, hitA.mObject, mPreprocessor.mPass, simpleRay.mPdf ); vssRays.push_back(vssRay); ++ hits; //cout << "vssray 1: " << *vssRay << " " << vssRay->mTermination - vssRay->mOrigin << endl; } if (castDoubleRay && (!pruneInvalidRays || hitB.mObject)) { VssRay *vssRay = new VssRay( hitA.mPoint, hitB.mPoint, hitA.mObject, hitB.mObject, mPreprocessor.mPass, simpleRay.mPdf ); vssRays.push_back(vssRay); ++ hits; //cout << "vssray 2: " << *vssRay << endl; } } return hits; } }