Esempio n. 1
0
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);
}
Esempio n. 2
0
int Intersect_Light_Tree(RAY *Ray, PROJECT_TREE_NODE *Tree, int x, int  y, INTERSECTION *Best_Intersection, OBJECT **Best_Object, LIGHT_SOURCE * /*Light_Source*/)
{
  INTERSECTION New_Intersection;
  unsigned short i;
  int Found;
  RAYINFO rayinfo;
  DBL key;
  BBOX_TREE *BBox_Node;
  PROJECT_TREE_NODE *Node;

  /* If there's no vista tree then return. */

  if (Tree == NULL)
  {
    return(false);
  }

  /* Start with an empty priority queue */

  New_Intersection.Object = NULL;

  VLBuffer_Queue->QSize = 0;

  Found = false;

#ifdef BBOX_EXTRA_STATS
  Increase_Counter(stats[totalQueueResets]);
#endif

  /* Traverse the tree. */

  Node_Queue->QSize = 0;

  /* Create the direction vectors for this ray */

  Create_Rayinfo(Ray, &rayinfo);

  /* Fill the priority queue with all possible candidates */

  /* Check root */

  Increase_Counter(stats[LBuffer_Tests]);

  if ((x >= Tree->Project.x1) && (x <= Tree->Project.x2) &&
      (y >= Tree->Project.y1) && (y <= Tree->Project.y2))
  {
    Increase_Counter(stats[LBuffer_Tests_Succeeded]);

    Node_Queue->Queue[(Node_Queue->QSize)++] = Tree;
  }

  /* Loop until queue is empty. */

  while (Node_Queue->QSize > 0)
  {
    Tree = Node_Queue->Queue[--(Node_Queue->QSize)];

    if (Tree->is_leaf)
    {
      /* Leaf --> test object's bounding box in 3d */

      Check_And_Enqueue(VLBuffer_Queue,
        ((PROJECT_TREE_LEAF *)Tree)->Node,
        &((PROJECT_TREE_LEAF *)Tree)->Node->BBox, &rayinfo);
    }
    else
    {
      /* Check siblings of the node in 2d */

      for (i = 0; i < Tree->Entries; i++)
      {
        Node = Tree->Entry[i];

        Increase_Counter(stats[LBuffer_Tests]);

        if ((x >= Node->Project.x1) && (x <= Node->Project.x2) &&
            (y >= Node->Project.y1) && (y <= Node->Project.y2))
        {
          Increase_Counter(stats[LBuffer_Tests_Succeeded]);

          /* Reallocate queues if they're too small. */

          Reinitialize_VLBuffer_Code();

          /* Add node to node queue */

          Node_Queue->Queue[(Node_Queue->QSize)++] = Node;
        }
      }
    }
  }

  /* Now test the candidates in the priority queue */

  while (VLBuffer_Queue->QSize > 0)
  {
    Priority_Queue_Delete(VLBuffer_Queue, &key, &BBox_Node);

    if (key > Best_Intersection->Depth)
    {
      break;
    }

        if (Intersection(&New_Intersection, (OBJECT *)BBox_Node->Node, Ray))
        {
      if (New_Intersection.Depth < Best_Intersection->Depth &&
        /* NK Feb 6, 2000 - bugfix */
        New_Intersection.Depth > Small_Tolerance)
          {
            *Best_Intersection = New_Intersection;

            *Best_Object = (OBJECT *)BBox_Node->Node;
    
            Found = true;
          }
        }
  }

  return(Found);
}
Esempio n. 3
0
bool Intersect_BBox_Tree(BBOX_TREE *Root, RAY *Ray, INTERSECTION *Best_Intersection, OBJECT **Best_Object, bool shadow_flag)
{
  int i, found;
  DBL Depth;
  BBOX_TREE *Node;
  RAYINFO rayinfo;
  INTERSECTION New_Intersection;

  /* Create the direction vectors for this ray. */

  Create_Rayinfo(Ray, &rayinfo);

  /* Start with an empty priority queue. */

  New_Intersection.Object = NULL;
  found = false;

  Frame_Queue->QSize = 0;

#ifdef BBOX_EXTRA_STATS
  Increase_Counter(stats[totalQueueResets]);
#endif

  /* Check top node. */

  Check_And_Enqueue(Frame_Queue, Root, &Root->BBox, &rayinfo);

  /* Check elements in the priority queue. */

  while (Frame_Queue->QSize)
  {
    Priority_Queue_Delete(Frame_Queue, &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(Frame_Queue, Node->Node[i], &Node->Node[i]->BBox, &rayinfo);
      }
    }
    else
    {
      /* This is a leaf so test contained object. */

      /* Add Object-Ray options [ENB 9/97] */
      if ( TEST_RAY_FLAGS_SHADOW((OBJECT *)Node->Node) )
      {
        if (Intersection(&New_Intersection, (OBJECT *)Node->Node, Ray))
        {
          if (New_Intersection.Depth < Best_Intersection->Depth)
          {
            *Best_Intersection = New_Intersection;

            *Best_Object = (OBJECT *)Node->Node;

            found = true;
          }
        }
      }
    }
  }

  return (found);
}