home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Graphics / Graphics.zip / pov22f.zip / source / objects.c < prev    next >
C/C++ Source or Header  |  1993-10-28  |  8KB  |  380 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 long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
  29. extern long Clipping_Region_Tests, Clipping_Region_Tests_Succeeded;
  30. extern unsigned int Options;
  31. extern long Istack_overflows;
  32. extern int Number_of_istacks;
  33. extern int Max_Intersections;
  34. extern ISTACK *free_istack;
  35.  
  36. int Intersection (Ray_Intersection, Object, Ray)
  37. INTERSECTION *Ray_Intersection;
  38. OBJECT *Object;
  39. RAY *Ray;
  40.   {
  41.   ISTACK *Depth_Stack;
  42.   INTERSECTION *Local;
  43.   DBL Closest = HUGE_VAL;
  44.  
  45.   if (Object == NULL)
  46.     return (FALSE);
  47.  
  48.   if(!Ray_In_Bounds (Ray,Object->Bound))
  49.     return (FALSE);
  50.  
  51.   Depth_Stack = open_istack ();
  52.  
  53.   if (All_Intersections (Object, Ray, Depth_Stack))
  54.     {
  55.     while ((Local = pop_entry(Depth_Stack)) != NULL)
  56.       if (Local->Depth < Closest)
  57.         {
  58.         *Ray_Intersection = *Local;
  59.         Closest = Local->Depth;
  60.         }
  61.     close_istack (Depth_Stack);
  62.     return (TRUE);
  63.     }
  64.   else
  65.     {
  66.     close_istack (Depth_Stack);
  67.     return (FALSE);
  68.     }
  69.   }
  70.  
  71. int Ray_In_Bounds (Ray,Bounds)
  72. RAY *Ray;
  73. OBJECT *Bounds;
  74.   {
  75.   OBJECT *Bound;
  76.   INTERSECTION Local;
  77.  
  78.   for (Bound = Bounds;
  79.   Bound != NULL;
  80.   Bound = Bound->Sibling)
  81.     {
  82.     Bounding_Region_Tests++;
  83.  
  84.     if (!Intersection (&Local, Bound, Ray))
  85.       if (!Inside_Object(&Ray->Initial,Bound))
  86.         return (FALSE);
  87.  
  88.     Bounding_Region_Tests_Succeeded++;
  89.     }
  90.  
  91.   return (TRUE);
  92.   }
  93.  
  94. int Point_In_Clip (IPoint, Clip)
  95. VECTOR *IPoint;
  96. OBJECT *Clip;
  97.   {
  98.   OBJECT *Local_Clip;
  99.  
  100.   for (Local_Clip = Clip;
  101.   Local_Clip != NULL;
  102.   Local_Clip = Local_Clip->Sibling)
  103.     {
  104.     Clipping_Region_Tests++;
  105.     if (!Inside_Object(IPoint, Local_Clip)) 
  106.       return (FALSE);
  107.  
  108.     Clipping_Region_Tests_Succeeded++;
  109.     }
  110.   return (TRUE);
  111.   }
  112.  
  113. OBJECT *Copy_Bound_Clip (Old)
  114. OBJECT *Old;
  115.   {
  116.   OBJECT *Current, *New, *Prev, *First;
  117.  
  118.   First = Prev = NULL;
  119.  
  120.   for (Current = Old;
  121.   Current != NULL ;
  122.   Current = Current->Sibling) 
  123.     {
  124.     New = Copy_Object (Current);
  125.     if (First == NULL)
  126.       First = New;
  127.     if (Prev != NULL)
  128.       Prev->Sibling = New;
  129.     Prev = New;
  130.     }
  131.   return (First);
  132.   }
  133.  
  134. OBJECT *Copy_Object (Old)
  135. OBJECT *Old;
  136.   {
  137.   OBJECT *New;
  138.  
  139.   if (Old == NULL)
  140.     return (NULL);
  141.  
  142.   New = Copy (Old);
  143.  
  144.   /* The following copying of OBJECT_FIELDS is redundant if Copy 
  145.    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.   New->Methods = Old->Methods;
  150.   New->Type    = Old->Type;
  151.   New->Sibling = Old->Sibling;
  152.   New->Texture = Old->Texture;
  153.   New->Bound   = Old->Bound;
  154.   New->Clip    = Old->Clip;
  155.   New->Bounds  = Old->Bounds;
  156.   New->No_Shadow_Flag = Old->No_Shadow_Flag;
  157.  
  158.   New->Sibling = NULL;          /* Important */
  159.  
  160.   New->Texture = Copy_Textures (Old->Texture);
  161.   New->Bound   = Copy_Bound_Clip (Old->Bound);
  162.   if (Old->Bound != Old->Clip)
  163.     New->Clip  = Copy_Bound_Clip (Old->Clip);
  164.   else
  165.     New->Clip  = New->Bound;
  166.  
  167.   return (New);
  168.   }   
  169.  
  170. void Translate_Object (Object, Vector)
  171. OBJECT *Object;
  172. VECTOR *Vector;
  173.   {
  174.   OBJECT *Sib;
  175.  
  176.   if (Object == NULL)
  177.     return;
  178.  
  179.   for (Sib = Object->Bound;
  180.   Sib != NULL;
  181.   Sib = Sib->Sibling)
  182.     Translate_Object (Sib, Vector);
  183.  
  184.   if (Object->Clip != Object->Bound)
  185.     for (Sib = Object->Clip;
  186.   Sib != NULL;
  187.   Sib = Sib->Sibling)
  188.     Translate_Object (Sib, Vector);
  189.  
  190.   Translate_Textures (Object->Texture,Vector);
  191.  
  192.   Translate (Object,Vector);
  193.   }
  194.  
  195. void Rotate_Object (Object, Vector)
  196. OBJECT *Object;
  197. VECTOR *Vector;
  198.   {
  199.   OBJECT *Sib;
  200.  
  201.   if (Object == NULL)
  202.     return;
  203.  
  204.   for (Sib = Object->Bound;
  205.   Sib != NULL;
  206.   Sib = Sib->Sibling)
  207.     Rotate_Object (Sib, Vector);
  208.  
  209.   if (Object->Clip != Object->Bound)
  210.     for (Sib = Object->Clip;
  211.   Sib != NULL;
  212.   Sib = Sib->Sibling)
  213.     Rotate_Object (Sib, Vector);
  214.  
  215.   Rotate_Textures (Object->Texture,Vector);
  216.  
  217.   Rotate (Object,Vector);
  218.   }
  219.  
  220. void Scale_Object (Object, Vector)
  221. OBJECT *Object;
  222. VECTOR *Vector;
  223.   {
  224.   OBJECT *Sib;
  225.  
  226.   if (Object == NULL)
  227.     return;
  228.  
  229.   for (Sib = Object->Bound;
  230.   Sib != NULL;
  231.   Sib = Sib->Sibling)
  232.     Scale_Object (Sib, Vector);
  233.  
  234.   if (Object->Clip != Object->Bound)
  235.     for (Sib = Object->Clip;
  236.   Sib != NULL;
  237.   Sib = Sib->Sibling)
  238.     Scale_Object (Sib, Vector);
  239.  
  240.   Scale_Textures (Object->Texture,Vector);
  241.  
  242.   Scale (Object,Vector);
  243.   }
  244.  
  245. int Inside_Object (IPoint, Object)
  246. VECTOR *IPoint;
  247. OBJECT *Object;
  248.   {
  249.   OBJECT *Sib;
  250.  
  251.   /* removed 7/19/92 CEY   
  252.    for (Sib = Object->Bound;
  253.         Sib != NULL;
  254.         Sib = Sib->Sibling)
  255.      if (!Inside_Object(IPoint, Sib))
  256.        return(FALSE);
  257. */
  258.   for (Sib = Object->Clip;
  259.   Sib != NULL;
  260.   Sib = Sib->Sibling)
  261.     if (!Inside_Object(IPoint, Sib))
  262.       return(FALSE);
  263.  
  264.   return (Inside(IPoint,Object));
  265.   }
  266.  
  267. void Invert_Object (Object)
  268. OBJECT *Object;
  269.   {
  270.   /*   OBJECT *Sib; */
  271.  
  272.   if (Object == NULL)
  273.     return;
  274.  
  275.   /* removed 3/29/93 CEY
  276.    for (Sib = Object->Clip;
  277.         Sib != NULL;
  278.         Sib = Sib->Sibling)
  279.      Invert_Object (Sib);
  280. */
  281.   Invert (Object);
  282.   }
  283.  
  284. void Destroy_Object (Object)
  285. OBJECT *Object;
  286.   {
  287.   OBJECT *Sib;
  288.  
  289.   while (Object != NULL)
  290.     {
  291.     Destroy_Textures (Object->Texture);
  292.     Destroy_Object (Object->Bound);
  293.     if (Object->Bound != Object->Clip)
  294.       Destroy_Object (Object->Clip);
  295.     Sib = Object->Sibling;
  296.     Destroy(Object);
  297.     Object = Sib;
  298.     }
  299.   }   
  300.  
  301. void Transform_Object (Object, Trans)
  302. OBJECT *Object;
  303. TRANSFORM *Trans;
  304.   {
  305.   OBJECT *Sib;
  306.  
  307.   if (Object == NULL)
  308.     return;
  309.  
  310.   for (Sib = Object->Bound;
  311.   Sib != NULL;
  312.   Sib = Sib->Sibling)
  313.     Transform_Object (Sib, Trans);
  314.  
  315.   if (Object->Clip != Object->Bound)
  316.     for (Sib = Object->Clip;
  317.   Sib != NULL;
  318.   Sib = Sib->Sibling)
  319.     Transform_Object (Sib, Trans);
  320.  
  321.   Transform_Textures (Object->Texture,Trans);
  322.  
  323.   Transform (Object,Trans);
  324.   }
  325.  
  326. void create_istack ()
  327.   {
  328.   ISTACK *New;
  329.  
  330.   if ((New = (ISTACK *) malloc (sizeof (ISTACK))) == NULL) 
  331.     {
  332.     fprintf (stderr, "\nOut of memory. Cannot allocate istack");
  333.     close_all();
  334.     exit(1);
  335.     }
  336.  
  337.   New->next = free_istack;
  338.   free_istack = New;
  339.  
  340.   if ((New->istack = (INTERSECTION *)
  341.     malloc (Max_Intersections * sizeof (INTERSECTION))) == NULL) 
  342.     {
  343.     fprintf (stderr, "\nOut of memory. Cannot allocate istack entries");
  344.     close_all();
  345.     exit(1);
  346.     }
  347.   Number_of_istacks++;
  348.   }
  349.  
  350. ISTACK *open_istack()
  351.   {
  352.   ISTACK *istk;
  353.  
  354.   if (free_istack == NULL) 
  355.     create_istack ();
  356.  
  357.   istk = free_istack;
  358.   free_istack = istk->next;
  359.   istk->top_entry = 0;
  360.  
  361.   return (istk);
  362.   }
  363.  
  364. void close_istack (istk)
  365. ISTACK *istk;
  366.   {
  367.   istk->next = free_istack;
  368.   free_istack = istk;
  369.   }
  370.  
  371. void incstack(istk)
  372. ISTACK *istk;
  373.   {
  374.   if (++istk->top_entry >= (unsigned int)Max_Intersections)
  375.     {
  376.     istk->top_entry--;
  377.     Istack_overflows++;
  378.     }
  379.   }
  380.