MODL: Difference between revisions
mNo edit summary |
(→Nodes) |
||
(20 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
== Conventions/Terminology == | == Conventions/Terminology == | ||
This document employs several terms and conventions | This document employs several terms and conventions. Most of these are concerned with data types, of course. | ||
* float - IEEE floating point value | * float - IEEE floating point value | ||
* vectorN - an N-dimensional array that consists of N floats | * vectorN - an N-dimensional array that consists of N floats | ||
* geoset - a collection of meshes | * geoset - a collection of meshes | ||
* string - character array padded with zeros (one or more) at the end | * string - character array padded with zeros (one or more) at the end | ||
* All values are little-endian unless otherwise specified | |||
* Fields marked with "(?)" have not been verified. this should not be confused with an ordinary question mark "?", which is a valid part of a field's description. | |||
== Layout == | == Layout == | ||
Line 26: | Line 28: | ||
footer | footer | ||
That is, mesh primitives with no relational information | That is, mesh primitives with no relational information are specified first through geosets, meshes, and faces. Relations between mesh primitives are represented through nodes, which are specified last. | ||
=== Header === | === Header === | ||
The header is formatted as follows | The header is formatted as follows: | ||
"MODL" FOURCC |4 bytes | "MODL" FOURCC |4 bytes | ||
number of materials used|4 bytes | number of materials used|4 bytes | ||
This is followed by material name fields, one per material: | This is followed by material name fields, one per material: | ||
material name, string|32 bytes | material name|32 bytes, string | ||
Followed the rest of the header: | |||
3d model name|32 bytes, string | |||
=== Geoset === | |||
The geoset header is formatted as follows: | |||
unknown |4 bytes | |||
number of geosets|4 bytes | |||
This is followed by (not very interesting) geoset structures, one per geoset: | |||
number of meshes|4 bytes | |||
==== Mesh ==== | |||
A mesh is formatted as follows: | |||
mesh name |32 bytes, string | |||
unknown |4 bytes | |||
geometry mode |4 bytes | |||
lighting mode |4 bytes | |||
texture mode |4 bytes | |||
number of mesh vertices |4 bytes | |||
number of texture vertices |4 bytes | |||
number of faces |4 bytes | |||
mesh vertex data |vector3 * number of mesh vertices | |||
texture vertex data |vector2 * number of texture vertices | |||
extra light data (see notes) |float * number of mesh vertices | |||
unknown |4 bytes * number of mesh vertices | |||
face data (see below) |... | |||
mesh vertex normal data |vector3 * number of mesh vertices | |||
has shadow |4 bytes | |||
unknown |4 bytes | |||
mesh radius |4 bytes | |||
unknown |vector3 | |||
unknown |vector3 | |||
===== Faces ===== | |||
face id (?) |4 bytes | |||
face type |4 bytes | |||
geometry mode |4 bytes | |||
lighting mode |4 bytes | |||
texture mode |4 bytes | |||
number of vertices |4 bytes | |||
unknown |4 bytes | |||
has texture? |4 bytes | |||
has material? |4 bytes | |||
unknown |vector3 | |||
extra light |4 bytes, float | |||
unknown |vector3 | |||
normal vector |vector3 | |||
mesh vertex indices |4 bytes, one per vertex | |||
if has texture, texture vertex indices|4 bytes, one per texture vertex | |||
if has material, material index |4 bytes | |||
=== Nodes === | |||
The nodes header looks like this: | |||
unknown |4 bytes | |||
number of nodes|4 bytes | |||
Followed by node structures, one per node: | |||
name |64 bytes, string | |||
flags |4 bytes | |||
unknown |4 bytes | |||
type |4 bytes | |||
mesh id |4 bytes | |||
depth |4 bytes | |||
has parent? |4 bytes | |||
number of children |4 bytes | |||
has children? |4 bytes | |||
has sibling? |4 bytes | |||
pivot |vector3 | |||
position |vector3 | |||
pitch |4 bytes, float | |||
yaw |4 bytes, float | |||
roll |4 bytes, float | |||
unknown |48 bytes (whoa!) | |||
if has parent, parent id |4 bytes | |||
if has child, child id |4 bytes | |||
if has sibling, sibling id|4 bytes | |||
=== Footer === | |||
The final piece is the footer, which contains some more information about the model: | |||
model radius |4 bytes, float | |||
insertion offset (see notes)|vector3 | |||
== Notes == | |||
# Extra-light values are used to as additional brightness values that are added to their corresponding vertex brightness value. This way, for example, for a given vertex v, an illumination value of 0.5 will increase v's brightness by 0.5. Illumination values (are floats, and) are in the range [0, 1]. All encountered models so far have all illumination values of 0.00. | |||
# In order to conserve space, faces only refer to vertices in their enclosing mesh. Therefore a "vertex index" is simply the vertex's position in the vertex array, starting at 0. | |||
# A "node id" refers to the node's position in the breadth-first traversal of the node tree. | |||
[[Category:Game Formats]] [[Category:3D Mesh Formats]] | |||
Latest revision as of 17:33, 23 September 2006
This page attempts to document the LucasArts MODL mesh format, file extension ".3do". Work is ongoing, so no guarantees are made regarding any information on this page.
Variants
The MODL format comes in two flavours: binary, and ASCII. The ASCII flavour is used in the Grim Fandango demo, and the binary one is used in the full version. It follows that the demo version contains ASCII-versions of models that appear in the full version. Such models should be approached with care, because it's not unlikely that corresponding models from the two versions contain slightly different data.
This document is concerned with the binary flavour of the mesh files.
TODO -- add more games that use MODL, if there are any; upload samples.
Conventions/Terminology
This document employs several terms and conventions. Most of these are concerned with data types, of course.
- float - IEEE floating point value
- vectorN - an N-dimensional array that consists of N floats
- geoset - a collection of meshes
- string - character array padded with zeros (one or more) at the end
- All values are little-endian unless otherwise specified
- Fields marked with "(?)" have not been verified. this should not be confused with an ordinary question mark "?", which is a valid part of a field's description.
Layout
The MODL format, at the highest level, has the following layout:
header geoset(s) \mesh(es) \face(s) node(s) footer
That is, mesh primitives with no relational information are specified first through geosets, meshes, and faces. Relations between mesh primitives are represented through nodes, which are specified last.
Header
The header is formatted as follows:
"MODL" FOURCC |4 bytes number of materials used|4 bytes
This is followed by material name fields, one per material:
material name|32 bytes, string
Followed the rest of the header:
3d model name|32 bytes, string
Geoset
The geoset header is formatted as follows:
unknown |4 bytes number of geosets|4 bytes
This is followed by (not very interesting) geoset structures, one per geoset:
number of meshes|4 bytes
Mesh
A mesh is formatted as follows:
mesh name |32 bytes, string unknown |4 bytes geometry mode |4 bytes lighting mode |4 bytes texture mode |4 bytes number of mesh vertices |4 bytes number of texture vertices |4 bytes number of faces |4 bytes mesh vertex data |vector3 * number of mesh vertices texture vertex data |vector2 * number of texture vertices extra light data (see notes) |float * number of mesh vertices unknown |4 bytes * number of mesh vertices face data (see below) |... mesh vertex normal data |vector3 * number of mesh vertices has shadow |4 bytes unknown |4 bytes mesh radius |4 bytes unknown |vector3 unknown |vector3
Faces
face id (?) |4 bytes face type |4 bytes geometry mode |4 bytes lighting mode |4 bytes texture mode |4 bytes number of vertices |4 bytes unknown |4 bytes has texture? |4 bytes has material? |4 bytes unknown |vector3 extra light |4 bytes, float unknown |vector3 normal vector |vector3 mesh vertex indices |4 bytes, one per vertex if has texture, texture vertex indices|4 bytes, one per texture vertex if has material, material index |4 bytes
Nodes
The nodes header looks like this:
unknown |4 bytes number of nodes|4 bytes
Followed by node structures, one per node:
name |64 bytes, string flags |4 bytes unknown |4 bytes type |4 bytes mesh id |4 bytes depth |4 bytes has parent? |4 bytes number of children |4 bytes has children? |4 bytes has sibling? |4 bytes pivot |vector3 position |vector3 pitch |4 bytes, float yaw |4 bytes, float roll |4 bytes, float unknown |48 bytes (whoa!) if has parent, parent id |4 bytes if has child, child id |4 bytes if has sibling, sibling id|4 bytes
The final piece is the footer, which contains some more information about the model:
model radius |4 bytes, float insertion offset (see notes)|vector3
Notes
- Extra-light values are used to as additional brightness values that are added to their corresponding vertex brightness value. This way, for example, for a given vertex v, an illumination value of 0.5 will increase v's brightness by 0.5. Illumination values (are floats, and) are in the range [0, 1]. All encountered models so far have all illumination values of 0.00.
- In order to conserve space, faces only refer to vertices in their enclosing mesh. Therefore a "vertex index" is simply the vertex's position in the vertex array, starting at 0.
- A "node id" refers to the node's position in the breadth-first traversal of the node tree.