#include "RayCaster.h" #include "VssRay.h" #include "Ray.h" #include "Preprocessor.h" namespace GtpVisibilityPreprocessor { #define DEBUG_RAYCAST 0 RayCaster::RayCaster(const Preprocessor &preprocessor): mPreprocessor(preprocessor) { } RayCaster::~RayCaster() { } VssRay *RayCaster::CastSingleRay(const Vector3 &viewPoint, const Vector3 &direction, const float probability, const AxisAlignedBox3 &box) { VssRayContainer rays; CastRay(viewPoint, direction, probability, rays, box, false); if (!rays.empty()) return rays.back(); else return NULL; } int RayCaster::ProcessRay(const Vector3 &viewPoint, const Vector3 &direction, Intersectable *objectA, Vector3 &pointA, const Vector3 &normalA, Intersectable *objectB, Vector3 &pointB, const Vector3 &normalB, const float probability, VssRayContainer &vssRays, const AxisAlignedBox3 &box ) { int hits = 0; #if DEBUG_RAYCAST Debug<<"PR "; #endif if (objectA == NULL && objectB == NULL) return 0; AxisAlignedBox3 sbox = box; sbox.Enlarge(Vector3(-Limits::Small)); if (!sbox.IsInside(viewPoint)) return 0; if (objectA == NULL) { // compute intersection with the scene bounding box static Ray ray; mPreprocessor.SetupRay(ray, viewPoint, direction); float tmin, tmax; if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax) pointA = ray.Extrap(tmax); else return 0; } else { if (mPreprocessor.mDetectEmptyViewSpace) if (DotProd(normalA, direction) >= 0) { // discard the sample return 0; } } if (objectB == NULL) { // compute intersection with the scene bounding box static Ray ray; mPreprocessor.SetupRay(ray, viewPoint, -direction); float tmin, tmax; if (box.ComputeMinMaxT(ray, &tmin, &tmax) && tmin < tmax) pointB = ray.Extrap(tmax); else return 0; } else { if (mPreprocessor.mDetectEmptyViewSpace) if (DotProd(normalB, direction) <= 0) { // discard the sample return 0; } } VssRay *vssRay = NULL; bool validSample = (objectA != objectB); if (validSample) { if (objectA) { vssRay = new VssRay( pointB, pointA, objectB, objectA, mPreprocessor.mPass, probability ); vssRays.push_back(vssRay); hits ++; } if (objectB) { vssRay = new VssRay( pointA, pointB, objectA, objectB, mPreprocessor.mPass, probability ); vssRays.push_back(vssRay); hits ++; } } return hits; } }