home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / formats / sgo / spec / sgo.txt < prev   
Text File  |  1994-06-18  |  11KB  |  329 lines

  1. Copyright  1993, Silicon Graphics, Inc. All rights reserved.
  2. Silicon Graphics and the Silicon Graphics logo are registered
  3. trademarks, and SGO is a trademark of Silicon Graphics.
  4. Specifications are subject to change without notice.
  5.  
  6.  
  7.  
  8.  
  9.     SGO File Format
  10.  
  11.     SGO = (Silicon Graphics Object)
  12.  
  13.     SGO format is a format slightly more complicated that Spin format,
  14.     but still quite simple.  It allows lists of quadrilaterals, lists
  15.     of triangles and triangle meshes.
  16.  
  17.     The first word in the file is the SGO magic number:
  18.  
  19.     word 1: 0x5424  (4 bytes)
  20.  
  21.     Following next is a set of objects:
  22.  
  23.     <object type 1 token>
  24.     <data for object 1>
  25.     <object type 2 token>
  26.     <data for object 2>
  27.     .
  28.     .
  29.     .
  30.     <object type n token>
  31.     <data for object n>
  32.     <end data token>
  33.  
  34.     Each of the tokens is 4 bytes long.  The tokens are:
  35.  
  36.     OBJ_QUADLIST    (= 1)
  37.     OBJ_TRILIST     (= 2)
  38.     OBJ_TRIMESH     (= 3)
  39.     OBJ_END         (= 4)   the end of data token.
  40.  
  41.     The next word following any of the three object types is the number
  42.     of longs in the data for that object.
  43.  
  44.     For OBJ_QUADLIST and OBJ_TRILIST (quadrilateral list and triangle
  45.     list), there are 9 floats of data for each vertex.  The first three
  46.     are the components of the normal vector at the vertex; the next
  47.     three are the color components (R, G, B), all between 0.0 and 1.0,
  48.     and finally there are the components of the vertex itself.
  49.  
  50.     For the OBJ_QUADLIST, the points are simply taken 4 at a time, so
  51.     there are 9*4 = 36 floats of data for each quadrilateral.  For the
  52.     OBJ_TRILIST, the points are used 3 at a time, making 9*3 = 27
  53.     floats per triangle.
  54.  
  55.     The triangle mesh (OBJ_TRIMESH) is the most complicated of the
  56.     three.  The data consist of a set of vertices followed by a set of
  57.     mesh control commands.  The data for each vertex is the same as
  58.     above -- 9 floats.  The mesh controls consist of:
  59.  
  60.     OP_BGNTMESH             (= 1)
  61.     OP_SWAPTMESH            (= 2)
  62.     OP_ENDBGNTMESH          (= 3)
  63.     OP_ENDTMESH             (= 4)
  64.  
  65.     Following the number of longs required for the entire triangle mesh
  66.     data is the number of floats required for the vertex data (at 9
  67.     floats per vertex).  Next comes the vertex data, and the rest of
  68.     the data are longs containing triangle mesh controls.
  69.  
  70.     For example, a file containing a single triangle mesh object with
  71.     four vertices, and nine mesh controls would look like this:
  72.  
  73.     word 1: 0x5424
  74.     word 2: OBJ_TRIMESH
  75.     word 3: 42 = 4*9 + 1 + 5
  76.     word 4: 36 (length of data for 4 vertices)
  77.     word 5-40: vertex data
  78.     word 41-49: mesh controls
  79.     word 50: OBJ_END
  80.  
  81.     When the triangle mesh is drawn, the controls are interpreted one
  82.     at a time.  The first control is assumed to be an OP_BGNTMESH.
  83.     After each control is a long indicating how many vertex indices
  84.     will follow.  The vertex indices are in byte offsets. For example,
  85.     vertex n is offset by n*9*4.
  86.  
  87.     To understand triangle meshes, consider the following example.
  88.     Suppose there are 6 points arranged as follows:
  89.  
  90.     0-----2-----4 
  91.      \   / \   / \
  92.       \ /   \ /   \
  93.        1-----3-----5
  94.  
  95.     To draw the triangles 012, 123, 234, and 345, the control sequence
  96.     (the mesh controls) would be:
  97.  
  98.     OP_BGTMESH 6 0*9*4 1*9*4 2*9*4 3*9*4 4*9*4 5*9*4 OP_ENDTMESH
  99.  
  100.     Two vertices are recorded in the hardware.  As each new vertex is
  101.     sent, a triangle is output with the two saved vertices and the new
  102.     one.  Then the oldest vertex is discarded and is replaced by the
  103.     second oldest, and the new vertex replaces the second oldest.  For
  104.     the sequence above, the state looks like this:
  105.  
  106.                 Saveold         Savenew         Output Triangle
  107.                 -------         -------         ------
  108.     OP_BGNTMESH:            invalid         invalid         nothing
  109.     point 0:                invalid         point 0         nothing
  110.     point 1:                point 0         point 1         nothing
  111.     point 2:                point 1         point 2         0-1-2
  112.     point 3:                point 2         point 3         1-2-3
  113.     point 4:                point 3         point 4         2-3-4
  114.     point 5:                point 4         point 5         3-4-5
  115.     OP_ENDTMESH:            invalid         invalid         nothing
  116.  
  117.     This is great if all you want to do is go down a ribbon outputting
  118.     triangles.  If you want to turn a corner, or to have multiple
  119.     sequences, OP_SWAPTMESH reverses the contents of the Saveold and
  120.     Savenew registers, and OP_ENDBGNTMESH is ends the current sequence
  121.     and begins a new one.
  122.  
  123.     One final example should illustrate this:
  124.  
  125.  
  126.     0-----2-----4 
  127.      \   / \   / \
  128.       \ /   \ /   \
  129.        1-----3-----5
  130.  
  131.        14-----13
  132.        / \   / \
  133.       /   \ /   \
  134.    6-----8----10-----12
  135.     \   / \   / \   /
  136.      \ /   \ /   \ /
  137.       7-----9-----11
  138.  
  139.     To draw the pattern above, use the following mesh control sequence:
  140.  
  141.     OP_BGNTMESH, 6, 0*9*4, 1*9*4, 2*9*4, 3*9*4, 4*9*4, 5*9*4,
  142.     OP_ENDBGNTMESH, 6, 6*9*4, 7*9*4, 8*9*4, 9*9*4, 10*9*4, 11*9*4,
  143.     OP_SWAPTMESH, 1, 12*9*4, OP_SWAPTMESH, 1, 13*9*4, OP_SWAPTMESH, 2,
  144.     14*9*4, 8*9*4, OP_ENDTMESH
  145.  
  146.                 Saveold         Savenew         Output Triangle
  147.                 -------         -------         ------
  148.     OP_BGNTMESH:        invalid         invalid         nothing
  149.     point 0:                invalid         point 0         nothing
  150.     point 1:                point 0         point 1         nothing
  151.     point 2:                point 1         point 2         0-1-2
  152.     point 3:                point 2         point 3         1-2-3
  153.     point 4:                point 3         point 4         2-3-4
  154.     point 5:                point 4         point 5         3-4-5
  155.     OP_ENDBGNTMESH:         invalid         invalid         nothing
  156.     point 6:                invalid         point 6         nothing
  157.     point 7:                point 6         point 7         nothing
  158.     point 8:                point 7         point 8         6-7-8
  159.     point 9:                point 8         point 9         7-8-9
  160.     point A:                point 9         point A         8-9-A
  161.     point B:                point A         point B         9-A-B
  162.     OP_SWAPTMESH:           point B         point A         nothing
  163.     point C:                point A         point C         B-A-C
  164.     OP_SWAPTMESH:           point C         point A         nothing
  165.     point D:                point A         point D         C-A-D
  166.     OP_SWAPTMESH:           point D         point A         nothing
  167.     point E:                point A         point E         D-A-E
  168.     point 8:                point E         point 8         A-E-8
  169.     OP_ENDTMESH:            invalid         invalid         nothing
  170.      
  171. */
  172.  
  173. #include <stdio.h>
  174.  
  175. #define OBJ_QUADLIST        1
  176. #define OBJ_TRILIST        2
  177. #define OBJ_TRIMESH         3
  178. #define OBJ_END             4
  179.  
  180. #define OP_BGNTMESH         1
  181. #define OP_SWAPTMESH        2
  182. #define OP_ENDBGNTMESH      3
  183. #define OP_ENDTMESH         4
  184.  
  185. FILE        *fp;
  186.  
  187. long        meshctl[27] = {
  188.     OP_BGNTMESH, 6, 0, 1*9*4, 2*9*4, 3*9*4, 4*9*4, 5*9*4, OP_ENDBGNTMESH,
  189.     6, 6*9*4, 7*9*4, 8*9*4, 9*9*4, 10*9*4, 11*9*4, OP_SWAPTMESH,
  190.     1, 12*9*4, OP_SWAPTMESH,
  191.     1, 13*9*4, OP_SWAPTMESH, 2, 14*9*4, 8*9*4, OP_ENDTMESH };
  192.  
  193. float       meshdata[15][3] = {
  194.     {3, 11, 0}, {5, 8, 0}, {7, 11, -1}, {9, 8, 0}, {11, 11, 0}, {13, 8, -1},
  195.     {2, 3, 0}, {4, 0, 0}, {6, 3, -1}, {8, 0, 0}, {10, 3, 1}, {12, 0, -1},
  196.     {14, 3, 3}, {12, 6, 2}, {8, 6, -2}
  197. };
  198.  
  199. float meshnorm[15][3] = {
  200.     {0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}, {1, 0, 0},
  201.     {0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}, {1, 0, 0},
  202.     {0, 0, 1}, {0, 1, 0}, {1, 0, 0}
  203. };
  204.  
  205. float       cube[8][3] = {
  206.     {-1.0, -1.0, -1.0},
  207.     {-1.0, -1.0, 1.0},
  208.     {-1.0, 1.0, 1.0},
  209.     {-1.0, 1.0, -1.0},
  210.     {1.0, -1.0, -1.0},
  211.     {1.0, -1.0, 1.0},
  212.     {1.0, 1.0, 1.0},
  213.     {1.0, 1.0, -1.0},
  214. };
  215.  
  216. float       ncube[6][3] = {
  217.     {1.0, 0.0, 0.0},
  218.     {-1.0, 0.0, 0.0},
  219.     {0.0, 1.0, 0.0},
  220.     {0.0, -1.0, 0.0},
  221.     {0.0, 0.0, 1.0},
  222.     {0.0, 0.0, -1.0},
  223. };
  224.  
  225. float nullcolor[3] = { 0.0, 0.0, 0.0 };
  226.  
  227. writesgomesh()
  228. {
  229.     long    typeandcount[3];
  230.     long    i;
  231.     
  232.     typeandcount[0] = OBJ_TRIMESH;
  233.     typeandcount[1] = 15*9 + 1 + 27;
  234.     typeandcount[2] = 15*9;
  235.     fwrite(&typeandcount[0], 4, 3, fp);
  236.     for (i = 0; i < 15; i++) {
  237.     fwrite(&meshnorm[i][0], 4, 3, fp);
  238.     fwrite(&nullcolor[0], 4, 3, fp);
  239.     fwrite(&meshdata[i][0], 4, 3, fp);
  240.     }
  241.     for (i = 0; i < 27; i++)
  242.     fwrite(&meshctl[i], 4, 1, fp);
  243. }
  244.  
  245. writesgocube()
  246. {
  247.     long    typeandcount[2];
  248.     
  249.     typeandcount[0] = OBJ_QUADLIST;
  250.     typeandcount[1] = 6*36;
  251.     fwrite(&typeandcount[0], 4, 2, fp);
  252.     
  253.     nw(0); vw(4); nw(0); vw(5); nw(0); vw(6); nw(0); vw(7);
  254.     nw(1); vw(0); nw(1); vw(1); nw(1); vw(2); nw(1); vw(3);
  255.     nw(2); vw(2); nw(2); vw(3); nw(2); vw(7); nw(2); vw(6);
  256.     nw(3); vw(0); nw(3); vw(1); nw(3); vw(5); nw(3); vw(4);
  257.     nw(4); vw(1); nw(4); vw(2); nw(4); vw(6); nw(4); vw(5);
  258.     nw(5); vw(0); nw(5); vw(3); nw(5); vw(7); nw(5); vw(4);
  259. }
  260.  
  261. vw(n)
  262. long n;
  263. {
  264.     fwrite(&cube[n][0], 4, 3, fp);
  265. }
  266.  
  267. nw(n)
  268. long n;
  269. {
  270.     fwrite(&ncube[n][0], 4, 3, fp);
  271.    fwrite(&nullcolor[0], 4, 3, fp);
  272. }
  273.  
  274. octvert(n)
  275. long        n;
  276. {
  277.     fwrite(&ncube[n][0], 4, 3, fp);
  278.     fwrite(&nullcolor[0], 4, 3, fp);
  279.     fwrite(&ncube[n][0], 4, 3, fp);
  280. }
  281.  
  282. sgotri(a, b, c)
  283. long        a, b, c;
  284. {
  285.     octvert(a); octvert(b); octvert(c);
  286. }
  287.  
  288. writesgooct()
  289. {
  290.     long    typeandcount[2];
  291.     
  292.     typeandcount[0] = OBJ_TRILIST;
  293.     typeandcount[1] = 8*27;
  294.     fwrite(&typeandcount[0], 4, 2, fp);
  295.     sgotri(0, 2, 5);
  296.     sgotri(0, 5, 3);
  297.     sgotri(0, 3, 4);
  298.     sgotri(0, 4, 2);
  299.     sgotri(1, 2, 5);
  300.     sgotri(1, 5, 3);
  301.     sgotri(1, 3, 4);
  302.     sgotri(1, 4, 2);
  303. }
  304.  
  305. main()
  306. {
  307.     long end = OBJ_END;
  308.     
  309.     /* comment out all but one of the next three lines */
  310.     writesgoheader();
  311.     /*writesgocube();*/
  312.     /*writesgooct();*/
  313.     writesgomesh();
  314.     fwrite(&end, 4, 1, fp);
  315.     fclose(fp);
  316. }
  317.  
  318. writesgoheader(polycount)
  319. long        polycount;
  320. {
  321.     long    magic;
  322.     
  323.     magic = 0x5424;
  324.     
  325.     fp = fopen("sgoout", "w");
  326.     fwrite(&magic, 4, 1, fp);
  327. }
  328.  
  329.