WorldToolKit Neutral File Format Version 2.1 The NFF Format The Sense8 neutral ASCII file format is a generic representation for polygonal geometry. Objects are represented as sets of polygons, and polygons are ordered collections of vertices. The format specifies polygon color and texture application, backface rejection, vertex normals, vertex colors, object names, polygon ids, and portals. Binary NFF (.bff) The NFF format is now supported in binary. The format layout and order is identical to the ASCII version, with the exception that 12-bit colors are not supported. (All colors are 24-bit.) NFF Syntax The following describes version 2.1 of the NFF format. For changes from earlier versions, see the section below, "NFF Revision History". NFF Header The file must begin with a line containing the string token "nff". The next line should state the version level of the NFF file. Next follows an optional viewpoint specification associated with the file, and a set of one or more object specifications. All lines must be terminated by a linefeed character, but the PC end-of-line convention CR-LF (carriage return - line feed) is also supported. NFF files may have comments placed on any line. The characters "//" introduce a comment. All characters on the line following the "//" are ignored. An NFF reader should also very flexible with white space; any number of tabs or spaces are allowed before, between and after words in the file. The second line in the file should be the NFF version number. The current version is 2.1. Although the version number is optional, providing it ensures that the file will be read correctly even if the NFF format changes in the future. The optional viewpoint is specified as two lines with the tokens "viewpos" and "viewdir". These specify the viewpoint's location and view direction respectively. Here is the entire header syntax: nff version n.nn [viewpos x y z] [viewdir x y z] Here is an example of a an NFF header: nff version 2.1 viewpos 0.000 0.000 0.000 viewdir 0.000 0.000 1.000 NFF Objects Each object specification starts with a line of text giving the object's symbolic name, followed by the description of the geometry of the object. The syntax is as follows: ... ... An NFF file can contain any number of objects, each described by its own name and geometry. The file structure is: ... NFF Vertices After the NFF object name, the next line should be a single integer value defining the total number of vertices in the object. Vertex x, y, z coordinates, as real numbers, follow one per line. One or more spaces or other white space must separate the numbers. You can optionally specify a normal vector for each vertex. The vertex normal is introduced by the keyword "norm" and is defined as three real numbers. Vertex normals are used for Gourand shading. You can optionally specify a vertex color. If vertex colors are provided for all the vertices of a polygon, the polygon is to be rendered with those colors instead of the polygon's color. The vertex color is introduced by the keyword "rgb" and takes the form 0xrrggbb, a hexadecimal number in the range 0x000000 to 0xffffff, with 8 bits each for red, green, and blue. For example, red is 0xff0000, black is 0x000000, white 0xffffff and yellow 0xffff00. A vertex may also specify an explicit texture coordinate (u,v). If present for all the vertices of a polygon, these (u,v) coordinates will precisely define the texture mapping. The vertex (u,v) values are introduced by the keyword "uv" and take the form of two floating-point numbers. Here is the vertex definition syntax: [norm ] [rgb <0xrrggbb>] [uv ] Here is an example of defining three vertices with vertex normals: 0.00 0.00 0.00 norm 0.707 0.707 0.00 -100.00 0.00 0.00 norm 1.00 0.00 0.00 0.00 100.00 0.00 norm -0.707 -0.707 0.00 This is an example of a vertex color: 0.00 2.00 0.00 rgb 0x0000ff // a blue vertex This is an example of a vertex uv value: 1.00 0.00 0.00 uv 0.5 0.5 // a uv coordinate NFF Polygons After defining the vertices, the next line contains the number of polygons in the object. Polygon specification lines follow, one for each polygon. Each polygon specification line is of the form: <#vertices>[both] [[]] [id=n] [] The polygon specification line starts with an integer giving the number of vertices in the polygon. Following that is a list of vertex indices for the current polygon, with zero referring to the first vertex in the object's vertex list. For backface rejection purposes it is important to note that the front face of a polygon is defined as the side of the polygon for which the vertices go around counter clockwise in a right-handed coordinate scheme. Backface rejection is further discussed below where the "both" flag is described. After the list of vertex indices is a color designator given in hexadecimal as a number in the range 0x0 to 0xffffff. The high order (left-most) 8 bits represent the red intensity, the middle 8 bits the green, and the low order 8 bits the blue, so that black is 0x000000, white is 0xffffff, and red is 0xff0000. If you wish, you may instead use a 12-bit color specification, in the form 0xrgb. The optional string "both" indicates that both sides of the polygon are to be visible. If "both" is not specified, then only front facing polygons, as defined above, are rendered. Optionally, a texture name and attributes can be specified for the polygon. When texturing is on, color is ignored for the textured polygons since the surface properties come from the texture. The texture name specifies the file containing the bitmap to be used as a texture and also specifies whether the texture is to be plain, shaded, or transparent. Shaded textures have their brightness affected by the lights present in the model. Transparent textures are rendered so that all black pixels in the source bitmap are transparent when the texture is applied to a polygon. Texture names begin with the character "_". The character following the "_" indicates the type of texture, according to the following: _v_ plain vanilla texture (no shading) _s_ shaded texture _t_ transparent texture _u_ shaded and transparent texture For example, a texture named "_v_rug" causes a texture from a file named "rug" to be used. A texture named "_s_rug" would apply the same texture, but shaded based on lighting. You can specify texture attributes in two ways: (1) by providing explicit uv mapping coordinates for the vertices using the "uv" keyword as described above in the section "NFF Vertices", or (2) by using the following keywords in the polygon specification: [rot ] [scale ] [trans ] [mirror] for texture rotation, scaling, translation, and mirroring respectively. Rotations are specified in radians, and all operations are performed in u,v texture coordinate space. Any or none of these attributes may appear, but they must be placed after the texture name. Note that if every vertex in the polygon has uv coordinates specified, then these uv values are used to determine the mapping of the texture onto the polygon, and any keywords which may be present (rot, scale, trans) are ignored. Regardless of the order of the attributes, at the time the polygon is loaded, they are applied in the following order: mirroring, rotation, scaling, translation. Since the NFF file's description of these texture attributes does not uniquely specify every possible transformation, if you require that files retain their exact transformation, use the vertex uv values. Using the optional polygon ID token "id=n", you can assign an integer value "n" to any polygon in your NFF file (example: id=567). Finally, a portal name can be specified for a polygon. Portal names begin with a hyphen "- " and contain the name of the universe to be loaded when the portal is crossed. This is a sample polygon specification, illustrating all possible options: 5 0 1 2 3 4 0xffff00 both _s_rug rot 1.0 scale 0.5 trans 1.0 1.0 id=5 -rugworld This polygon has 5 vertices and is colored yellow, although the yellow will not appear unless you are rendering without textures. Both sides of the polygon are visible, and a shaded rug texture is applied. The rug texture is rotated 1 radian, scaled to half-size, and translated by (1.0,1.0) in (u,v) space. The polygon`s ID number is set to 5 and if the viewpoint crosses this polygon, the universe "rugworld" will be loaded. WorldToolKit-Specific NFF Extensions Automatic Normal Generation Since adding vertex normals by hand can be difficult, WorldToolKit supports an automatic normal generation procedure for NFF files. To use this feature, you would add an "N" at the end of any vertex line for which you wanted WorldToolKit to calculate the normals. When the file is read into WorldToolKit, the "N" is replaced with an approximate vertex normal, based on the average of the polygons surrounding that vertex. This approximation may lead to an incorrect normal if polygons are defined haphazardly. You may also encounter problems if some vertices are shared by polygons you don't want Gouraud-shaded. In this case, you will have to make duplicate vertices - one with a vertex normal and one without. After reading in an object with automatic normals, you may want to write the object back out so that the next time it is read the normals are already calculated. NFF Version History and Backwards Compatibility 2.1 no changes 2.09 binary nff file format introduced added "rgb" keyword for vertex colors added "uv" keyword for vertex texture mapping coordinates added _u_ designation for textures which are both shaded and transparent 2.0 added "norm" keyword to introduce vertex normals allow 24-bit color for polygons 1.9 no changes 1.7 changed object shading to =on and =off instead of =flat and =none 1.6 first numbered version Sample NFF File The following is an example of a simple ASCII NFF file containing simple cube structures. Some polygons of the first cube are textured and some are not. nff // This is the first word of any NFF file. version 2.1 // The following two lines are optional. viewpos 0.0 0.0 0.0 // Viewpoint is at the origin viewdir 0.0 0.0 1.0 // and looking straight forward. SimpleCube // Name of the object. 8 // Number of vertices. 3.0 3.0 -3.0 // Vertex info. 3.0 -3.0 -3.0 -3.0 -3.0 -3.0 -3.0 3.0 -3.0 3.0 3.0 3.0 3.0 -3.0 3.0 -3.0 -3.0 3.0 -3.0 3.0 3.0 6 // Number of polygons. 4 0 1 2 3 0xff0000 both // 0xff0000 is the color, in this case, Red 4 7 6 5 4 0x00ff00 both // "both" sides of the cube's faces are visible, 4 0 4 5 1 0x0000ff both // so it is visible even from inside the cube. 4 1 5 6 2 0xffff00 both _S_wings // A shaded texture called "wings" 4 2 6 7 3 0xffffff both _T_fish rot 1.0 // A rotated, transparent fish texture 4 3 7 4 0 0x000000 both _V_kproom -kproom // a portal to universe "kproom" // with a texture called "kproom" SecondObject // Name of the object. 8 // Number of vertices. 9.0 9.0 -9.0 uv 0.0 0.0 // Vertex info, including texture uv. 9.0 -9.0 -9.0 uv 1.0 0.0 -9.0 -9.0 -9.0 uv 1.0 0.5 -9.0 9.0 -9.0 uv 0.0 0.5 9.0 9.0 9.0 rgb 0xff0000 9.0 -9.0 9.0 rgb 0xff8800 // orange -9.0 -9.0 9.0 rgb 0x0000ff -9.0 9.0 9.0 rgb 0xff0000 6 // Number of polygons. 4 0 1 2 3 0xff0000 both _T_fish // Texture is applied using vertex uv's // to apply bottom half of texture to polygon 4 7 6 5 4 0x00ff00 both // Note that this polygon will use vertex colors // instead of the polygon color! 4 0 4 5 1 0x0000ff both 4 1 5 6 2 0xffff00 both 4 2 6 7 3 0xffffff both 4 3 7 4 0 0x000000 both