PLG, FIG, WLD File Formats

Original by Bernie Roehl

Edited by Paul Bourke
October 1994


PLG Format

I originally designed PLG files for use with REND386; for
better or worse, they seem to have become something of a standard. 
REND386, AVRIL, VR386 and Jon Blossom's Gossamer all use them for
object geometry description; there are also translators that turn
other formats into PLG, and the NorthCAD-3D program can generate
PLG files as output.  The PLG in the name stands for "polygon".

There will soon be a file format for the interchange of
virtual objects and virtual worlds between VR systems; at that
point, support for the PLG file format will diminish.  Conversion
programs will be made available to convert PLG files to the new
format.

A PLG file basically has three parts: a header line, a list
of vertices and a list of facets.

The header line has the object name, the number of vertices,
and the number of facets; for example:

     kitchen_table 100 35

which would mean that the object "kitchen_table" has 100 vertices
and 35 facets.

Anything after the facet count should be ignored, since it
may be used for future expansion.

Following this line are the vertices, one x,y,z triplet per
line (each value is a floating-point number, and they're
separated by spaces).  For example:

     18027 23025 98703

Only the first three values on the line should be used; anything
following these values should be ignored.  This allows future
support for such things as vertex normals.

This is followed by the facet information, one line per
facet; each of these lines is of the form

     surfacedesc n v1 v2 v3 ...

The surfacedesc is described below.  The n is the number of
vertices in the facet.  The v1, v2, v3 and so on are indices into
the array of vertices; the vertices are listed in a counter-
clockwise order as seen from the "front" (i.e. visible side) of
the facet.  Note that the vertices are counted "origin zero",
i.e. the first vertex is vertex number 0, not vertex number 1.

For example:

     0x8002 4 8 27 5 12

would mean a four-sided facet bounded by vertices 8, 27, 5 and
12.  This facet has a surface descriptor of 0x8002.

Anything after the list of vertex indices should be ignored.

The PLG format supports comments.  Anything after a # should
be ignored by any program that parses PLG files.  In addition,
lines beginning with a '*' should be ignored.

PLG files can have multiple copies of an object at different
resolutions.  PLG files containing such multiple-resolution
versions of objects must have "#MULTI" as their first line.

For each object defined in such a file, the object name
includes a number specifying the pixel size of the object on the
screen.  The object names for each representation must be

     name_####

where #### is the smallest pixel width to use this representation
for. For example, TABLE_15 would be a valid name.

If the smallest rep size is zero, then that represenation
will be used no matter how small the object gets.  If the
smallest rep size is 1 or greater, then the object will vanish if
it gets too small.

The surface descriptor can either be a decimal integer or a
0x or 0X followed by a hexadecimal integer value.  The surface
descriptor is a 16-bit value which is interpreted as follows:

     H R SS CCCC BBBBBBBB

The R bit is reserved, and should be set to zero.  If the H bit
is set, it indicates that this is a "mapped" surface descriptor;
the bottom 14 bits are taken to be an index into a surface map.

If the H bit is clear, the SS bits are interpreted as follows:

00 --     This facet is "solid shaded"; i.e. it should be
          drawn in a fixed color, with no special effects.
          If the CCCC bits are zero, then the BBBBBBBB bits
          directly specify one of the 256 available colors;
          if the CCCC bits are non-zero, then they specify
          one of sixteen hues and the top four bits of
          BBBBBBBB specify which shade of that hue to use.

01 --     This facet is "flat shaded"; i.e. it should be
          drawn with a constant shading that is determined
          by the angle at which light is striking it; thus,
          as the facet moves around, its apparent brightness
          will change.  The CCCC bits specify one of sixteen
          hues, and the bottom 8 bits BBBBBBBB represent the
          "brightness" of the color.  This brightness value
          is multiplied by the cosine of the angle between
          the facet's normal vector and the vector from the
          facet to the light source; the result is used to
          specify an offset into the given color's array of
          shades.  Note that if the CCCC value is 0, the
          color will always be black.

10 --     This facet should be treated as being "metallic";
          the CCCC bits (which should be non-zero) specify
          one of the 16 hues, and the top 5 bits of the
          BBBBBBBB value are used as an offset into a range
          of shades to cycle through to give the metallic
          effect, i.e. a starting offset into the color
          cycle.

11 --     This facet should be treated as being
          "transparent"; it is just like surface type 10,
          except that alternating rows of dots are used
          instead of solid colors, allowing you to "see
          through" the facet.

Palette of first 256 indices


FIG Format

FIG files are a way of representing multi-segmented, hierarchical
entities.

      This format will soon be considered obsolete.

There will soon be a file format for the interchange of
virtual objects and virtual worlds between VR systems; at that
point, support for the FIG file format will diminish.  Conversion
programs will be made available to convert FIG files to the new
format.

