Luanti .obj
file format specification
#
The .obj
file format supported by Luanti is a subset of Wavefront Object (.obj
) Files.
Material (.mtl
) files are not supported; .obj
files can not be animated.
Number formatting #
Numbers are formatted as either floats or integers:
Floats #
An optional minus sign (-
), followed by one or more digits,
followed by a decimal dot (.
), followed by one or more digits.
Example: -42.3
.
Integers #
Optional minus sign (-
), followed by one or more digits.
Example: -42
.
Indices #
Indexing starts at one; indices are always integers.
Negative indices (-1
being the last element) are supported.
Commands #
.obj
is a line-based format.
Each line contains a “command” followed by a series of parameters, separated by spaces.
Comments are done by starting a line with #
.
Luanti supports the following commands:
- Vertex coordinates:
v <x> <y> <z>
- Texture coordinates:
vt <u> <v>
- Vertex normals:
vn <x> <y> <z>
- Groups:
g <name>
(recommended) orusemtl <name>
introduce a new group- Choosing unique names is recommended; avoid empty groups
- Subsequent faces belong to a new material (separate texture / tile)
- Texture slots / indices are determined by order of appearance
Info
Irrlicht’s .obj
reader happens to be quite lax at the moment -
just looking at the first few characters needed to tell commands apart,
ignoring superfluous parameters, ignoring unsupported commands -
but you must not rely on this.
Coordinate System #
Normally you should not need to care about these conventions - appropriate conversions ensure that your models look the same in Luanti as in your model editor - but knowledge may be necessary (1) to choose the correct export settings or (2) when procedurally generating .obj
models using Lua code.
.obj
uses a right-handed coordinate system, which is converted to Luanti’s left-handed coordinate system by inverting the X-axis.
Additionally, Luanti uses V-down texture coordinates,
whereas .obj
uses V-up, hence the v
coordinate (texture Y-coordinate) is flipped.
The center of a node or object respectively is the origin of the .obj
.
Note
For legacy reasons, entities use a 10x scale for meshes: 10 units = 1 node. Nodes, however, use a 1 node = 1 unit scale. This means a full node extends from (-0.5, -0.5, -0.5) to (0.5, 0.5, 0.5); whereas a 1³ cube entity would extend from (-5, -5, -5) to (5, 5, 5).
Tip
You can use node visual_scale
to compensate this inconsistency,
e.g. if you want to use the same model for a node and entity.
(Using the visual_size
object property instead is not recommended,
as it propagates to children when using attachments;
you would have to divide the child visual size by the parent’s
visual size to undo this, and remember to multiply again when detaching.)
Examples #
Plane #
A simple textured square at z = 0.
v 0 0 0
v 0 1 0
v 1 1 0
v 1 0 0
vt 0 0
vt 0 1
vt 1 1
vt 1 0
f 1/1 2/2 3/3
f 3/3 4/4 1/1
Cube #
# A cube (for use as a node) centered at the origin; each face receives a separate texture / tile
# no care was taken to ensure "proper" texture orientation
v -0.5 -0.5 -0.5
v -0.5 -0.5 0.5
v -0.5 0.5 -0.5
v -0.5 0.5 0.5
v 0.5 -0.5 -0.5
v 0.5 -0.5 0.5
v 0.5 0.5 -0.5
v 0.5 0.5 0.5
vn -1 0 0
vn 0 -1 0
vn 0 0 -1
vn 1 0 0
vn 0 1 0
vn 0 0 1
vt 0 0
vt 1 0
vt 0 1
vt 1 1
g right
f 1/1/1 3/3/1 2/2/1 4/4/1
g bottom
f 1/1/2 5/3/2 2/2/2 6/4/2
g front
f 1/1/3 5/3/3 3/2/3 7/4/3
g left
f 5/1/4 7/3/4 2/2/4 8/4/4
g top
f 3/1/5 7/3/5 4/2/5 8/4/5
g back
f 2/1/6 6/3/6 4/2/6 8/4/6