home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / icoons / source / ttddd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-23  |  9.8 KB  |  335 lines

  1. /* :ts=8 */    /* Yes some of us still use vi ! */
  2. /************************************************************************/
  3. /*                                                                      */
  4. /* This file contains code which is called from tesselate.c to generate    */
  5. /* a ttddd description file of the current object.            */
  6. /*                                                                      */
  7. /************************************************************************/
  8.  
  9. #include <math.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <ctype.h>
  13. #include <errno.h>
  14. #include <stdlib.h>
  15. #include "general.h"
  16. #include "globals.h"
  17. #include "intui.h"
  18. #include "tesselate.h"
  19. #include "ttddd.h"
  20.  
  21.  
  22.     /* Increase these for very big objects              */
  23.     /* Decrease them if you don't have enough memory        */
  24.     /* Note the arrays need only be big enough to contain    */
  25.     /* data for a single patch!                    */
  26.  
  27. #define Max_Nbr_TTDDD_Points    1000
  28. #define Max_Nbr_TTDDD_Edges    1000
  29. #define Max_Nbr_TTDDD_Faces    500
  30.  
  31.  
  32. typedef struct {
  33.     short        P1;
  34.     short        P2;
  35. } Edge_T;
  36.  
  37. typedef struct {
  38.     short        E1;
  39.     short        E2;
  40.     short        E3;
  41. } Face_T;
  42.  
  43. static Boolean_T  Phong        = TRUE;    /* Phong smoothing?    */
  44. static double      TScale_Factor  = 1.0;        /* Scale factor        */
  45. static FILE      *TTDDD_Stream     = NULL;
  46.  
  47. static Vector_T  TTDDD_Points[Max_Nbr_TTDDD_Points]; /* Table of points    */
  48. static short     Nbr_TTDDD_Points    = 0;
  49.  
  50. static Edge_T     TTDDD_Edges[Max_Nbr_TTDDD_Edges];   /* Table of edges    */
  51. static short     Nbr_TTDDD_Edges    = 0;
  52.  
  53. static Face_T     TTDDD_Faces[Max_Nbr_TTDDD_Faces];   /* Table of faces    */
  54. static short     Nbr_TTDDD_Faces     = 0;
  55.  
  56.  
  57. static
  58. short Get_TTDDD_Point(Vector_T Point)
  59. /************************************************************************/
  60. /*                                    */
  61. /* Get id for the point 'Point'.                    */
  62. /* If no such point exist, then create it and return the newly created  */
  63. /* id.                                                                  */
  64. /*                                    */
  65. /************************************************************************/
  66. {
  67.     short    i;
  68.  
  69.     for (i = Nbr_TTDDD_Points-1; i >= 0; i--) {
  70.  
  71.     if (ABS(Point[0] - TTDDD_Points[i][0]) < FTINY &&
  72.         ABS(Point[1] - TTDDD_Points[i][1]) < FTINY &&
  73.         ABS(Point[2] - TTDDD_Points[i][2]) < FTINY) return(i);
  74.  
  75.     } /* for */
  76.  
  77.     if (Nbr_TTDDD_Points >= Max_Nbr_TTDDD_Points) {
  78.     Display_Error_Message("Too many points");
  79.       CloseStuff();
  80.     exit(9);
  81.     }
  82.  
  83.     TTDDD_Points[Nbr_TTDDD_Points][0] = Point[0];
  84.     TTDDD_Points[Nbr_TTDDD_Points][1] = Point[1];
  85.     TTDDD_Points[Nbr_TTDDD_Points][2] = Point[2];
  86.  
  87.     return(Nbr_TTDDD_Points++);
  88.  
  89. } /* Get_TTDDD_Point */
  90.  
  91. static
  92. short Get_TTDDD_Edge(short P1, short P2)
  93. /************************************************************************/
  94. /*                                    */
  95. /* Get id for the edge that connects the points P1 and P2.              */
  96. /* If no such edge exists, then create it and return the newly created  */
  97. /* id.                                                                  */
  98. /*                                    */
  99. /************************************************************************/
  100. {
  101.     short    i;
  102.  
  103.     for (i = Nbr_TTDDD_Edges-1; i >= 0; i--) {
  104.  
  105.     if ((TTDDD_Edges[i].P1 == P1 && TTDDD_Edges[i].P2 == P2) ||
  106.         (TTDDD_Edges[i].P1 == P2 && TTDDD_Edges[i].P2 == P1)) return(i);
  107.  
  108.     } /* for */
  109.  
  110.     if (Nbr_TTDDD_Edges >= Max_Nbr_TTDDD_Edges) {
  111.     Display_Error_Message("Too many edges");
  112.       CloseStuff();
  113.     exit(9);
  114.     }
  115.  
  116.     TTDDD_Edges[Nbr_TTDDD_Edges].P1 = P1;
  117.     TTDDD_Edges[Nbr_TTDDD_Edges].P2 = P2;
  118.  
  119.     return(Nbr_TTDDD_Edges++);
  120.  
  121. } /* Get_TTDDD_Edge */
  122.  
  123. static
  124. void Add_TTDDD_Face(short P1, short P2, short P3)
  125. /************************************************************************/
  126. /*                                    */
  127. /* Add a new face connecting P1, P2 and P3 to the face table.           */
  128. /* The corresponding edges will be created if they don't exist.         */
  129. /*                                    */
  130. /************************************************************************/
  131. {
  132.     short    i;
  133.     short E1, E2, E3;
  134.  
  135.     E1 = Get_TTDDD_Edge(P1, P2);
  136.     E2 = Get_TTDDD_Edge(P2, P3);
  137.     E3 = Get_TTDDD_Edge(P3, P1);
  138.  
  139.     for (i = Nbr_TTDDD_Faces-1; i >= 0; i--) {
  140.  
  141.     if (TTDDD_Faces[i].E1 == E1 && TTDDD_Faces[i].E2 == E2 &&
  142.                           TTDDD_Faces[i].E3 == E3) return;
  143.  
  144.     } /* for */
  145.  
  146.  
  147.     if (Nbr_TTDDD_Faces >= Max_Nbr_TTDDD_Faces) {
  148.     Display_Error_Message("Too many faces");
  149.       CloseStuff();
  150.     exit(9);
  151.     }
  152.  
  153.     TTDDD_Faces[Nbr_TTDDD_Faces].E1      = Get_TTDDD_Edge(P1, P2);
  154.     TTDDD_Faces[Nbr_TTDDD_Faces].E2      = Get_TTDDD_Edge(P2, P3);
  155.     TTDDD_Faces[Nbr_TTDDD_Faces].E3      = Get_TTDDD_Edge(P3, P1);
  156.  
  157.     Nbr_TTDDD_Faces++;
  158.  
  159. } /* Add_TTDDD_Face */
  160.  
  161. static 
  162. void Write_TTDDD_Object()
  163. /************************************************************************/
  164. /*                                    */
  165. /* Write the object saved in the global variables to TTDDD_Stream in     */
  166. /* TTDDD format.                            */
  167. /* If 'Phong' is TRUE, the object should be phong smoothed.        */
  168. /*                                    */
  169. /************************************************************************/
  170. {
  171.     short        i;
  172.  
  173.     if (Nbr_TTDDD_Points == 0) return;
  174.  
  175.     fprintf(TTDDD_Stream, "OBJ Begin   %% Begin Object chunk\n");
  176.     fprintf(TTDDD_Stream, "\n");
  177.  
  178.     fprintf(TTDDD_Stream, "DESC Begin  %% Begin DESC sub-chunk\n");
  179.     fprintf(TTDDD_Stream, "\n");
  180.  
  181.     fprintf(TTDDD_Stream, "\tNAME \"%s\"\n", "ICOONS");
  182.     fprintf(TTDDD_Stream, "\n");
  183.     fprintf(TTDDD_Stream, "\tSHAP Shape 2   %% Axis object\n");
  184.     fprintf(TTDDD_Stream, "\tSHAP Lamp  0   %% Not a lamp\n");
  185.     fprintf(TTDDD_Stream, "\n");
  186.     fprintf(TTDDD_Stream, "\tPOSI X=0.0 Y=0.0 Z=0.0 %% Position.\n");
  187.     fprintf(TTDDD_Stream, "\n");
  188.  
  189.     fprintf(TTDDD_Stream, "\tAXIS XAxis X=1 %% Defaults to 1 0 0\n");
  190.     fprintf(TTDDD_Stream, "\tAXIS YAxis Y=1 %% Defaults to 0 1 0\n");
  191.     fprintf(TTDDD_Stream, "\tAXIS ZAxis Z=1 %% Defaults to 0 0 1\n");
  192.     fprintf(TTDDD_Stream, "\n");
  193.  
  194.     fprintf(TTDDD_Stream, "\tSIZE X=32 Y=32 Z=32 %% Defaults to 32.0\n");
  195.     fprintf(TTDDD_Stream, "\n");
  196.  
  197.         /* POINTS */
  198.  
  199.     fprintf(TTDDD_Stream, "\tPNTS PCount %d %% Number of points\n", 
  200.                                 Nbr_TTDDD_Points);
  201.     fprintf(TTDDD_Stream, "\n");
  202.  
  203.     for (i = 0; i < Nbr_TTDDD_Points; i++) {
  204.         fprintf(TTDDD_Stream, "\tPNTS Point[%d] %lf %lf %lf\n", 
  205.                 i, 
  206.                 TScale_Factor * TTDDD_Points[i][0], 
  207.                 TScale_Factor * TTDDD_Points[i][1], 
  208.                 TScale_Factor * TTDDD_Points[i][2]);
  209.     } /* for */
  210.     fprintf(TTDDD_Stream, "\n");
  211.  
  212.  
  213.         /* EDGES */
  214.     fprintf(TTDDD_Stream, "\tEDGE ECount %d %% Number of edges\n", 
  215.                                 Nbr_TTDDD_Edges);
  216.     fprintf(TTDDD_Stream, "\n");
  217.     for (i = 0; i < Nbr_TTDDD_Edges; i++) {
  218.         fprintf(TTDDD_Stream, "\tEDGE Edge[%d] %d %d\n", 
  219.                 i, TTDDD_Edges[i].P1, TTDDD_Edges[i].P2);
  220.     } /* for */
  221.     fprintf(TTDDD_Stream, "\n");
  222.  
  223.  
  224.         /* FACES */
  225.     fprintf(TTDDD_Stream, "\tFACE TCount %d %% Number of faces\n", 
  226.                                 Nbr_TTDDD_Faces);
  227.     fprintf(TTDDD_Stream, "\n");
  228.     for (i = 0; i < Nbr_TTDDD_Faces; i++) {
  229.         fprintf(TTDDD_Stream, "\tFACE Connect[%d] %d %d %d\n", 
  230.                 i, 
  231.                 TTDDD_Faces[i].E1, 
  232.                 TTDDD_Faces[i].E2, 
  233.                 TTDDD_Faces[i].E3);
  234.     } /* for */
  235.     fprintf(TTDDD_Stream, "\n");
  236.  
  237.  
  238.     fprintf(TTDDD_Stream, "\tMTTR Type  4   %%\n");
  239.     fprintf(TTDDD_Stream, "\tMTTR Index 1.0 %%\n");
  240.     fprintf(TTDDD_Stream, "\n");
  241.  
  242.     fprintf(TTDDD_Stream, "\tSPEC Specularity 0\n");
  243.     fprintf(TTDDD_Stream, "\tSPEC Hardness    0\n");
  244.     fprintf(TTDDD_Stream, "\n");
  245.  
  246.     fprintf(TTDDD_Stream, "\tPRP0[0] 0   %% Blending (dither) factor.\n");
  247.     fprintf(TTDDD_Stream, "\tPRP0[1] 0   %% Roughness factor.\n");
  248.     fprintf(TTDDD_Stream, "\tPRP0[2] 0   %% Shading on/off.\n");
  249.     fprintf(TTDDD_Stream, "\tPRP0[3] %d  %% Phong shading flag.\n", !Phong);
  250.     fprintf(TTDDD_Stream, "\tPRP0[4] 0   %% Glossy flag. \n");
  251.     fprintf(TTDDD_Stream, "\tPRP0[5] 0   %% Quickdraw flag.\n");
  252.     fprintf(TTDDD_Stream, "\n");
  253.  
  254.     fprintf(TTDDD_Stream, "End DESC  %% End of DESC sub-chunk\n");
  255.     fprintf(TTDDD_Stream, "\n");
  256.  
  257.     fprintf(TTDDD_Stream, "TOBJ %% End of object hierachy.\n");
  258.     fprintf(TTDDD_Stream, "\n");
  259.  
  260.     fprintf(TTDDD_Stream, "End OBJ  %% End of object chunk\n");
  261.     fprintf(TTDDD_Stream, "\n");
  262.  
  263.     Nbr_TTDDD_Points = 0;
  264.     Nbr_TTDDD_Edges  = 0;
  265.     Nbr_TTDDD_Faces  = 0;
  266.  
  267. } /* Write_TTDDD_Object */
  268.  
  269. static
  270. void Generate_TTDDD_Face(Vector_T Point0, Vector_T Point1, 
  271.                 Vector_T Point2, Vector_T Point3)
  272. /************************************************************************/
  273. /*                                    */
  274. /* Add the square given by the four points to the face/edge/point lists.*/
  275. /*                                    */
  276. /************************************************************************/
  277. {
  278.     Boolean_T     Face1_Ok, Face2_Ok;
  279.     short    Point0_Id, Point1_Id, Point2_Id, Point3_Id;
  280.  
  281.     Face1_Ok = Face_Is_Ok(Point0, Point1, Point2);
  282.     Face2_Ok = Face_Is_Ok(Point1, Point2, Point3);
  283.  
  284.     if (Face1_Ok || Face2_Ok) {
  285.  
  286.            if (Face1_Ok) Point0_Id = Get_TTDDD_Point(Point0);
  287.  
  288.         Point1_Id = Get_TTDDD_Point(Point1);
  289.         Point2_Id = Get_TTDDD_Point(Point2);
  290.  
  291.         if (Face2_Ok) Point3_Id = Get_TTDDD_Point(Point3);
  292.  
  293.     if (Face1_Ok) Add_TTDDD_Face(Point0_Id, Point1_Id, Point2_Id); 
  294.  
  295.     if (Face2_Ok) Add_TTDDD_Face(Point2_Id, Point1_Id, Point3_Id);
  296.  
  297.     } /* if */
  298.  
  299. } /* Generate_TTDDD_Face */
  300.  
  301. Boolean_T Generate_TTDDD_File(char *Path)
  302. /************************************************************************/
  303. /*                                    */
  304. /* Tesselate the current object, and generate a TTDDD description of it    */
  305. /* in the file with name 'Path'.                    */
  306. /*                                    */
  307. /************************************************************************/
  308. {
  309.     Tesselate_Info_T    TI;
  310.     Boolean_T        Error;
  311.  
  312.  
  313.     TTDDD_Stream = fopen(Path, "w");
  314.     if (TTDDD_Stream == NULL) {
  315.         sprintf(Error_Msg, "Couldn't create TTDDD file '%s'", Path);
  316.     Display_Message(Error_Msg);
  317.     return(TRUE);
  318.     }
  319.  
  320.     TI.Patch_Begin         = NULL;
  321.     TI.Patch_Generate_Face = Generate_TTDDD_Face;
  322.     TI.Patch_End          = Write_TTDDD_Object;
  323.  
  324.     Set_Pointer(TRUE);
  325.  
  326.     Error = Tesselate_Object(&TI);
  327.  
  328.     fclose(TTDDD_Stream);
  329.  
  330.     Set_Pointer(FALSE);
  331.  
  332.     return(Error);
  333.  
  334. } /* Generate_TTDDD_File */
  335.