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

  1. /****************************************************************************
  2. *                   csg.c
  3. *
  4. *  This module implements routines for constructive solid geometry.
  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.  
  23. #include "frame.h"
  24. #include "vector.h"
  25. #include "povproto.h"
  26.  
  27. METHODS CSG_Union_Methods =
  28. { Object_Intersect, All_CSG_Union_Intersections,
  29.    Inside_CSG_Union, NULL,
  30.    Copy_CSG,
  31.    Translate_CSG, Rotate_CSG,
  32.    Scale_CSG, Invert_CSG};
  33.  
  34. METHODS CSG_Intersection_Methods =
  35. { Object_Intersect, All_CSG_Intersect_Intersections,
  36.    Inside_CSG_Intersection, NULL,
  37.    Copy_CSG,
  38.    Translate_CSG, Rotate_CSG,
  39.    Scale_CSG, Invert_CSG};
  40.  
  41. extern RAY *VP_Ray;
  42.  
  43. int All_CSG_Union_Intersections (Object, Ray, Depth_Queue)
  44. OBJECT *Object;
  45. RAY *Ray;
  46. PRIOQ *Depth_Queue;
  47. {
  48.    register int Intersection_Found;
  49.    CSG_SHAPE *Shape = (CSG_SHAPE *) Object;
  50.    SHAPE *Local_Shape;
  51.  
  52.    Intersection_Found = FALSE;
  53.    for (Local_Shape = Shape -> Shapes;
  54.               Local_Shape != NULL ;
  55.               Local_Shape = Local_Shape -> Next_Object)
  56.       if (All_Intersections ((OBJECT *) Local_Shape, Ray, Depth_Queue))
  57.          Intersection_Found = TRUE;
  58.  
  59.    return (Intersection_Found);
  60. }
  61.  
  62. int All_CSG_Intersect_Intersections (Object, Ray, Depth_Queue)
  63. OBJECT *Object;
  64. RAY *Ray;
  65. PRIOQ *Depth_Queue;
  66. {
  67.    int Intersection_Found, Any_Intersection_Found;
  68.    CSG_SHAPE *Shape = (CSG_SHAPE *) Object;
  69.    SHAPE *Local_Shape, *Shape2;
  70.    PRIOQ *Local_Depth_Queue;
  71.    INTERSECTION *Local_Intersection;
  72.  
  73.    Local_Depth_Queue = pq_new (128);
  74.  
  75.    Any_Intersection_Found = FALSE;
  76.  
  77.    for (Local_Shape = Shape -> Shapes ;
  78.               Local_Shape != NULL ;
  79.               Local_Shape = Local_Shape -> Next_Object) {
  80.  
  81.       All_Intersections ((OBJECT *) Local_Shape, Ray, Local_Depth_Queue);
  82.  
  83.       for (Local_Intersection = pq_get_highest (Local_Depth_Queue);
  84.                     Local_Intersection != NULL ;
  85.                     pq_delete_highest (Local_Depth_Queue),
  86.                     Local_Intersection = pq_get_highest (Local_Depth_Queue)) {
  87.  
  88.          Intersection_Found = TRUE;
  89.  
  90.          for (Shape2 = Shape -> Shapes;
  91.                           Shape2 != NULL ;
  92.                           Shape2 = Shape2 -> Next_Object)
  93.  
  94.             if (Shape2 != Local_Shape)
  95.                if (!Inside (&Local_Intersection->Point, (OBJECT *) Shape2)) {
  96.                   Intersection_Found = FALSE;
  97.                   break;
  98.                }
  99.  
  100.          if (Intersection_Found) {
  101.             pq_add (Depth_Queue, Local_Intersection);
  102.             Any_Intersection_Found = TRUE;
  103.          }
  104.       }
  105.    }
  106.  
  107.    pq_free (Local_Depth_Queue);
  108.  
  109.    return (Any_Intersection_Found);
  110. }
  111.  
  112. int Inside_CSG_Union (Test_Point, Object)
  113. VECTOR *Test_Point;
  114. OBJECT *Object;
  115. {
  116.    CSG_SHAPE *Shape = (CSG_SHAPE *) Object;
  117.    SHAPE *Local_Shape;
  118.  
  119.    for (Local_Shape = Shape -> Shapes ;
  120.               Local_Shape != NULL ;
  121.               Local_Shape = Local_Shape -> Next_Object)
  122.  
  123.       if (Inside (Test_Point, (OBJECT *) Local_Shape))
  124.          return (TRUE);
  125.    return (FALSE);
  126. }
  127.  
  128. int Inside_CSG_Intersection (Test_Point, Object)
  129. OBJECT *Object;
  130. VECTOR *Test_Point;
  131. {
  132.    SHAPE *Local_Shape;
  133.    CSG_SHAPE *Shape = (CSG_SHAPE *) Object;
  134.  
  135.    for (Local_Shape = Shape -> Shapes ;
  136.               Local_Shape != NULL ;
  137.               Local_Shape = Local_Shape -> Next_Object)
  138.  
  139.       if (!Inside (Test_Point, (OBJECT *) Local_Shape))
  140.          return (FALSE);
  141.  
  142.    return (TRUE);
  143. }
  144.  
  145. void *Copy_CSG (Object)
  146. OBJECT *Object;
  147. {
  148.    CSG_SHAPE *Shape = (CSG_SHAPE *) Object;
  149.    CSG_SHAPE *New_Shape;
  150.    SHAPE *Local_Shape, *Copied_Shape;
  151.  
  152.    New_Shape = Get_CSG_Shape ();
  153.    New_Shape->Methods = Shape->Methods;
  154.    New_Shape->Type = Shape->Type;
  155.    New_Shape -> Next_Object = NULL;
  156.    New_Shape -> Shapes = NULL;
  157.  
  158.    for (Local_Shape = Shape -> Shapes;
  159.               Local_Shape != NULL ;
  160.               Local_Shape = Local_Shape -> Next_Object) {
  161.  
  162.       Copied_Shape = (SHAPE *) Copy ((OBJECT *) Local_Shape);
  163.       Link ((OBJECT *) Copied_Shape,
  164.          (OBJECT **) &(Copied_Shape -> Next_Object),
  165.          (OBJECT **) &(New_Shape -> Shapes));
  166.    }
  167.    return ((void *)New_Shape);
  168. }
  169.  
  170. void Translate_CSG (Object, Vector)
  171. OBJECT *Object;
  172. VECTOR *Vector;
  173. {
  174.    SHAPE *Local_Shape;
  175.  
  176.    for (Local_Shape = ((CSG_SHAPE *) Object) -> Shapes;
  177.               Local_Shape != NULL ;
  178.               Local_Shape = Local_Shape -> Next_Object)
  179.  
  180.       Translate ((OBJECT *) Local_Shape, Vector);   
  181. }
  182.  
  183. void Rotate_CSG (Object, Vector)
  184. OBJECT *Object;
  185. VECTOR *Vector;
  186. {
  187.    SHAPE *Local_Shape;
  188.  
  189.    for (Local_Shape = ((CSG_SHAPE *) Object) -> Shapes;
  190.               Local_Shape != NULL ;
  191.               Local_Shape = Local_Shape -> Next_Object)
  192.  
  193.       Rotate ((OBJECT *) Local_Shape, Vector);   
  194. }
  195.  
  196. void Scale_CSG (Object, Vector)
  197. OBJECT *Object;
  198. VECTOR *Vector;
  199. {
  200.    SHAPE *Local_Shape;
  201.  
  202.    for (Local_Shape = ((CSG_SHAPE *) Object) -> Shapes;
  203.               Local_Shape != NULL ;
  204.               Local_Shape = Local_Shape -> Next_Object)
  205.  
  206.       Scale ((OBJECT *) Local_Shape, Vector);   
  207. }
  208.  
  209. void Invert_CSG (Object)
  210. OBJECT *Object;
  211. {
  212.    SHAPE *Local_Shape;
  213.    CSG_SHAPE *Csg = (CSG_SHAPE *) Object;
  214.  
  215.    if (Csg->Type == CSG_INTERSECTION_TYPE) {
  216.       Csg->Type = CSG_UNION_TYPE;
  217.       Csg->Methods = &CSG_Union_Methods;
  218.    }
  219.    else if (Csg->Type == CSG_UNION_TYPE) {
  220.       Csg->Type = CSG_INTERSECTION_TYPE;
  221.       Csg->Methods = &CSG_Intersection_Methods;
  222.    }
  223.  
  224.    for (Local_Shape = Csg -> Shapes;
  225.               Local_Shape != NULL ;
  226.               Local_Shape = Local_Shape -> Next_Object)
  227.  
  228.       Invert ((OBJECT *) Local_Shape);   
  229. }
  230.  
  231. void Set_CSG_Parents (Shape, Object)
  232. CSG_SHAPE *Shape;
  233. OBJECT *Object;
  234. {
  235.    SHAPE *Local_Shape;
  236.  
  237.    for (Local_Shape = Shape -> Shapes;
  238.               Local_Shape != NULL ;
  239.               Local_Shape = Local_Shape -> Next_Object) {
  240.  
  241.       Local_Shape->Parent_Object = Object;
  242.       if ((Local_Shape->Type == CSG_UNION_TYPE) ||
  243.          (Local_Shape->Type == CSG_INTERSECTION_TYPE))
  244.          Set_CSG_Parents((CSG_SHAPE *)Local_Shape, Object);
  245.    }
  246. }
  247.