home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / povsrc.sit / SOURCE / OBJECTS.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-03  |  16.6 KB  |  563 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 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. extern RAY *VP_Ray;
  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.  
  32. METHODS Composite_Methods =
  33. { Object_Intersect, All_Composite_Intersections,
  34.    Inside_Composite_Object, NULL,
  35.    Copy_Composite_Object,
  36.    Translate_Composite_Object, Rotate_Composite_Object,
  37.    Scale_Composite_Object, Invert_Composite_Object};
  38.  
  39. METHODS Basic_Object_Methods =
  40. { Object_Intersect, All_Object_Intersections,
  41.    Inside_Basic_Object, NULL,
  42.    Copy_Basic_Object,
  43.    Translate_Basic_Object, Rotate_Basic_Object,
  44.    Scale_Basic_Object, Invert_Basic_Object};
  45.  
  46.  
  47. INTERSECTION *Object_Intersect (Object, Ray)
  48. OBJECT *Object;
  49. RAY *Ray;
  50. {
  51.    INTERSECTION *Local_Intersection, *Queue_Element;
  52.    PRIOQ *Depth_Queue;
  53.  
  54.    Depth_Queue = pq_new (128);
  55.  
  56.    if ((All_Intersections (Object, Ray, Depth_Queue))
  57.       && ((Queue_Element = pq_get_highest (Depth_Queue)) != NULL))
  58.    {
  59.       if ((Local_Intersection = (INTERSECTION *) malloc(sizeof(INTERSECTION)))
  60.          == NULL) {
  61.          printf("Cannot allocate memory for local intersection\n");
  62.          exit(1);
  63.       }
  64.       Local_Intersection->Point = Queue_Element->Point;
  65.       Local_Intersection->Shape = Queue_Element->Shape;
  66.       Local_Intersection->Depth = Queue_Element->Depth;
  67.       Local_Intersection->Object = Queue_Element->Object;
  68.       pq_free (Depth_Queue);
  69.       return (Local_Intersection);
  70.    }
  71.    else
  72.    {
  73.       pq_free (Depth_Queue);
  74.       return (NULL);
  75.    }
  76. }
  77.  
  78.  
  79. int All_Composite_Intersections (Object, Ray, Depth_Queue)
  80. OBJECT *Object;
  81. RAY *Ray;
  82. PRIOQ *Depth_Queue;
  83. {
  84.    register int Intersection_Found, Any_Intersection_Found;
  85.    SHAPE *Bounding_Shape;
  86.    SHAPE *Clipping_Shape;
  87.    INTERSECTION *Local_Intersection;
  88.    OBJECT *Local_Object;
  89.    PRIOQ *Local_Depth_Queue;
  90.  
  91.    for (Bounding_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  92.               Bounding_Shape != NULL ;
  93.               Bounding_Shape = Bounding_Shape -> Next_Object) {
  94.  
  95.       Bounding_Region_Tests++;
  96.       COOPERATE
  97.       if ((Local_Intersection = Intersection ((OBJECT *) Bounding_Shape, Ray)) != NULL)
  98.          free (Local_Intersection);
  99.       else
  100.          if (!Inside (&Ray -> Initial, (OBJECT *) Bounding_Shape))
  101.             return (FALSE);
  102.       Bounding_Region_Tests_Succeeded++;
  103.    }
  104.  
  105.    Local_Depth_Queue = pq_new (128);
  106.    Any_Intersection_Found = FALSE;
  107.  
  108.    for (Local_Object = ((COMPOSITE *) Object) -> Objects ;
  109.               Local_Object != NULL ;
  110.               Local_Object = Local_Object -> Next_Object)
  111.  
  112.       All_Intersections (Local_Object, Ray, Local_Depth_Queue);
  113.  
  114.    for (Local_Intersection = pq_get_highest (Local_Depth_Queue);
  115.           Local_Intersection != NULL ;
  116.           pq_delete_highest (Local_Depth_Queue),
  117.           Local_Intersection = pq_get_highest (Local_Depth_Queue)) {
  118.  
  119.       Intersection_Found = TRUE;
  120.  
  121.       for (Clipping_Shape = Object -> Clipping_Shapes ;
  122.                      Clipping_Shape != NULL ;
  123.                      Clipping_Shape = Clipping_Shape -> Next_Object) {
  124.          Clipping_Region_Tests++;
  125.          if (!Inside (&Local_Intersection->Point, (OBJECT *) Clipping_Shape)) {
  126.             Intersection_Found = FALSE;
  127.             break;
  128.          }
  129.          Clipping_Region_Tests_Succeeded++;
  130.       }
  131.  
  132.       if (Intersection_Found) {
  133.          pq_add (Depth_Queue, Local_Intersection);
  134.          Any_Intersection_Found = TRUE;
  135.       }
  136.    }
  137.    pq_free (Local_Depth_Queue);
  138.    return (Any_Intersection_Found);
  139. }
  140.  
  141.  
  142. int All_Object_Intersections (Object, Ray, Depth_Queue)
  143. OBJECT *Object;
  144. RAY *Ray;
  145. PRIOQ *Depth_Queue;
  146. {
  147.    int Intersection_Found, Any_Intersection_Found;
  148.    INTERSECTION *Local_Intersection;
  149.    SHAPE *Bounding_Shape;
  150.    SHAPE *Clipping_Shape;
  151.    PRIOQ *Local_Depth_Queue;
  152.  
  153.    for (Bounding_Shape = Object -> Bounding_Shapes ;
  154.               Bounding_Shape != NULL ;
  155.               Bounding_Shape = Bounding_Shape -> Next_Object) {
  156.  
  157.       Bounding_Region_Tests++;
  158.       COOPERATE
  159.       if ((Local_Intersection = Intersection ((OBJECT *) Bounding_Shape, Ray)) != NULL)
  160.          free (Local_Intersection);
  161.       else
  162.          if (!Inside (&Ray -> Initial, (OBJECT *) Bounding_Shape))
  163.             return (FALSE);
  164.       Bounding_Region_Tests_Succeeded++;
  165.    }
  166.  
  167.    Local_Depth_Queue = pq_new (128);
  168.    Any_Intersection_Found = FALSE;
  169.    All_Intersections ((OBJECT *)Object->Shape, Ray, Local_Depth_Queue);
  170.  
  171.    for (Local_Intersection = pq_get_highest (Local_Depth_Queue);
  172.              Local_Intersection != NULL ;
  173.             pq_delete_highest (Local_Depth_Queue),
  174.             Local_Intersection = pq_get_highest (Local_Depth_Queue)) {
  175.  
  176.       Intersection_Found = TRUE;
  177.  
  178.       for (Clipping_Shape = Object -> Clipping_Shapes ;
  179.                 Clipping_Shape != NULL ;
  180.                 Clipping_Shape = Clipping_Shape -> Next_Object) {
  181.  
  182.          Clipping_Region_Tests++;
  183.          if (Options & DEBUGGING) {
  184.             printf("Test (%.4lf, %.4lf, %.4lf)\n",
  185.                Local_Intersection->Point.x,
  186.                Local_Intersection->Point.y,
  187.                Local_Intersection->Point.z);
  188.          }
  189.          if (!Inside (&Local_Intersection->Point, (OBJECT *) Clipping_Shape)) {
  190.             if (Options & DEBUGGING)
  191.                printf("not ok\n");
  192.             Intersection_Found = FALSE;
  193.             break;
  194.          }
  195.          Clipping_Region_Tests_Succeeded++; 
  196.       }
  197.  
  198.       if (Intersection_Found) {
  199.          if (Options & DEBUGGING)
  200.             printf("ok\n");
  201.          pq_add (Depth_Queue, Local_Intersection);
  202.          Any_Intersection_Found = TRUE;
  203.  
  204.       }
  205.    }
  206.    pq_free (Local_Depth_Queue);
  207.    return (Any_Intersection_Found);
  208. }
  209.  
  210.  
  211. int Inside_Basic_Object (Test_Point, Object)
  212. VECTOR *Test_Point;
  213. OBJECT *Object;
  214. {
  215.    SHAPE *Bounding_Shape;
  216.    SHAPE *Clipping_Shape;
  217.  
  218.    for (Bounding_Shape = Object -> Bounding_Shapes ;
  219.               Bounding_Shape != NULL ;
  220.               Bounding_Shape = Bounding_Shape -> Next_Object)
  221.  
  222.       if (!Inside (Test_Point, (OBJECT *) Bounding_Shape))
  223.          return (FALSE);
  224.  
  225.    for (Clipping_Shape = Object -> Clipping_Shapes ;
  226.                Clipping_Shape != NULL ;
  227.                Clipping_Shape = Clipping_Shape -> Next_Object)
  228.  
  229.       if (!Inside (Test_Point, (OBJECT *) Clipping_Shape))
  230.          return (FALSE);
  231.  
  232.    if (Inside (Test_Point, (OBJECT *) Object -> Shape))
  233.       return (TRUE);
  234.    return (FALSE);
  235. }
  236.  
  237. int Inside_Composite_Object (Test_Point, Object)
  238. VECTOR *Test_Point;
  239. OBJECT *Object;
  240. {
  241.    SHAPE *Bounding_Shape;
  242.    SHAPE *Clipping_Shape;
  243.    OBJECT *Local_Object;
  244.  
  245.    for (Bounding_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  246.               Bounding_Shape != NULL ;
  247.               Bounding_Shape = Bounding_Shape -> Next_Object)
  248.  
  249.       if (!Inside (Test_Point, (OBJECT *) Bounding_Shape))
  250.          return (FALSE);
  251.  
  252.    for (Clipping_Shape = ((COMPOSITE *) Object) -> Clipping_Shapes ;
  253.               Clipping_Shape != NULL ;
  254.               Clipping_Shape = Clipping_Shape -> Next_Object)
  255.  
  256.       if (!Inside (Test_Point, (OBJECT *) Clipping_Shape))
  257.          return (FALSE);
  258.  
  259.    for (Local_Object = ((COMPOSITE *) Object) -> Objects ;
  260.               Local_Object != NULL ;
  261.               Local_Object = Local_Object -> Next_Object)
  262.  
  263.       if (Inside (Test_Point, Local_Object))
  264.          return (TRUE);
  265.  
  266.    return (FALSE);
  267. }
  268.  
  269. void *Copy_Basic_Object (Object)
  270. OBJECT *Object;
  271. {
  272.    SHAPE *Local_Shape, *Copied_Shape;
  273.    OBJECT *New_Object;
  274.  
  275.    New_Object = Get_Object();
  276.    *New_Object = *Object;
  277.    New_Object -> Next_Object = NULL;
  278.    New_Object -> Bounding_Shapes = NULL;
  279.    New_Object -> Clipping_Shapes = NULL;
  280.    for (Local_Shape = Object -> Bounding_Shapes ;
  281.               Local_Shape != NULL ;
  282.               Local_Shape = Local_Shape -> Next_Object) {
  283.  
  284.       Copied_Shape = (SHAPE *) Copy((OBJECT *) Local_Shape);
  285.       Link ((OBJECT *) Copied_Shape,
  286.          (OBJECT **) &(Copied_Shape -> Next_Object),
  287.          (OBJECT **) &(New_Object -> Bounding_Shapes));
  288.  
  289.       if ((Copied_Shape->Type == CSG_UNION_TYPE)
  290.          || (Copied_Shape->Type == CSG_INTERSECTION_TYPE)
  291.          || (Copied_Shape->Type == CSG_DIFFERENCE_TYPE))
  292.          Set_CSG_Parents ((CSG_SHAPE *) Copied_Shape, New_Object);
  293.    }
  294.  
  295.    for (Local_Shape = Object -> Clipping_Shapes ;
  296.               Local_Shape != NULL ;
  297.               Local_Shape = Local_Shape -> Next_Object) {
  298.  
  299.       Copied_Shape = (SHAPE *) Copy((OBJECT *) Local_Shape);
  300.       Link ((OBJECT *) Copied_Shape,
  301.          (OBJECT **) &(Copied_Shape -> Next_Object),
  302.          (OBJECT **) &(New_Object -> Clipping_Shapes));
  303.  
  304.       if ((Copied_Shape->Type == CSG_UNION_TYPE)
  305.          || (Copied_Shape->Type == CSG_INTERSECTION_TYPE)
  306.          || (Copied_Shape->Type == CSG_DIFFERENCE_TYPE))
  307.          Set_CSG_Parents ((CSG_SHAPE *) Copied_Shape, New_Object);
  308.    }
  309.  
  310.    New_Object -> Shape = (SHAPE *) Copy((OBJECT *) Object -> Shape);
  311.    if ((New_Object->Shape->Type == CSG_UNION_TYPE)
  312.       || (New_Object->Shape->Type == CSG_INTERSECTION_TYPE)
  313.       || (New_Object->Shape->Type == CSG_DIFFERENCE_TYPE))
  314.       Set_CSG_Parents ((CSG_SHAPE *) New_Object->Shape, New_Object);
  315.    else
  316.       New_Object->Shape->Parent_Object = New_Object;
  317.  
  318.  
  319.    if (New_Object->Object_Texture != NULL)
  320.       New_Object->Object_Texture = Copy_Texture (New_Object->Object_Texture);
  321.  
  322.    return ((void *)New_Object);
  323. }
  324.  
  325. void *Copy_Composite_Object (Object)
  326. OBJECT *Object;
  327. {
  328.    COMPOSITE *New_Object;
  329.    SHAPE *Local_Shape;
  330.    OBJECT *Local_Object, *Copied_Object;
  331.  
  332.    New_Object = Get_Composite_Object();
  333.    *New_Object = *((COMPOSITE *) Object);
  334.    New_Object -> Next_Object = NULL;
  335.    New_Object -> Objects = NULL;
  336.    for (Local_Object = ((COMPOSITE *) Object) -> Objects;
  337.               Local_Object != NULL ;
  338.               Local_Object = Local_Object -> Next_Object) {
  339.  
  340.       Copied_Object = (OBJECT *) Copy(Local_Object);
  341.       Link (Copied_Object,
  342.          &(Copied_Object -> Next_Object),
  343.          &(New_Object -> Objects));
  344.    }
  345.  
  346.    New_Object -> Bounding_Shapes = NULL;
  347.    for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes;
  348.               Local_Shape != NULL ;
  349.               Local_Shape = Local_Shape -> Next_Object) {
  350.  
  351.       Copied_Object = (OBJECT *) Copy((OBJECT *) Local_Shape);
  352.       Link (Copied_Object,
  353.          &(Copied_Object -> Next_Object),
  354.          (OBJECT **) &(New_Object -> Bounding_Shapes));
  355.    }
  356.    New_Object -> Clipping_Shapes = NULL;
  357.    for (Local_Shape = ((COMPOSITE *) Object) -> Clipping_Shapes;
  358.               Local_Shape != NULL ;
  359.               Local_Shape = Local_Shape -> Next_Object) {
  360.  
  361.       Copied_Object = (OBJECT *) Copy((OBJECT *) Local_Shape);
  362.       Link (Copied_Object,
  363.          &(Copied_Object -> Next_Object),
  364.          (OBJECT **) &(New_Object -> Clipping_Shapes));
  365.    }
  366.    return ((void *)New_Object);
  367. }
  368.  
  369. void Translate_Basic_Object (Object, Vector)
  370. OBJECT *Object;
  371. VECTOR *Vector;
  372. {
  373.    SHAPE *Local_Shape;
  374.  
  375.    for (Local_Shape = Object -> Bounding_Shapes ;
  376.               Local_Shape != NULL ;
  377.               Local_Shape = Local_Shape -> Next_Object)
  378.  
  379.       Translate ((OBJECT *) Local_Shape, Vector);
  380.  
  381.    for (Local_Shape = Object -> Clipping_Shapes ;
  382.               Local_Shape != NULL ;
  383.               Local_Shape = Local_Shape -> Next_Object)
  384.  
  385.       Translate ((OBJECT *) Local_Shape, Vector);
  386.  
  387.    Translate ((OBJECT *) Object -> Shape, Vector);
  388.  
  389.    Translate_Texture (&Object->Object_Texture, Vector);
  390. }
  391.  
  392. void Rotate_Basic_Object (Object, Vector)
  393. OBJECT *Object;
  394. VECTOR *Vector;
  395. {
  396.    SHAPE *Local_Shape;
  397.    TRANSFORMATION Transformation;
  398.  
  399.    for (Local_Shape = Object -> Bounding_Shapes ;
  400.               Local_Shape != NULL ;
  401.               Local_Shape = Local_Shape -> Next_Object)
  402.  
  403.       Rotate ((OBJECT *) Local_Shape, Vector);
  404.  
  405.    for (Local_Shape = Object -> Clipping_Shapes ;
  406.               Local_Shape != NULL ;
  407.               Local_Shape = Local_Shape -> Next_Object)
  408.  
  409.       Rotate ((OBJECT *) Local_Shape, Vector);
  410.  
  411.    Rotate ((OBJECT *) Object -> Shape, Vector);
  412.    Get_Rotation_Transformation (&Transformation, Vector);
  413.  
  414.    Rotate_Texture (&Object->Object_Texture, Vector);
  415. }
  416.  
  417. void Scale_Basic_Object (Object, Vector)
  418. OBJECT *Object;
  419. VECTOR *Vector;
  420. {
  421.    SHAPE *Local_Shape;
  422.  
  423.    for (Local_Shape = Object -> Bounding_Shapes ;
  424.               Local_Shape != NULL ;
  425.               Local_Shape = Local_Shape -> Next_Object)
  426.  
  427.       Scale ((OBJECT *) Local_Shape, Vector);
  428.  
  429.    for (Local_Shape = Object -> Clipping_Shapes ;
  430.               Local_Shape != NULL ;
  431.               Local_Shape = Local_Shape -> Next_Object)
  432.  
  433.       Scale ((OBJECT *) Local_Shape, Vector);
  434.  
  435.    Scale ((OBJECT *) Object -> Shape, Vector);
  436.  
  437.    Scale_Texture (&Object->Object_Texture, Vector);
  438. }
  439.  
  440. void Translate_Composite_Object (Object, Vector)
  441. OBJECT *Object;
  442. VECTOR *Vector;
  443. {
  444.    OBJECT *Local_Object;
  445.    SHAPE *Local_Shape;
  446.  
  447.    for (Local_Object = ((COMPOSITE *) Object) -> Objects;
  448.               Local_Object != NULL ;
  449.               Local_Object = Local_Object -> Next_Object)
  450.  
  451.       Translate (Local_Object, Vector);   
  452.  
  453.    for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  454.               Local_Shape != NULL ;
  455.               Local_Shape = Local_Shape -> Next_Object)
  456.  
  457.       Translate ((OBJECT *) Local_Shape, Vector);
  458.  
  459.    for (Local_Shape = ((COMPOSITE *) Object) -> Clipping_Shapes ;
  460.               Local_Shape != NULL ;
  461.               Local_Shape = Local_Shape -> Next_Object)
  462.  
  463.       Translate ((OBJECT *) Local_Shape, Vector);
  464. }
  465.  
  466. void Rotate_Composite_Object (Object, Vector)
  467. OBJECT *Object;
  468. VECTOR *Vector;
  469. {
  470.    OBJECT *Local_Object;
  471.    SHAPE *Local_Shape;
  472.  
  473.    for (Local_Object = ((COMPOSITE *) Object) -> Objects;
  474.               Local_Object != NULL ;
  475.               Local_Object = Local_Object -> Next_Object)
  476.  
  477.       Rotate (Local_Object, Vector);   
  478.  
  479.    for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  480.               Local_Shape != NULL ;
  481.               Local_Shape = Local_Shape -> Next_Object)
  482.  
  483.       Rotate ((OBJECT *) Local_Shape, Vector);
  484.  
  485.    for (Local_Shape = ((COMPOSITE *) Object) -> Clipping_Shapes ;
  486.               Local_Shape != NULL ;
  487.               Local_Shape = Local_Shape -> Next_Object)
  488.  
  489.       Rotate ((OBJECT *) Local_Shape, Vector);
  490. }
  491.  
  492. void Scale_Composite_Object (Object, Vector)
  493. OBJECT *Object;
  494. VECTOR *Vector;
  495. {
  496.    OBJECT *Local_Object;
  497.    SHAPE *Local_Shape;
  498.  
  499.    for (Local_Object = ((COMPOSITE *) Object) -> Objects;
  500.               Local_Object != NULL ;
  501.               Local_Object = Local_Object -> Next_Object)
  502.  
  503.       Scale (Local_Object, Vector);   
  504.  
  505.    for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  506.               Local_Shape != NULL ;
  507.               Local_Shape = Local_Shape -> Next_Object)
  508.  
  509.       Scale ((OBJECT *) Local_Shape, Vector);
  510.  
  511.    for (Local_Shape = ((COMPOSITE *) Object) -> Clipping_Shapes ;
  512.               Local_Shape != NULL ;
  513.               Local_Shape = Local_Shape -> Next_Object)
  514.  
  515.       Scale ((OBJECT *) Local_Shape, Vector);
  516. }
  517.  
  518.  
  519. void Invert_Basic_Object (Object)
  520. OBJECT *Object;
  521. {
  522.    SHAPE *Local_Shape;
  523.  
  524.    for (Local_Shape = Object -> Bounding_Shapes ;
  525.               Local_Shape != NULL ;
  526.               Local_Shape = Local_Shape -> Next_Object)
  527.  
  528.       Invert ((OBJECT *) Local_Shape);
  529.  
  530.    for (Local_Shape = Object -> Clipping_Shapes ;
  531.               Local_Shape != NULL ;
  532.               Local_Shape = Local_Shape -> Next_Object)
  533.  
  534.       Invert ((OBJECT *) Local_Shape);
  535.    Invert ((OBJECT *) Object -> Shape);
  536. }
  537.  
  538. void Invert_Composite_Object (Object)
  539. OBJECT *Object;
  540. {
  541.    OBJECT *Local_Object;
  542.    SHAPE *Local_Shape;
  543.  
  544.    for (Local_Object = ((COMPOSITE *)Object) -> Objects;
  545.               Local_Object != NULL ;
  546.               Local_Object = Local_Object -> Next_Object)
  547.  
  548.       Invert (Local_Object);   
  549.  
  550.    for (Local_Shape = ((COMPOSITE *) Object) -> Bounding_Shapes ;
  551.               Local_Shape != NULL ;
  552.               Local_Shape = Local_Shape -> Next_Object)
  553.  
  554.       Invert ((OBJECT *) Local_Shape);
  555.  
  556.    for (Local_Shape = ((COMPOSITE *) Object) -> Clipping_Shapes ;
  557.               Local_Shape != NULL ;
  558.               Local_Shape = Local_Shape -> Next_Object)
  559.  
  560.       Invert ((OBJECT *) Local_Shape);
  561. }
  562.