#include "InternalRayCaster.h" #include "VssRay.h" #include "KdTree.h" #include "Preprocessor.h" #define DEBUG_RAYCAST 0 namespace GtpVisibilityPreprocessor { InternalRayCaster::InternalRayCaster(const Preprocessor &preprocessor): RayCaster(preprocessor) { } InternalRayCaster::~InternalRayCaster() { } int InternalRayCaster::CastRay(const SimpleRay &simpleRay, VssRayContainer &vssRays, const AxisAlignedBox3 &box, const bool castDoubleRay, const bool pruneInvalidRays) { if (simpleRay.mType == Ray::GLOBAL_RAY) return CastGlobalRay(simpleRay, vssRays, box, pruneInvalidRays); //cout << "internal ray" << endl; static Ray ray; int hits = 0; Intersection hitA(simpleRay.mOrigin), hitB(simpleRay.mOrigin); // inside test for bounding box // enlarge box slightly so the view point fits for sure // AxisAlignedBox3 sbox = box; // sbox.Enlarge(Vector3(-Limits::Small)); // $$ JB moved here from Validate routine // if (!box.IsInside(simpleRay.mOrigin)) { // cout<<"out of box "<CastRay(ray)) { hitA.mObject = ray.intersections[0].mObject; hitA.mPoint = ray.Extrap(ray.intersections[0].mT); hitA.mNormal = ray.intersections[0].mNormal; // cout << "hita: " << hitA.mPoint << " !obj: " << hitA.mObject << endl; } mPreprocessor.SetupRay(ray, simpleRay.mOrigin, -simpleRay.mDirection); ray.mFlags &= ~Ray::CULL_BACKFACES; if (castDoubleRay && mPreprocessor.mKdTree->CastRay(ray)) { hitB.mObject = ray.intersections[0].mObject; hitB.mPoint = ray.Extrap(ray.intersections[0].mT); hitB.mNormal = ray.intersections[0].mNormal; } return ProcessRay( simpleRay, hitA, hitB, vssRays, box, castDoubleRay, pruneInvalidRays ); } int InternalRayCaster::CastGlobalRay(const SimpleRay &simpleRay, VssRayContainer &vssRays, const AxisAlignedBox3 &box, const bool pruneInvalidRays ) { static Ray ray; int hits = 0; mPreprocessor.SetupRay(ray, simpleRay.mOrigin, simpleRay.mDirection); float tmin, tmax; if (!(box.ComputeMinMaxT(ray, &tmin, &tmax) && (tmin < tmax))) return 0; // shift the ray origin to tmin // Vector3 origin = ray.Extrap(tmin); // mPreprocessor.SetupRay(ray, origin, simpleRay.mDirection); ray.SetType(Ray::GLOBAL_RAY); ray.mFlags &= ~Ray::CULL_BACKFACES; VssRay *vssRay; if (mPreprocessor.mKdTree->CastRay(ray)) { // sort intersections ray.SortIntersections(); // cout<<"I="<mFlags |= VssRay::Valid; vssRay->mDistribution = simpleRay.mDistribution; vssRays.push_back(vssRay); ++hits; } hit = ray.intersections[ray.intersections.size()-1]; if (DotProd(hit.mNormal, ray.GetDir()) > 0) { // cout<<"L:"<mFlags |= VssRay::Valid; vssRay->mDistribution = simpleRay.mDistribution; vssRays.push_back(vssRay); ++hits; } // insert the rest of segments for (int i=0; i < ray.intersections.size() - 1; i++) { Ray::Intersection &hitA = ray.intersections[i]; Ray::Intersection &hitB = ray.intersections[i + 1]; if (hitB.mT - hitA.mT > Limits::Small) { if (DotProd(hitA.mNormal, ray.GetDir()) > 0 && DotProd(hitB.mNormal, ray.GetDir()) < 0 ) { vssRay = new VssRay( ray.Extrap(hitA.mT), ray.Extrap(hitB.mT), hitA.mObject, hitB.mObject, mPreprocessor.mPass, simpleRay.mPdf ); vssRay->mFlags |= VssRay::Valid; vssRay->mDistribution = simpleRay.mDistribution; vssRays.push_back(vssRay); ++hits; vssRay = new VssRay( ray.Extrap(hitB.mT), ray.Extrap(hitA.mT), hitB.mObject, hitA.mObject, mPreprocessor.mPass, simpleRay.mPdf ); vssRay->mFlags |= VssRay::Valid; vssRay->mDistribution = simpleRay.mDistribution; vssRays.push_back(vssRay); ++hits; } } } } return hits; } void InternalRayCaster::CastRays16(SimpleRayContainer &rays, VssRayContainer &vssRays, const AxisAlignedBox3 &sbox, const bool castDoubleRays, const bool pruneInvalidRays) { #if DEBUG_RAYCAST Debug << "C16 " << flush; #endif SimpleRayContainer::const_iterator sit, sit_end = rays.end(); // no acceleration for ray bundles implemented right now for (sit = rays.begin(); sit != sit_end; ++ sit) { CastRay(*sit, vssRays, sbox, castDoubleRays, pruneInvalidRays); } #if DEBUG_RAYCAST Debug<<"C16F\n"<