home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / povsrc.sit / SOURCE / PRIOQ.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-03  |  3.9 KB  |  175 lines

  1. /****************************************************************************
  2. *                prioq.c
  3. *
  4. *  This module implements a priority queue using a heap.
  5. *
  6. *  from Persistence of Vision Raytracer 
  7. *  Copyright 1992 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  Copying, distribution and legal info is in the file povlegal.doc which
  10. *  should be distributed with this file. If povlegal.doc is not available
  11. *  or for more info please contact:
  12. *
  13. *       Drew Wells [POV-Team Leader] 
  14. *       CIS: 73767,1244  Internet: 73767.1244@compuserve.com
  15. *       Phone: (213) 254-4041
  16. * This program is based on the popular DKB raytracer version 2.12.
  17. * DKBTrace was originally written by David K. Buck.
  18. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  19. *
  20. *****************************************************************************/
  21.  
  22. #include "frame.h"
  23. #include "povproto.h"
  24.  
  25. #define NUMBER_OF_PRIOQS 32
  26. #define NUMBER_OF_INTERSECTIONS 128
  27.  
  28. PRIOQ *prioqs;
  29.  
  30. void pq_init ()
  31. {
  32.    register int i;
  33.    PRIOQ *new_pq;
  34.  
  35.    prioqs = NULL;
  36.  
  37.    for (i = 0 ; i < NUMBER_OF_PRIOQS; i++)
  38.    {
  39.       if ((new_pq = (PRIOQ *) malloc (sizeof (PRIOQ))) == NULL) {
  40.          fprintf (stderr, "\nOut of memory. Cannot allocate queues");
  41.          close_all();
  42.          exit(1);
  43.       }
  44.  
  45.       new_pq -> next_pq = prioqs;
  46.       prioqs = new_pq;
  47.  
  48.       if ((new_pq -> queue = (INTERSECTION *)
  49.          malloc (NUMBER_OF_INTERSECTIONS * sizeof (INTERSECTION))) == NULL) {
  50.          fprintf (stderr, "\nOut of memory. Cannot allocate queue entries");
  51.          close_all();
  52.          exit(1);
  53.       }
  54.    }
  55. }
  56.  
  57. PRIOQ *pq_alloc()
  58. {
  59.    PRIOQ *allocated_queue;
  60.  
  61.    if (prioqs == NULL) {
  62.       fprintf (stderr, "\nOut of prioqs");
  63.       close_all();
  64.       exit(1);
  65.    }
  66.  
  67.    allocated_queue = prioqs;
  68.    prioqs = allocated_queue -> next_pq;
  69.    return (allocated_queue);
  70. }
  71.  
  72. void pq_free (pq)
  73. PRIOQ *pq;
  74. {
  75.    pq -> next_pq = prioqs;
  76.    prioqs = pq;
  77. }
  78.  
  79. PRIOQ *pq_new (index_size)
  80. int index_size;
  81. {
  82.    PRIOQ *pq;
  83.  
  84.    if (index_size >= NUMBER_OF_INTERSECTIONS)    /* Charles Marslett */
  85.       index_size = NUMBER_OF_INTERSECTIONS - 1;    /* Most real scenes overflow! */
  86.  
  87.  
  88.    if ((pq = pq_alloc()) == NULL)
  89.       return (NULL);
  90.  
  91.    pq -> queue_size = index_size;
  92.    pq -> current_entry = 0;
  93.    return (pq);
  94. }
  95.  
  96. void pq_balance(q, entry_pos1)
  97. PRIOQ *q;
  98. unsigned int entry_pos1;
  99. {
  100.    register INTERSECTION *entry1, *entry2;
  101.    INTERSECTION temp_entry;
  102.    register unsigned int entry_pos2;
  103.  
  104.    entry1 = &q->queue[entry_pos1];
  105.  
  106.    if ((entry_pos1 * 2 < q->queue_size)
  107.       && (entry_pos1 * 2 <= q -> current_entry))
  108.    {
  109.       if ((entry_pos1*2+1 > q->current_entry) ||
  110.          (q->queue[entry_pos1*2].Depth < q->queue[entry_pos1*2+1].Depth))
  111.          entry_pos2 = entry_pos1*2;
  112.       else
  113.          entry_pos2 = entry_pos1*2+1;
  114.  
  115.       entry2 = &q->queue[entry_pos2];
  116.  
  117.       if (entry1->Depth > entry2->Depth) {
  118.          temp_entry = *entry1;
  119.          *entry1 = *entry2;
  120.          *entry2 = temp_entry;
  121.          pq_balance (q, entry_pos2);
  122.       }
  123.    }
  124.  
  125.    if (entry_pos1 / 2 >= 1 )
  126.    {
  127.       entry_pos2 = entry_pos1 / 2;
  128.       entry2 = &q->queue[entry_pos2];
  129.       if (entry1->Depth < entry2->Depth) {
  130.          temp_entry = *entry1;
  131.          *entry1 = *entry2;
  132.          *entry2 = temp_entry;
  133.          pq_balance (q, entry_pos2);
  134.       }
  135.    }
  136. }
  137.  
  138. void pq_add (q, queue_entry)
  139. PRIOQ *q;
  140. INTERSECTION *queue_entry;
  141. {
  142.    q -> current_entry++;
  143.    if (q -> current_entry >= q -> queue_size)
  144.       q -> current_entry--;
  145.  
  146.    q -> queue [q -> current_entry] = *queue_entry;
  147.    pq_balance (q, q -> current_entry);
  148. }
  149.  
  150. INTERSECTION *pq_get_highest(q)
  151. PRIOQ *q;
  152. {
  153.    if (q -> current_entry >= 1)
  154.       return (&(q -> queue[1]));
  155.    else
  156.       return (NULL);
  157. }
  158.  
  159. int pq_is_empty(q)
  160. PRIOQ *q;
  161. {
  162.    if (q -> current_entry < 1)
  163.       return (TRUE);
  164.    else
  165.       return (FALSE);
  166. }
  167.  
  168. void pq_delete_highest (q)
  169. PRIOQ *q;
  170. {
  171.    q -> queue[1] = q -> queue[q -> current_entry--];
  172.    pq_balance (q, 1);
  173. }
  174.