The syntax of a figure file is simple, and very C-like.  It
consists of a series of segments, each of which can possess a set
of attributes, as well as child segments.  Each segment is
bounded by braces.  Attributes are arbitrary text strings ending
in a semicolon.

The list of possible attributes is open-ended and
extensible; programs that read figure files should ignore any
attributes they don't recognize.

An example will make all this clearer.

comment = a human body;
name = pelvis;  comment = this is the name of the root segment;
     {
     name = chest;
              { name = left upper arm; { name = left lower arm; } }
              { name = right upper arm; { name = right lower arm; } }
              { name = head; }
     }
     { name = left upper leg; { name = right lower leg; } }
     { name = right upper leg; { name = right lower leg; } }
     }
}

In general, attributes are of the form "keyword = value;", though
this is not a requirement.  The attributes used above are name
and comment.  Note that no program ever has to recognize a
comment attribute, since by defintion comments should be ignored.

The attributes currently defined are as follows:

name = somestring;
       pos = x,y,z;
       rot = x,y,z;
       plgfile = filename scale x,y,z shift X,Y,Z sort type map filename;
       segnum = someinteger;

The pos is the x,y,z displacement of the origin of this segment
relative to the parent's coordinate system.  The rot is the
rotation of this segment relative to the parent.  For root
objects (which have no parent) these values are the absolute
location and rotation of the entire figure in world coordinates.

The plgfile gives the name of a .plg file containing a
geometric representation of the segment.  Note that the figure
file format does not strictly depend on .plg files; the reason
the syntax is "plgfile = " rather than just "file =" is because a
segment may have a large number of different representations and
an application can choose whichever one they like.

The scale, shift, sort and map values are all optional, but
in order to specify any of them you must specify all the
preceeding ones (i.e. you cannot simply omit the scale
parameter).  The scale values represent the amount by which the
object should be scaled along each of its axes when it's loaded. 
The shift value is the amount by which to shift the object's
origin at load time.  The sort value is the type of depth-sorting
to use for this segment's representation (the default is zero). 
The map value is the name of a file containing a list of unsigned
values that are to be used in surface remapping for this segment. 
If the top bit of a color value is set in a plg file, the bottom
fourteen bits are used as an index into this map.

The difference between shift and pos is important.  The
shift value is used to shift an object relative to its "native"
origin, while the pos value is the amount by which the new origin
should be displaced from the parent node's origin.

For example, suppose you want to represent the head of a
human figure with a cube.  The cube may, in the .plg file, be
defined with its (0,0,0) point at one corner.  Clearly, this
origin is inconvenient for the head, since if the origin is
centered over the neck of the figure then the head will be
displaced to one side.

Alternatively, the cube might be defined with its (0,0,0)
point at its geometric center.  However, this is also
impractical; your head  should not rotate freely about its
center.  If it does, stop reading this document immediately and
seek medical attention.

What you to do is shift the cube so that its origin lies
below the center of the cube, where your "neck joint" is.  That's
what the shift value in the plgfile attribute specifies.

Important note: objects rotate about their [0,0,0] point as
loaded.

The pos attribute specifies where this neck joint is in
relation to the origin of the chest segment.  If your chest were
longer vertically, then the pos attribute of the head segment
should be increased in the Y direction (for example).

The segnum attribute associates a simple integer value with
a segment, which can subsequently be used to refer to the segment
when manipulating it.

Note that a figure file can in fact contain a series of
segments; each of these is a root segment, so a figure file can
in effect store a complete scene description (excluding lights
and cameras).

WLD Format

WLD files were designed to store information about the layout of
objects in a virtual world.

       This format will soon be considered obsolete.

There will soon be a file format for the interchange of virtual
objects and virtual worlds between VR systems; at that point,
support for the WLD file format will diminish.  Conversion
programs will be made available to convert WLD files to the new
format.

A WLD file is entirely ascii.  Each statement is one line;
anything after the first '#' is treated as a comment and ignored. 
Blank lines are also ignored.  The format is intended to be
highly extensible; any line which cannot be recognized should
simply be ignored.  Each statement contains some information
about the scene; the possible types of statements are listed
below.  Everything is case-insensitive; keywords are shown below
in uppercase, but are generally entered in lowercase.

LOADPATH path
     Specifies a path prefix for loading files.  Any files
     (whether specified in the world file itself, subsequent
     world files, or in referenced FIG files) will be loaded from
     the specified directory.  However, if a filename begins with
     the '\' or '/' characters, it is used verbatim (i.e. the
     LOADPATH setting is ignored).

PALETTE filename
     Loads a 256-entry binary palette file (3 bytes (R,G,B) for
     each entry).  Note that alternate palettes may not handle
     shading as well as the default one does.

