bool Intersect_BBox_Tree(BBoxPriorityQueue& pqueue, const BBOX_TREE *Root, const Ray& ray, Intersection *Best_Intersection, const RayObjectCondition& precondition, const RayObjectCondition& postcondition, TraceThreadData *Thread) { int i, found; DBL Depth; const BBOX_TREE *Node; Intersection New_Intersection; // Create the direction vectors for this ray. Rayinfo rayinfo(ray); // Start with an empty priority queue. pqueue.Clear(); New_Intersection.Object = NULL; found = false; // Check top node. Check_And_Enqueue(pqueue, Root, &Root->BBox, &rayinfo, Thread); // Check elements in the priority queue. while(!pqueue.IsEmpty()) { pqueue.RemoveMin(Depth, Node); // If current intersection is larger than the best intersection found // so far our task is finished, because all other bounding boxes in // the priority queue are further away. if(Depth > Best_Intersection->Depth) break; // Check current node. if(Node->Entries) { // This is a node containing leaves to be checked. for (i = 0; i < Node->Entries; i++) Check_And_Enqueue(pqueue, Node->Node[i], &Node->Node[i]->BBox, &rayinfo, Thread); } else { if(precondition(ray, reinterpret_cast<ObjectPtr>(Node->Node), 0.0) == true) { // This is a leaf so test contained object. if(Find_Intersection(&New_Intersection, reinterpret_cast<ObjectPtr>(Node->Node), ray, postcondition, Thread)) { if(New_Intersection.Depth < Best_Intersection->Depth) { *Best_Intersection = New_Intersection; found = true; } } } } } return (found); }
bool Ray_In_Bound (const Ray& ray, const vector<ObjectPtr>& Bounding_Object, TraceThreadData *Thread) { Intersection Local; for(vector<ObjectPtr>::const_iterator Bound = Bounding_Object.begin(); Bound != Bounding_Object.end(); Bound++) { Thread->Stats()[Bounding_Region_Tests]++; if((!Find_Intersection (&Local, *Bound, ray, Thread)) && (!Inside_Object(ray.Origin, *Bound, Thread))) return false; Thread->Stats()[Bounding_Region_Tests_Succeeded]++; } return true; }