home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / RAYTRACE / POVRAY2 / SRC / OBJECTS.C < prev    next >
C/C++ Source or Header  |  1993-07-28  |  8KB  |  376 lines

  1. /****************************************************************************
  2. *                objects.c
  3. *
  4. *  This module implements the methods for objects and composite objects.
  5. *
  6. *  from Persistence of Vision Raytracer
  7. *  Copyright 1993 Persistence of Vision Team
  8. *---------------------------------------------------------------------------
  9. *  NOTICE: This source code file is provided so that users may experiment
  10. *  with enhancements to POV-Ray and to port the software to platforms other 
  11. *  than those supported by the POV-Ray Team.  There are strict rules under
  12. *  which you are permitted to use this file.  The rules are in the file
  13. *  named POVLEGAL.DOC which should be distributed with this file. If 
  14. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  15. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  16. *  Forum.  The latest version of POV-Ray may be found there as well.
  17. *
  18. * This program is based on the popular DKB raytracer version 2.12.
  19. * DKBTrace was originally written by David K. Buck.
  20. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  21. *
  22. *****************************************************************************/
  23.  
  24. #include "frame.h"
  25. #include "vector.h"
  26. #include "povproto.h"
  27.  
  28. extern RAY *VP_Ray;
  29. extern long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
  30. extern long Clipping_Region_Tests, Clipping_Region_Tests_Succeeded;
  31. extern unsigned int Options;
  32. extern long Istack_overflows;
  33. extern int Number_of_istacks;
  34. extern int Max_Intersections;
  35. extern ISTACK *free_istack;
  36.  
  37. int Intersection (Ray_Intersection, Object, Ray)
  38. INTERSECTION *Ray_Intersection;
  39. OBJECT *Object;
  40. RAY *Ray;
  41.   {
  42.   ISTACK *Depth_Stack;
  43.   INTERSECTION *Local;
  44.   DBL Closest = HUGE_VAL;
  45.  
  46.   if (Object == NULL)
  47.     return (FALSE);
  48.  
  49.   if(!Ray_In_Bounds (Ray,Object->Bound))
  50.     return (FALSE);
  51.  
  52.   Depth_Stack = open_istack ();
  53.  
  54.   if (All_Intersections (Object, Ray, Depth_Stack))
  55.     {
  56.     while ((Local = pop_entry(Depth_Stack)) != NULL)
  57.       if (Local->Depth < Closest)
  58.         {
  59.         *Ray_Intersection = *Local;
  60.         Closest = Local->Depth;
  61.         }
  62.     close_istack (Depth_Stack);
  63.     return (TRUE);
  64.     }
  65.   else
  66.     {
  67.     close_istack (Depth_Stack);
  68.     return (FALSE);
  69.     }
  70.   }
  71.  
  72. int Ray_In_Bounds (Ray,Bounds)
  73. RAY *Ray;
  74. OBJECT *Bounds;
  75.   {
  76.   OBJECT *Bound;
  77.   INTERSECTION Local;
  78.  
  79.   for (Bound = Bounds;
  80.   Bound != NULL;
  81.   Bound = Bound->Sibling)
  82.     {
  83.     Bounding_Region_Tests++;
  84.  
  85.     if (!Intersection (&Local, Bound, Ray))
  86.       if (!Inside_Object(&Ray->Initial,Bound))
  87.         return (FALSE);
  88.  
  89.     Bounding_Region_Tests_Succeeded++;
  90.     }
  91.  
  92.   return (TRUE);
  93.   }
  94.  
  95. int Point_In_Clip (IPoint, Clip)
  96. VECTOR *IPoint;
  97. OBJECT *Clip;
  98.   {
  99.   OBJECT *Local_Clip;
  100.  
  101.   for (Local_Clip = Clip;
  102.   Local_Clip != NULL;
  103.   Local_Clip = Local_Clip->Sibling)
  104.     {
  105.     Clipping_Region_Tests++;
  106.     if (!Inside_Object(IPoint, Local_Clip)) 
  107.       return (FALSE);
  108.  
  109.     Clipping_Region_Tests_Succeeded++;
  110.     }
  111.   return (TRUE);
  112.   }
  113.  
  114. OBJECT *Copy_Bound_Clip (Old)
  115. OBJECT *Old;
  116.   {
  117.   OBJECT *Current, *New, *Prev, *First;
  118.  
  119.   First = Prev = NULL;
  120.  
  121.   for (Current = Old;
  122.   Current != NULL ;
  123.   Current = Current->Sibling) 
  124.     {
  125.     New = Copy_Object (Current);
  126.     if (First == NULL)
  127.       First = New;
  128.     if (Prev != NULL)
  129.       Prev->Sibling = New;
  130.     Prev = New;
  131.     }
  132.   return (First);
  133.   }
  134.  
  135. OBJECT *Copy_Object (Old)
  136. OBJECT *Old;
  137.   {
  138.   OBJECT *New;
  139.  
  140.   if (Old == NULL)
  141.     return (NULL);
  142.  
  143.   New = Copy (Old);
  144.  
  145.   /* This is redundant if Copy did *New = *Old but we cannot assume it did.
  146.    It is safe for Copy to do *New = *Old but it should not otherwise
  147.    touch OBJECT_FIELDS.
  148.    
  149.    Because New and Old are type OBJECT, only OBJECT_FIELDS are affected
  150.    by the next statement. */
  151.  
  152.   *New = *Old;
  153.  
  154.   New->Sibling = NULL;          /* Important */
  155.  
  156.   New->Texture = Copy_Textures (Old->Texture);
  157.   New->Bound   = Copy_Bound_Clip (Old->Bound);
  158.   if (Old->Bound != Old->Clip)
  159.     New->Clip  = Copy_Bound_Clip (Old->Clip);
  160.   else
  161.     New->Clip  = New->Bound;
  162.  
  163.   return (New);
  164.   }   
  165.  
  166. void Translate_Object (Object, Vector)
  167. OBJECT *Object;
  168. VECTOR *Vector;
  169.   {
  170.   OBJECT *Sib;
  171.  
  172.   if (Object == NULL)
  173.     return;
  174.  
  175.   for (Sib = Object->Bound;
  176.   Sib != NULL;
  177.   Sib = Sib->Sibling)
  178.     Translate_Object (Sib, Vector);
  179.  
  180.   if (Object->Clip != Object->Bound)
  181.     for (Sib = Object->Clip;
  182.   Sib != NULL;
  183.   Sib = Sib->Sibling)
  184.     Translate_Object (Sib, Vector);
  185.  
  186.   Translate_Textures (Object->Texture,Vector);
  187.  
  188.   Translate (Object,Vector);
  189.   }
  190.  
  191. void Rotate_Object (Object, Vector)
  192. OBJECT *Object;
  193. VECTOR *Vector;
  194.   {
  195.   OBJECT *Sib;
  196.  
  197.   if (Object == NULL)
  198.     return;
  199.  
  200.   for (Sib = Object->Bound;
  201.   Sib != NULL;
  202.   Sib = Sib->Sibling)
  203.     Rotate_Object (Sib, Vector);
  204.  
  205.   if (Object->Clip != Object->Bound)
  206.     for (Sib = Object->Clip;
  207.   Sib != NULL;
  208.   Sib = Sib->Sibling)
  209.     Rotate_Object (Sib, Vector);
  210.  
  211.   Rotate_Textures (Object->Texture,Vector);
  212.  
  213.   Rotate (Object,Vector);
  214.   }
  215.  
  216. void Scale_Object (Object, Vector)
  217. OBJECT *Object;
  218. VECTOR *Vector;
  219.   {
  220.   OBJECT *Sib;
  221.  
  222.   if (Object == NULL)
  223.     return;
  224.  
  225.   for (Sib = Object->Bound;
  226.   Sib != NULL;
  227.   Sib = Sib->Sibling)
  228.     Scale_Object (Sib, Vector);
  229.  
  230.   if (Object->Clip != Object->Bound)
  231.     for (Sib = Object->Clip;
  232.   Sib != NULL;
  233.   Sib = Sib->Sibling)
  234.     Scale_Object (Sib, Vector);
  235.  
  236.   Scale_Textures (Object->Texture,Vector);
  237.  
  238.   Scale (Object,Vector);
  239.   }
  240.  
  241. int Inside_Object (IPoint, Object)
  242. VECTOR *IPoint;
  243. OBJECT *Object;
  244.   {
  245.   OBJECT *Sib;
  246.  
  247.   /* removed 7/19/92 CEY   
  248.    for (Sib = Object->Bound;
  249.         Sib != NULL;
  250.         Sib = Sib->Sibling)
  251.      if (!Inside_Object(IPoint, Sib))
  252.        return(FALSE);
  253. */
  254.   for (Sib = Object->Clip;
  255.   Sib != NULL;
  256.   Sib = Sib->Sibling)
  257.     if (!Inside_Object(IPoint, Sib))
  258.       return(FALSE);
  259.  
  260.   return (Inside(IPoint,Object));
  261.   }
  262.  
  263. void Invert_Object (Object)
  264. OBJECT *Object;
  265.   {
  266.   /*   OBJECT *Sib; */
  267.  
  268.   if (Object == NULL)
  269.     return;
  270.  
  271.   /* removed 3/29/93 CEY
  272.    for (Sib = Object->Clip;
  273.         Sib != NULL;
  274.         Sib = Sib->Sibling)
  275.      Invert_Object (Sib);
  276. */
  277.   Invert (Object);
  278.   }
  279.  
  280. void Destroy_Object (Object)
  281. OBJECT *Object;
  282.   {
  283.   OBJECT *Sib;
  284.  
  285.   while (Object != NULL)
  286.     {
  287.     Destroy_Textures (Object->Texture);
  288.     Destroy_Object (Object->Bound);
  289.     if (Object->Bound != Object->Clip)
  290.       Destroy_Object (Object->Clip);
  291.     Sib = Object->Sibling;
  292.     Destroy(Object);
  293.     Object = Sib;
  294.     }
  295.   }   
  296.  
  297. void Transform_Object (Object, Trans)
  298. OBJECT *Object;
  299. TRANSFORM *Trans;
  300.   {
  301.   OBJECT *Sib;
  302.  
  303.   if (Object == NULL)
  304.     return;
  305.  
  306.   for (Sib = Object->Bound;
  307.   Sib != NULL;
  308.   Sib = Sib->Sibling)
  309.     Transform_Object (Sib, Trans);
  310.  
  311.   if (Object->Clip != Object->Bound)
  312.     for (Sib = Object->Clip;
  313.   Sib != NULL;
  314.   Sib = Sib->Sibling)
  315.     Transform_Object (Sib, Trans);
  316.  
  317.   Transform_Textures (Object->Texture,Trans);
  318.  
  319.   Transform (Object,Trans);
  320.   }
  321.  
  322. void create_istack ()
  323.   {
  324.   ISTACK *New;
  325.  
  326.   if ((New = (ISTACK *) malloc (sizeof (ISTACK))) == NULL) 
  327.     {
  328.     fprintf (stderr, "\nOut of memory. Cannot allocate istack");
  329.     close_all();
  330.     exit(1);
  331.     }
  332.  
  333.   New->next = free_istack;
  334.   free_istack = New;
  335.  
  336.   if ((New->istack = (INTERSECTION *)
  337.     malloc (Max_Intersections * sizeof (INTERSECTION))) == NULL) 
  338.     {
  339.     fprintf (stderr, "\nOut of memory. Cannot allocate istack entries");
  340.     close_all();
  341.     exit(1);
  342.     }
  343.   Number_of_istacks++;
  344.   }
  345.  
  346. ISTACK *open_istack()
  347.   {
  348.   ISTACK *istk;
  349.  
  350.   if (free_istack == NULL) 
  351.     create_istack ();
  352.  
  353.   istk = free_istack;
  354.   free_istack = istk->next;
  355.   istk->top_entry = 0;
  356.  
  357.   return (istk);
  358.   }
  359.  
  360. void close_istack (istk)
  361. ISTACK *istk;
  362.   {
  363.   istk->next = free_istack;
  364.   free_istack = istk;
  365.   }
  366.  
  367. void incstack(istk)
  368. ISTACK *istk;
  369.   {
  370.   if (++istk->top_entry >= (unsigned int)Max_Intersections)
  371.     {
  372.     istk->top_entry--;
  373.     Istack_overflows++;
  374.     }
  375.   }
  376.