OBJ For Developers

This document is written for for programmers who are writing import/export scripts/plugins for 3-d modeling programs. It is a supplement to the OBJ8 Specification and other OBJ documentation.

This document explains the philosophy behind OBJ8; the OBJ8 file format is fairly rich and contains a large number of individual commands and attributes. By understanding how the file format is structured, you can simplify the process of writing an importer or exporter.

Before reading the specific notes it may help to look at some very simple OBJ files in a text editor, or export simple shapes from another 3-d program.

= OBJ8 Art Assets =

Like most games and rendering engines, X-Plane uses proprietary, application-specific file formats for final deployed art assets and content. All 3-d models in X-Plane are represented by OBJ files (no relationship to Wavefront OBJs). OBJs are text files that contain all aspects of a 3-d model except for the textures, which are referenced by file name.

Conceptually an OBJ has the following information:
 * Global header information (e.g. references to external textures and other object-wide propreties).
 * A table of mesh geometry (vertices and indices).
 * One or more levels of detail, each containing an annotated mesh - that is, the actual mesh, with meta data applied via commands.
 * The annotated mesh can contain intervening special-purpose draw commands (e.g. billboard lights, smoke puffs).

= Mesh Notes =

X-Plane's mesh is drawn in the order specified in the file. Conceptually a mesh is broken into batches of triangles that all have uniform properties. Properties are applied to those mesh triangles by an attribute command. Attributes operate on a virtual state machine. For example:

TRIS 0 300 ATTR_lit_level 0 1 sim/some/dataref TRIS 0 30
 * 1) We are in the 'default state'.
 * 2) This specifies that 100 triangles are in the first batch
 * 1) This defines a second batch of 10 triangles, with the lighting levels changed.

Pretty much all non-global "attributes" apply to the following mesh triangles. For example, ATTR_lit_level specifies what sim variable maps to the emissive texture brightness for the following triangles, and ATTR_shiny_rat controls the level of specular hilights on the following triangles.

Historically, the number of attributes available on a batch of triangles has grown over time; exporters should use a flexible mapping from the 3-d program's interface to enable easy addition of new attributes.

= Animation =

Objects animate via transform animation - that is, key framed animation commands change the coordinate system for subsequent meshes. OBJ does not have a full skin system; you can think of OBJ animation as a skin system where an entire batch of triangles must be anchored to a single bone with 100% vertex weight.

Animations can be nested; animation groups define the scope of nesting.

Besides translations and rotations, show-hide animation commands can inhibit drawing. Show-hide commands only affect drawing, not meta data. There is no way to have an attribute be conditionally applied to an element of mesh. For example: ANIM_begin ANIM_hide 0 1 some/dataref ATTR_no_cull ANIM_end TRIS 0 100 is exactly the same as ATTR_no_cull TRIS 0 100
 * 1) This batch is ALWAYS 2-sided!

= Intervening Commands =

Some commands in an OBJ can produce non-mesh drawing. The main examples are named lights and lines, but this category also includes smoke puffs, etc. When possible, this interleaved drawing is done in between drawing parts of the mesh. Intervening drawing is subject to animation but is usually not affected by attributes, which usually only affect mesh batches.