home *** CD-ROM | disk | FTP | other *** search
- Copyright 1993, Silicon Graphics, Inc. All rights reserved.
- Silicon Graphics and the Silicon Graphics logo are registered
- trademarks, and SGO is a trademark of Silicon Graphics.
- Specifications are subject to change without notice.
-
-
-
-
- SGO File Format
-
- SGO = (Silicon Graphics Object)
-
- SGO format is a format slightly more complicated that Spin format,
- but still quite simple. It allows lists of quadrilaterals, lists
- of triangles and triangle meshes.
-
- The first word in the file is the SGO magic number:
-
- word 1: 0x5424 (4 bytes)
-
- Following next is a set of objects:
-
- <object type 1 token>
- <data for object 1>
- <object type 2 token>
- <data for object 2>
- .
- .
- .
- <object type n token>
- <data for object n>
- <end data token>
-
- Each of the tokens is 4 bytes long. The tokens are:
-
- OBJ_QUADLIST (= 1)
- OBJ_TRILIST (= 2)
- OBJ_TRIMESH (= 3)
- OBJ_END (= 4) the end of data token.
-
- The next word following any of the three object types is the number
- of longs in the data for that object.
-
- For OBJ_QUADLIST and OBJ_TRILIST (quadrilateral list and triangle
- list), there are 9 floats of data for each vertex. The first three
- are the components of the normal vector at the vertex; the next
- three are the color components (R, G, B), all between 0.0 and 1.0,
- and finally there are the components of the vertex itself.
-
- For the OBJ_QUADLIST, the points are simply taken 4 at a time, so
- there are 9*4 = 36 floats of data for each quadrilateral. For the
- OBJ_TRILIST, the points are used 3 at a time, making 9*3 = 27
- floats per triangle.
-
- The triangle mesh (OBJ_TRIMESH) is the most complicated of the
- three. The data consist of a set of vertices followed by a set of
- mesh control commands. The data for each vertex is the same as
- above -- 9 floats. The mesh controls consist of:
-
- OP_BGNTMESH (= 1)
- OP_SWAPTMESH (= 2)
- OP_ENDBGNTMESH (= 3)
- OP_ENDTMESH (= 4)
-
- Following the number of longs required for the entire triangle mesh
- data is the number of floats required for the vertex data (at 9
- floats per vertex). Next comes the vertex data, and the rest of
- the data are longs containing triangle mesh controls.
-
- For example, a file containing a single triangle mesh object with
- four vertices, and nine mesh controls would look like this:
-
- word 1: 0x5424
- word 2: OBJ_TRIMESH
- word 3: 42 = 4*9 + 1 + 5
- word 4: 36 (length of data for 4 vertices)
- word 5-40: vertex data
- word 41-49: mesh controls
- word 50: OBJ_END
-
- When the triangle mesh is drawn, the controls are interpreted one
- at a time. The first control is assumed to be an OP_BGNTMESH.
- After each control is a long indicating how many vertex indices
- will follow. The vertex indices are in byte offsets. For example,
- vertex n is offset by n*9*4.
-
- To understand triangle meshes, consider the following example.
- Suppose there are 6 points arranged as follows:
-
- 0-----2-----4
- \ / \ / \
- \ / \ / \
- 1-----3-----5
-
- To draw the triangles 012, 123, 234, and 345, the control sequence
- (the mesh controls) would be:
-
- OP_BGTMESH 6 0*9*4 1*9*4 2*9*4 3*9*4 4*9*4 5*9*4 OP_ENDTMESH
-
- Two vertices are recorded in the hardware. As each new vertex is
- sent, a triangle is output with the two saved vertices and the new
- one. Then the oldest vertex is discarded and is replaced by the
- second oldest, and the new vertex replaces the second oldest. For
- the sequence above, the state looks like this:
-
- Saveold Savenew Output Triangle
- ------- ------- ------
- OP_BGNTMESH: invalid invalid nothing
- point 0: invalid point 0 nothing
- point 1: point 0 point 1 nothing
- point 2: point 1 point 2 0-1-2
- point 3: point 2 point 3 1-2-3
- point 4: point 3 point 4 2-3-4
- point 5: point 4 point 5 3-4-5
- OP_ENDTMESH: invalid invalid nothing
-
- This is great if all you want to do is go down a ribbon outputting
- triangles. If you want to turn a corner, or to have multiple
- sequences, OP_SWAPTMESH reverses the contents of the Saveold and
- Savenew registers, and OP_ENDBGNTMESH is ends the current sequence
- and begins a new one.
-
- One final example should illustrate this:
-
-
- 0-----2-----4
- \ / \ / \
- \ / \ / \
- 1-----3-----5
-
- 14-----13
- / \ / \
- / \ / \
- 6-----8----10-----12
- \ / \ / \ /
- \ / \ / \ /
- 7-----9-----11
-
- To draw the pattern above, use the following mesh control sequence:
-
- OP_BGNTMESH, 6, 0*9*4, 1*9*4, 2*9*4, 3*9*4, 4*9*4, 5*9*4,
- OP_ENDBGNTMESH, 6, 6*9*4, 7*9*4, 8*9*4, 9*9*4, 10*9*4, 11*9*4,
- OP_SWAPTMESH, 1, 12*9*4, OP_SWAPTMESH, 1, 13*9*4, OP_SWAPTMESH, 2,
- 14*9*4, 8*9*4, OP_ENDTMESH
-
- Saveold Savenew Output Triangle
- ------- ------- ------
- OP_BGNTMESH: invalid invalid nothing
- point 0: invalid point 0 nothing
- point 1: point 0 point 1 nothing
- point 2: point 1 point 2 0-1-2
- point 3: point 2 point 3 1-2-3
- point 4: point 3 point 4 2-3-4
- point 5: point 4 point 5 3-4-5
- OP_ENDBGNTMESH: invalid invalid nothing
- point 6: invalid point 6 nothing
- point 7: point 6 point 7 nothing
- point 8: point 7 point 8 6-7-8
- point 9: point 8 point 9 7-8-9
- point A: point 9 point A 8-9-A
- point B: point A point B 9-A-B
- OP_SWAPTMESH: point B point A nothing
- point C: point A point C B-A-C
- OP_SWAPTMESH: point C point A nothing
- point D: point A point D C-A-D
- OP_SWAPTMESH: point D point A nothing
- point E: point A point E D-A-E
- point 8: point E point 8 A-E-8
- OP_ENDTMESH: invalid invalid nothing
-
- */
-
- #include <stdio.h>
-
- #define OBJ_QUADLIST 1
- #define OBJ_TRILIST 2
- #define OBJ_TRIMESH 3
- #define OBJ_END 4
-
- #define OP_BGNTMESH 1
- #define OP_SWAPTMESH 2
- #define OP_ENDBGNTMESH 3
- #define OP_ENDTMESH 4
-
- FILE *fp;
-
- long meshctl[27] = {
- OP_BGNTMESH, 6, 0, 1*9*4, 2*9*4, 3*9*4, 4*9*4, 5*9*4, OP_ENDBGNTMESH,
- 6, 6*9*4, 7*9*4, 8*9*4, 9*9*4, 10*9*4, 11*9*4, OP_SWAPTMESH,
- 1, 12*9*4, OP_SWAPTMESH,
- 1, 13*9*4, OP_SWAPTMESH, 2, 14*9*4, 8*9*4, OP_ENDTMESH };
-
- float meshdata[15][3] = {
- {3, 11, 0}, {5, 8, 0}, {7, 11, -1}, {9, 8, 0}, {11, 11, 0}, {13, 8, -1},
- {2, 3, 0}, {4, 0, 0}, {6, 3, -1}, {8, 0, 0}, {10, 3, 1}, {12, 0, -1},
- {14, 3, 3}, {12, 6, 2}, {8, 6, -2}
- };
-
- float meshnorm[15][3] = {
- {0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}, {1, 0, 0},
- {0, 0, 1}, {0, 1, 0}, {1, 0, 0}, {0, 0, 1}, {0, 1, 0}, {1, 0, 0},
- {0, 0, 1}, {0, 1, 0}, {1, 0, 0}
- };
-
- float cube[8][3] = {
- {-1.0, -1.0, -1.0},
- {-1.0, -1.0, 1.0},
- {-1.0, 1.0, 1.0},
- {-1.0, 1.0, -1.0},
- {1.0, -1.0, -1.0},
- {1.0, -1.0, 1.0},
- {1.0, 1.0, 1.0},
- {1.0, 1.0, -1.0},
- };
-
- float ncube[6][3] = {
- {1.0, 0.0, 0.0},
- {-1.0, 0.0, 0.0},
- {0.0, 1.0, 0.0},
- {0.0, -1.0, 0.0},
- {0.0, 0.0, 1.0},
- {0.0, 0.0, -1.0},
- };
-
- float nullcolor[3] = { 0.0, 0.0, 0.0 };
-
- writesgomesh()
- {
- long typeandcount[3];
- long i;
-
- typeandcount[0] = OBJ_TRIMESH;
- typeandcount[1] = 15*9 + 1 + 27;
- typeandcount[2] = 15*9;
- fwrite(&typeandcount[0], 4, 3, fp);
- for (i = 0; i < 15; i++) {
- fwrite(&meshnorm[i][0], 4, 3, fp);
- fwrite(&nullcolor[0], 4, 3, fp);
- fwrite(&meshdata[i][0], 4, 3, fp);
- }
- for (i = 0; i < 27; i++)
- fwrite(&meshctl[i], 4, 1, fp);
- }
-
- writesgocube()
- {
- long typeandcount[2];
-
- typeandcount[0] = OBJ_QUADLIST;
- typeandcount[1] = 6*36;
- fwrite(&typeandcount[0], 4, 2, fp);
-
- nw(0); vw(4); nw(0); vw(5); nw(0); vw(6); nw(0); vw(7);
- nw(1); vw(0); nw(1); vw(1); nw(1); vw(2); nw(1); vw(3);
- nw(2); vw(2); nw(2); vw(3); nw(2); vw(7); nw(2); vw(6);
- nw(3); vw(0); nw(3); vw(1); nw(3); vw(5); nw(3); vw(4);
- nw(4); vw(1); nw(4); vw(2); nw(4); vw(6); nw(4); vw(5);
- nw(5); vw(0); nw(5); vw(3); nw(5); vw(7); nw(5); vw(4);
- }
-
- vw(n)
- long n;
- {
- fwrite(&cube[n][0], 4, 3, fp);
- }
-
- nw(n)
- long n;
- {
- fwrite(&ncube[n][0], 4, 3, fp);
- fwrite(&nullcolor[0], 4, 3, fp);
- }
-
- octvert(n)
- long n;
- {
- fwrite(&ncube[n][0], 4, 3, fp);
- fwrite(&nullcolor[0], 4, 3, fp);
- fwrite(&ncube[n][0], 4, 3, fp);
- }
-
- sgotri(a, b, c)
- long a, b, c;
- {
- octvert(a); octvert(b); octvert(c);
- }
-
- writesgooct()
- {
- long typeandcount[2];
-
- typeandcount[0] = OBJ_TRILIST;
- typeandcount[1] = 8*27;
- fwrite(&typeandcount[0], 4, 2, fp);
- sgotri(0, 2, 5);
- sgotri(0, 5, 3);
- sgotri(0, 3, 4);
- sgotri(0, 4, 2);
- sgotri(1, 2, 5);
- sgotri(1, 5, 3);
- sgotri(1, 3, 4);
- sgotri(1, 4, 2);
- }
-
- main()
- {
- long end = OBJ_END;
-
- /* comment out all but one of the next three lines */
- writesgoheader();
- /*writesgocube();*/
- /*writesgooct();*/
- writesgomesh();
- fwrite(&end, 4, 1, fp);
- fclose(fp);
- }
-
- writesgoheader(polycount)
- long polycount;
- {
- long magic;
-
- magic = 0x5424;
-
- fp = fopen("sgoout", "w");
- fwrite(&magic, 4, 1, fp);
- }
-
-