MDL file

From Wiki

Jump to: navigation, search
Line 177: Line 177:
 
===The animation frame buffer===
 
===The animation frame buffer===
 
</legend>
 
</legend>
 +
{{main|/Algorithm A (Tinman codec)}}
  
 +
The Tinman frame buffer model cannot be represented by a definite structure. It is instead a kind of specialized compression algorithm. For a precise definition, there is [[MDL (file format)/Algorithm A (Tinman codec)]].
 +
 +
How it works in a nutshell; there is a sequence of variable length frames, which are themselves comprised of a sequence of variable length channel operations. Unaffected channels are omitted per frame. And in general the affect upon the channel for that frame is proportional to the amount of bits consumed by that operation. Each operation upon a channel is accumulated frame by frame until the animation runs its course.
 +
 +
The word length of the frame buffer in total is not part of the MDL format. It is necessary to traverse the coarsest level of granularity afforded the frame buffer model in order to compute it. Or in fact to arrive at the end of the the animation itself. Which is where you will find the next animation, and so on, until the last animation indicated in the [[#Header]] is encountered.
 +
 +
The first channel operation sequence of the first frame of the first animation includes some additional information which describes a skeletal hierarchy by ID. IDs up to the number of [[#Primitive channels]] outlined into the file refer to the primitive channels themselves in that order. Subsequent IDs refer to hence undefined animation only channels, ie. lacking in geometry. 
 +
 +
Each channel operation has the net effect of transforming (eg. translating and rotating) its channel per each frame of animation.
 
</ifieldset>
 
</ifieldset>
  

Revision as of 18:57, 8 April 2011

<legend class="caps">

Header

</legend>

16 8bit bytes in total
LF HA SA TB PC 00 -16- PCSZ -16- HASZ SASZ

<ifieldset class="spec"> <legend> swordofmoonlight.h </legend>

LF: leadflags perhaps bitwise flags
HA: hardanims JointMIMe-like animation (PSOne)
SA: softanims Vertex/normalMIMe-like animation
TB: timblocks Textures (PSOne TIM image format)
PC: primchans one or more required (meshes)
00: unknown00 perhaps always one
PCSZ: primchanwords dword anims block offset (could be 32bit)
HASZ: hardanimwords dword sizeof anims block
SASZ: softanimwords dword sizeof diffs block

</ifieldset>

LF

This byte is not super well understood. It is either a straight value, or a bitwise combination of flag values. Known values are 0, 1, and 4. For not animated, Tinman style animation, and Scarecrow style animation respectively.

HA ¦  SA

These bytes are the number of hard and soft (aka. Tinman/Scarecrow) animations contained within the file.

TB

This byte is the number of PlayStation TIM images embedded within the file. These images are used as textures. It seems that the EneEdit tool somehow overrides the use of the embedded images, in favor of external TXR images which it is able to generate (please note that the author himself is uncertain the accuracy of this claim!!)

PC

This byte is the number of sub headers in the file, of which there is one of per each separate section of geometry (a MDL may include many such sections.)

PCSZ ¦ HASZ ¦ SASZ

These three 16bit values indicate the size of the first three data blocks. The units are in 32bit intervals. In other words, a value of 4, indicates 16 bytes. Each block begins after the previous block, therefore it is necessary to sum the preceding blocks in order to arrive at the offset to any given block. There is a fourth block, which runs to the end of the file. The four blocks respectively pertain to 3D geometry, Tinman animation, Scarecrow animation, and TIM images. The TIM images themselves can consecutively be thought of as 4th, 5th, and so on blocks. It's a matter of personal interpretation.

<legend class="tech">1st PRIMITIVE CHANNEL

Primitive channels

</legend>

7 32bit words in total
- -VB- - - -VC- - - -NB- - - -NC- - - -PB- - - -PC- - - -00- -

<ifieldset class="spec"> <legend> swordofmoonlight.h </legend>

VB: vertsbase dword offset to vertex block
VC: vertcount
NB: normsbase dword offset to normal block
NC: normcount
PB: primsbase dword offset to face block
PC: primcount
00: unknown00 probably always zero

</ifieldset>

VB ¦ NB ¦ PB

These three 32bit+ values are offsets which should be added to the end of the header (or the beginning of the first primitive channel sub header) in order to reach the beginning of the Vertex/Normal/Primitive (face) data belonging to this primitive channel. Part of the #Per vertex location, #Per vertex lighting, and #3D primitives blocks respectively. The units are in 32bit intervals. In other words, a value of 4, indicates 16 bytes. The offsets are absolute, which is to say, not relative to one another.

VC ¦ NC ¦ PC

These three 32bit+ values account for the number of elements expected to be found within the data indicated by VB, NB, PB respectively.

+The alignment is 32bit, the values themselves may be 16bit.

<legend>⋯</legend>

<legend>Nth PRIMITIVE CHANNEL</legend>

<legend class="tech">3D PRIMITIVES BLOCK

3D primitives

</legend>

<legend class="tech">PER VERTEX LOCATION BLOCK

Per vertex location

</legend>

This block is packed with consecutive 3D vertex coordinates side by side and nothing else. See #Primitive channels and #3D primitives for more information.

two 64bit vertices
-VX- -VY- -VZ- -00- -VX- -VY- -VZ- -00-
VX ¦ VY ¦ VZ

These are signed 16bit whole number values. The units are in millimeters, indicating a three dimensional point in space.

00

VX/Y/Z cover all the bases for a 3D vertex. These bits are not used (vertices must begin on 32bit word boundaries)

<legend class="tech">PER VERTEX LIGHTING BLOCK

Per vertex lighting

</legend>

This block is packed with consecutive 3D lighting vectors (surface normals) side by side and nothing else. See #Primitive channels and #3D primitives for more information.

two 64bit normals
-NX- -NY- -NZ- -00- -NX- -NY- -NZ- -00-
NX ¦ NY ¦ NZ

These are signed 16bit whole number values indicating a three dimensional surface normal. The convention is 4096:1. Not enough attention has been payed to if/when the values are normalized prior to use.

00

NX/Y/Z cover all the bases for a 3D normal. These bits are not used (normals must begin on 32bit word boundaries)

<legend class="tech">Tinman ANIMATIONS BLOCK

Tinman animations

</legend>

32bits
-NC- -00-
NC

This 16bit value accounts for the total number of animation channels. A channel may have primitives associated with it or not. Channels are arranged hierarchically / outwardly from a single top-level channel. When one channel is animated, the effect is applied accumulatively to the subordinate channels.

00

This 16bit value is not understood. It may always be 1.

<ifieldset class="spec"> <legend class="tech">1st Tinman ANIMATION

Animations by ID

</legend>

32bits
-ID- -NF-
ID

This 16bit value identifies the context of the animation. For instance, 0 for an "idle" animation. 4 for an "open" animation (eg. a door.) The meanings of the IDs appear to be implicit rather than conventional. Ie. they are hard wired into Sword of Moonlight itself. For a complete list of known IDs, see MDL (file format) / Appendix A (animation IDs).

NF

This 16bit value accounts for the total number of sequential frames involved in the animation. The frames are not interpolated over time, and appear at regular intervals. There is no standard reference in terms of timing. However traditional (eg. original Sword of Moonlight files) playback speed is approximately 30 frames per second (reports exist that PRF files are useful for modulating playback in some way unclear / not well documented)

<ifieldset class="spec"> <legend class="caps">

The animation frame buffer

</legend>

The Tinman frame buffer model cannot be represented by a definite structure. It is instead a kind of specialized compression algorithm. For a precise definition, there is MDL (file format) / Algorithm A (Tinman codec).

How it works in a nutshell; there is a sequence of variable length frames, which are themselves comprised of a sequence of variable length channel operations. Unaffected channels are omitted per frame. And in general the affect upon the channel for that frame is proportional to the amount of bits consumed by that operation. Each operation upon a channel is accumulated frame by frame until the animation runs its course.

The word length of the frame buffer in total is not part of the MDL format. It is necessary to traverse the coarsest level of granularity afforded the frame buffer model in order to compute it. Or in fact to arrive at the end of the the animation itself. Which is where you will find the next animation, and so on, until the last animation indicated in the #Header is encountered.

The first channel operation sequence of the first frame of the first animation includes some additional information which describes a skeletal hierarchy by ID. IDs up to the number of #Primitive channels outlined into the file refer to the primitive channels themselves in that order. Subsequent IDs refer to hence undefined animation only channels, ie. lacking in geometry.

Each channel operation has the net effect of transforming (eg. translating and rotating) its channel per each frame of animation. </ifieldset>

</ifieldset> <ifieldset class="spec"> <legend>⋯</legend> </ifieldset> <ifieldset class="spec"> <legend>Nth Tinman ANIMATION</legend> </ifieldset>

<legend class="tech">Scarecrow ANIMATIONS BLOCK

Scarecrow animations

</legend>

<legend class="tech">1st PlayStation .TIM IMAGE

TIM imaging

</legend>

This block is an embedded TIM image which works as a 3D Texture. The TIM specifications are not fully implemented by Sword of Moonlight. 24bit color mode is not supported. Dimensions are restricted to 256x256 pixels or less. It's generally not known to what extent the PlayStation frame buffer is implemented. Up to four 256x256 textures are known to work (some speculations are conceivable.)

<legend>⋯</legend>

<legend>Nth PlayStation .TIM IMAGE</legend>

See also