For triangle-bintree-based ROAM implementations, surfaces must be put into a form that consists of quadrilateral tiles made up of (2n+1)x(2n+1) arrays of surface points. These tiles must match on their mutual boundaries, i.e. the array's boundary entries on one tile's edge must match those on its edge-neighbor's edge. The following ASCII-text format (.tile files) is used to store such tiled surfaces, and contains the surface positions, material colors and unit normals for every point. We have developed tools that produce tiled surfaces in this format from a scalar-field isosurfacing process and through subdivision-surface editing. These files are then converted to a binary, ready-to-render format (.qtile files) that are described on another page.
The file format is as follows:
The first line is the number of square tiles making up the surface, e.g.
n 86means there are 86 tiles. The remainder of the file is the data for the tiles, one at a time.
A tile starts with the line
f 12 3 34 2 56 1 78 0The "f" indicates this is the face adjacency info. There are always four adjacent faces, listed in this order:
+---------------------------+ | 2 | | | | | | | | | | 3 1 | | | | | | | | | | 0 | start --> +---------------------------+Each adjacency link is two numbers, first the face index of the neighbor (e.g. 12) and second the edge of that neighbor that points back (e.g. 3).
The next line for a tile is the tile array dimensions
a 65 33This means the array is 65 wide and 33 tall, and contains 65*33 vertices. Note that the array boundary rows/columns are duplicated in the respective neighbor array boundary row/column.
Finally the remainder of the tile is one line per vertex
v 0.149558 0.147513 0.606701 1 1 1 0.693204 0.456271 0.557929The first three numbers are the (x,y,z) position of the vertex. The next three numbers are the (r,g,b) color (on a scale of 0=black, 1.0=maximum intensity). The final three numbers are the unit-length normal vector.
These vertices are listed in the following order:
2 +---------------------------+ | | | | | | | | | | 3 10 11 ... | 1 | | | | 5 6 7 8 9 | | | | start --> 0------1------2------3------4 0Here is a simple data structure and API for .tile surfaces:
lib_struct { int n; // number of tiles in object tile tiles,tiles1; // list of tiles (start and end elements) } tileobj; lib_struct { tileobj tob; // tile object containing this tile tile t0,t1; // links for tob's tiles list int titab[4]; // indices of edge-neighbor tiles int eitab[4]; // back-pointing edge index int nu,nv; // tile array sizes float *p; // array of points (stored x y z x y z ..) float *pn; // array of normals int ti; // tile index (application-supplied) } tile; tileobj tileobj_create(); // create an empty tile object void tileobj_destroy(tileobj tob); // de-allocate tile object tileobj tileobj_readascii(char *filename); // append tiles from .tile file tile tile_create(tileobj tob,int nu,int nv,float *p); // add tile void tile_destroy(tile t); // kill a particular tileObviously this is missing a tileobj_writeascii() call... This code is included in the ROAM source code distribution in the Tile directory. Check out tilespin.l and tile2qtile.l as applications of this library.
Updated Dec 21, 1999