The LPM format is a lightweight, human-readable format designed to store low-polygon 3D models. It supports vertices, normals, UVs, faces, and skeletal animations. Its simplicity makes it easy to parse and implement in custom tools.
- Single texture per model
- Comments supported (lines starting with
#
) - Compact and straightforward structure
- Skeletal animations support (optional)
- Comments start with
#
and must be on their own line. - Sections are identified by keywords (e.g.,
vertices
,faces
). - Values within sections are comma-delimited, and they can include as many whitespaces as desired.
- The
version
andtexture
headers use a colon:
followed by their values. - Sections for
bones
,weights
, andanimation
are optional for static models.
An LPM file has the following structure:
version: 1
texture: cube.png
vertices
faces
bones
weights
animation
Specifies the version of the LPM format.
- Syntax:
version: <number>
- Example:
version: 1
Specifies the texture file used for the model.
- Syntax:
texture: <filename>
- Example:
texture: cube.png
Defines the vertices of the model.
- Syntax:
<x>,<y>,<z>,<nx>,<ny>,<nz>,<u>,<v>
<x>,<y>,<z>
: Position of the vertex.<nx>,<ny>,<nz>
: Normal vector.<u>,<v>
: UV texture coordinates.
- Example:
vertices -1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0 1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0
Defines the faces of the model as a list of vertex indices.
- Syntax:
<v1>,<v2>,<v3>
- Example:
faces 0, 1, 2 0, 2, 3
Defines the skeletal hierarchy. (Optional for static models)
- Syntax:
<bone_name>,<bone_id>,<parent_bone_id>, <head_x>, <head_y>, <head_z>, <tail_x>, <tail_y>, <tail_z>
<bone_name>
: Name of the bone.<bone_id>
: Unique bone ID.<parent_bone_id>
: Parent bone ID (-1 for root).<head_x>, <head_y>, <head_z>
: Head coordinates of the bone in 3D space<tail_x>, <tail_y>, <tail_z>
: Tail coordinates of the bone in 3D space
- Example:
# Bones: bone_name, bone_id, parent_bone_id, head_x, head_y, head_z, tail_x, tail_y, tail_z bones Hips, 0, -1, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 Spine, 1, 0, 0.0, 1.0, 0.0, 0.0, 2.0, 0.0
Maps vertices to bones with associated weights. (Optional for static models)
- Syntax:
<vertex_id>,<bone_id_1>,<weight_1>,<bone_id_2>,<weight_2>, ...
<vertex_id>
: Index of the vertex in thevertices
section.<bone_id_n>
: Bone ID from thebones
section.<weight_n>
: Weight of the bone's influence (0.0 to 1.0).
- Example:
weights 0, 0, 1.0 1, 1, 0.5, 0, 0.5
Defines animation frames for bones. (Optional for static models)
- Syntax:
<frame_id>,<bone_id>,<x>,<y>,<z>,<rx>,<ry>,<rz>
<frame_id>
: ID of the frame<bone_id>
: ID of the bone.<x>,<y>,<z>
: Position of the bone.<rx>,<ry>,<rz>
: Rotation in radians.
- Example:
animation # Frame 0 0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 0, 1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0 # Frame 1 1, 0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.1 1, 2, 1.0, 0.1, 0.0, 0.0, 0.0, 0.1
- Comments (
#
) and empty lines are ignored. - Sections are terminated by the start of a new section or the end of the file.
- Data within sections is comma-delimited, and they can include as many whitespaces as desired.
- Section order:
version
texture
vertices
faces
- Optional:
bones
,weights
,animation
# LPM: Low Poly Model
version: 1
texture: cube.png
# Vertices: x, y, z, nx, ny, nz, u, v
vertices
-1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0
1.0, -1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 0.0
1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 1.0, 1.0
-1.0, 1.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0
# Faces: vertex_1, vertex_2, vertex_3
faces
0, 1, 2
0, 2, 3
# Bones: bone_name, bone_id, parent_bone_id, head_x, head_y, head_z, tail_x, tail_y, tail_z
bones
Hips, 0, -1, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0
Spine, 1, 0, 0.0, 1.0, 0.0, 0.0, 2.0, 0.0
# Weights: vertex_id, bone_id_1, weight_1, bone_id_2, weight_2, ...
weights
0, 0, 1.0
1, 1, 0.5, 0, 0.5
# Animation frames: frame_id, bone_id, pos_x, pos_y, pos_z, rot_x, rot_y, rot_z
animation
# Frame 0
0, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
0, 1, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0
# Frame 1
1, 0, 0.0, 0.1, 0.0, 0.0, 0.0, 0.1
1, 1, 1.0, 0.1, 0.0, 0.0, 0.0, 0.1