bool Find_Intersection(Intersection *isect, ObjectPtr object, const Ray& ray, const RayObjectCondition& postcondition, TraceThreadData *threadData) { if(object != NULL) { DBL closest = HUGE_VAL; BBoxVector3d origin; BBoxVector3d invdir; BBoxDirection variant; Vector3d tmp(1.0 / ray.GetDirection()[X], 1.0 / ray.GetDirection()[Y], 1.0 /ray.GetDirection()[Z]); origin = BBoxVector3d(ray.Origin); invdir = BBoxVector3d(tmp); variant = (BBoxDirection)((int(invdir[X] < 0.0) << 2) | (int(invdir[Y] < 0.0) << 1) | int(invdir[Z] < 0.0)); if(object->Intersect_BBox(variant, origin, invdir, closest) == false) return false; if(object->Bound.empty() == false) { if(Ray_In_Bound(ray, object->Bound, threadData) == false) return false; } IStack depthstack(threadData->stackPool); POV_REFPOOL_ASSERT(depthstack->empty()); // verify that the IStack pulled from the pool is in a cleaned-up condition if(object->All_Intersections(ray, depthstack, threadData)) { bool found = false; double tmpDepth = 0; while(depthstack->size() > 0) { tmpDepth = depthstack->top().Depth; // TODO FIXME - This was SMALL_TOLERANCE, but that's too rough for some scenes [cjc] need to check what it was in the old code [trf] if(tmpDepth < closest && (ray.IsSubsurfaceRay() || tmpDepth >= MIN_ISECT_DEPTH) && postcondition(ray, object, tmpDepth)) { *isect = depthstack->top(); closest = tmpDepth; found = true; } depthstack->pop(); } return (found == true); } POV_REFPOOL_ASSERT(depthstack->empty()); // verify that the IStack is in a cleaned-up condition (again) } return false; }
bool LightSource::All_Intersections(const Ray& ray, IStack& Depth_Stack, TraceThreadData *Thread) { if(!children.empty()) { if(children[0]->Bound.empty() || Ray_In_Bound(ray, children[0]->Bound, Thread)) { if(children[0]->All_Intersections(ray, Depth_Stack, Thread)) return true; } } return false; }
bool Find_Intersection(Intersection *isect, ObjectPtr object, const Ray& ray, ObjectBase::BBoxDirection variant, const BBOX_VECT& origin, const BBOX_VECT& invdir, const RayObjectCondition& postcondition, TraceThreadData *threadData) { if(object != NULL) { DBL closest = HUGE_VAL; if(object->Intersect_BBox(variant, origin, invdir, closest) == false) return false; if(object->Bound.empty() == false) { if(Ray_In_Bound(ray, object->Bound, threadData) == false) return false; } IStack depthstack(threadData->stackPool); assert(depthstack->empty()); // verify that the IStack pulled from the pool is in a cleaned-up condition if(object->All_Intersections(ray, depthstack, threadData)) { bool found = false; double tmpDepth = 0; while(depthstack->size() > 0) { tmpDepth = depthstack->top().Depth; // TODO FIXME - This was SMALL_TOLERANCE, but that's too rough for some scenes [cjc] need to check what it was in the old code [trf] if(tmpDepth < closest && (ray.IsSubsurfaceRay() || tmpDepth >= MIN_ISECT_DEPTH) && postcondition(ray, object, tmpDepth)) { *isect = depthstack->top(); closest = tmpDepth; found = true; } depthstack->pop(); } return (found == true); } assert(depthstack->empty()); // verify that the IStack is in a cleaned-up condition (again) } return false; }
bool Intersection (INTERSECTION *Ray_Intersection, OBJECT *Object, RAY *Ray) { ISTACK *Depth_Stack; INTERSECTION *Local; DBL Closest = HUGE_VAL; if (Object == NULL) { return (false); } if (!Ray_In_Bound (Ray,Object->Bound)) { return (false); } Depth_Stack = open_istack (); if (All_Intersections (Object, Ray, Depth_Stack)) { while ((Local = pop_entry(Depth_Stack)) != NULL) { if (Local->Depth < Closest) { *Ray_Intersection = *Local; Closest = Local->Depth; } } close_istack (Depth_Stack); return (true); } else { close_istack (Depth_Stack); return (false); } }