#include "RayCaster.h" #include "VssRay.h" #include "Ray.h" #include "Preprocessor.h" #include "ViewCellsManager.h" namespace GtpVisibilityPreprocessor { #define DEBUG_RAYCAST 0 #define EXACT_BOX_CLIPPING 0 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, true); if (!rays.empty()) return rays.back(); else return NULL; } bool RayCaster::ClipToViewSpaceBox(const Vector3 &origin, const Vector3 &termination, Vector3 &clippedOrigin, Vector3 &clippedTermination) { Ray ray(origin, termination - origin, Ray::LINE_SEGMENT); ray.Precompute(); float tmin, tmax; if ((!mPreprocessor.mViewCellsManager-> GetViewSpaceBox().ComputeMinMaxT(ray, &tmin, &tmax)) || tmin>=tmax ) return false; if (tmin >= 1.0f || tmax <=0.0f) return false; if (tmin > 0.0f) clippedOrigin = ray.Extrap(tmin); else clippedOrigin = origin; if (tmax < 1.0f) clippedTermination = ray.Extrap(tmax); else clippedTermination = termination; return true; } /** 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 "<= -Limits::Small) { hit.mObject = NULL; return false; } } } return true; } void RayCaster::SortRays(SimpleRayContainer &rays) { AxisAlignedBox3 box = mPreprocessor.mViewCellsManager->GetViewSpaceBox(); float b[12]={ box.Min().x, box.Min().y, box.Min().z, -1, -1, -1, box.Max().x, box.Max().y, box.Max().z, 1, 1, 1 }; _SortRays(rays, 0, (int)rays.size()-1, 0, b ); } void RayCaster::_SortRays(SimpleRayContainer &rays, const int l, const int r, const int depth, float box[12]) { // pick-up a pivot int axis; float maxDiff = -1.0f; // get the largest axis int offset = 0; int i; const int batchsize = 8192; // if (r - l < 32*batchsize) // offset = 3; // if (depth%5==0) // offset = 3; for (i=offset; i < offset + 3; i++) { float diff = box[i + 6] - box[i]; if (diff > maxDiff) { maxDiff = diff; axis = i; } } // cout<mFlags |= VssRay::Valid; vssRay->mDistribution = simpleRay.mDistribution; vssRay->mGeneratorId = simpleRay.mGeneratorId; vssRays.push_back(vssRay); ++ hits; //cout << "vssray 1: " << *vssRay << " " << vssRay->mTermination - vssRay->mOrigin << endl; } #if DEBUG_RAYCAST Debug<<"PR3"<mFlags |= VssRay::Valid; vssRay->mDistribution = simpleRay.mDistribution; vssRay->mGeneratorId = simpleRay.mGeneratorId; vssRays.push_back(vssRay); ++ hits; //cout << "vssray 2: " << *vssRay << endl; } #if DEBUG_RAYCAST Debug<<"PR4"<