SKYCOLOR index
     Specifies which of the 256 available colors should be used
     for the "sky".

GROUNDCOLOR index
     Specifies which of the 256 available colors should be used
     for the "ground". If the sky and ground color are identical,
     a solid screen clear is used; this is a bit faster.

SCREENCLEAR value
     If the specified value is non-zero, then the screen will be
     cleared before each frame; if it's zero, the screen clearing
     is not done (this is useful if you know that the entire
     window will be covered by the image, and that no background
     will show through; in such a situation, specifying this
     option will improve performance).

AMBIENT value
     Specifies the level of the ambient light; 76 is the default,
     and a good value to use.

LIGHT x,y,z
     Specifies the location of a light source in world
     coordinates.

CAMERA x,y,z tilt,pan,roll zoom
     Specifies your starting location, viewing direction and zoom
     factor.  The x,y,z values are floating-point numbers giving
     coordinates, the tilt,pan,roll values are floating-point
     angles, and the zoom is a floating-point number giving the
     zoom factor.

HITHER value
     Specifies the near clipping distance in world coordinates. 
     The value should typically be 10 or more.

YON value
     Specifies the far clipping distance in world coordinates. 
     The value should typically be 1000000 or more.

OBJECT [objname=]filename sx,sy,sz rx,ry,rz tx,ty,tz depthtype
mappings parent
     Loads an object from a .plg file with the given filename. 
     If the objname= is present, it assigns the newly-loaded
     object that name for future reference.  The sx,sy,sz values
     are floating-point scale factors to increase or decrease the
     size of the object as it's loaded.  The rx,ry,rz values are
     the angles to rotate the object around in each of the three
     axes; ry is done first, then rx and finally rz.  The
     tx,ty,tz values translate (move) the object to a new
     location; this is done after the scaling and rotation.  The
     depthtype field is not currently used.  The mappings feature
     is explained below.  The parent field is the name of the
     object that this object is a child of; if omitted, the child
     moves independently.  If parent is the word "fixed", then
     the object is fixed in space and cannot be moved.  All
     fields are optional, but you must include all the fields
     prior to the last one you wish to use (i.e. you can only
     leave things off the end, not off the beginning or out of
     the middle).

FIGURE [figname=]filename sx,sy,sz rx,ry,rz tx,ty,tz parent
     Loads a segmented figure from a FIG file with the given
     filename.  All the parameters have the same meaning as for
     the OBJECT statement described above.

POLYOBJ npts surface x1,y1,z1 x2,y2,z2 [...] x8,y8,z8
     Directly specifies a facet to be placed in the scene.  The
     value npts is the number of points (maximum 8), the surface
     is a surface name (see below on surfaces) and the vertices
     are given in world coordinates.

POLYOBJ2 npts surface1,surface2 x1,y1,z1 x2,y2,z2 [...] x8,y8,z8
     Directly specifies a double-sided facet to be placed in the
     scene.  The value npts is the number of points (maximum 8),
     surface1 and surface2 are surface names (see below on
     surfaces) and the vertices are given in world coordinates.

INCLUDE filename
     Includes the specified file as if its contents appeared at
     the current point in the current file.

POSITION objname x,y,z
     Moves (i.e. translates) the specified object to the given
     x,y,z location.

ROTATE objname rx,ry,rz
     Rotates the specified object to the given angles about each
     of the axes.  The angles are specified in floating point,
     and are measured in degrees.  The rotation order is Y then X
     then Z.

VERSION number
     Allows you to define a version number.  Not currently used
     for anything; can be omitted.

TITLE text
     Allows you to define a title for your world.

About Mapping
A PLG file can contain indexed color values (such as 0x8002)
which are used to index a surface map.  Entries in surface maps
refer to surfaces.  Surfaces are created using the SURFACEDEF
statement, surface maps are created with the SURFACEMAP
statement, and entries are placed in them with the SURFACE
statement.  The statement formats are as follows:

SURFACEDEF name value
     Defines a new surface; maps a surface name (such as "wood")
     to a numeric surface descriptor (value) of the type
     described in Appendix C.

SURFACEMAP name maxentries
     Marks the start of a new surface map.  All subsequent
     SURFACE entries will be placed in this map.  The maxentries
     field gives the maximum number of entries this surface map
     will have; if omitted, it defaults to 10.

SURFACE index name
     Defines an entry in the current surface map, which takes an
     index value (the bottom 15 bits of the value in the .plg
     file) and maps it into a surface name (which is in turn
     mapped to a 16-bit color value).

USEMAP mapname
     Causes all subsequently loaded objects that don't have a
     mapname on their OBJECT statements to use the specified
     mapname.