.MDX

From Wikipedia, the free encyclopedia

.MDX files are 3D model files engineered and used by Blizzard Entertainment in their games. Several variations exists but this document focuses on the format used in Warcraft 3 and Frozen Throne. The format actually comes in two flavors, .MDX and .MDL. .MDX is a binary format. It's harder to edit but has generally smaller filesizes. .MDL is a text format which allows you to edit the models with just Notepad. The text formatting increases the filesize drastically though. Several converters exists to quickly convert between these formats.

Contents

[edit] Converters

This is a list of known converters to convert to and from the MDX format.

[edit] Editors

This is a list of known editors for manipulating the MDX files.

[edit] Code syntax

All code samples below will be given in a C/C++ like pseudo code. To simplify syntax and readability some have been splitted into substructures. The following notations are used to describe this.

  • X - A structure X that must be present and in the given order
  • {X} - A structure X that may or may not be present. They may also be in a different order.

A few special fields exists which has specific meanings.

  • ChunkSize - The size of the chunk (see General structure below)
  • InclusiveSize - The size of the structure including the size of this variable
  • ExclusiveSize - The size of the structure NOT including the size of this variable

Other notations.

  • #X - A flag value. Multiple flags can be combined in a single variable.

[edit] Datatypes

In the code below various datatypes are used. This is a table describing these datatypes.

  • UINT8 - An 8-bit unsigned integer, little endian
  • UINT16 - A 16-bit unsigned integer, little endian
  • UINT32 - A 32-bit unsigned integer, little endian
  • FLOAT - A 32-bit floating point number, IEEE single precision
  • FLOAT[N] - A sequence of N 32-bit floating point numbers forming a vector
  • STRING[N] - A sequence of N 8-bit characters forming a string

[edit] General structure

All models have a tree hiearchy of components, or chunks. Many components lie directly under the root while others are subcomponents. The contents vary from type to type though most of them have the same kind of header as shown below.

struct Chunk
{
  UINT32 Tag;
  UINT32 ChunkSize;

  ...
};

Each chunk begins with two 32-bit unsigned integers. The first is a tag describing the type. It's usually (always) constructed as a sequence of four 8-bit characters giving them a descriptive id if viewed in a hex editor (or even Notepad). The second integer tells the size of the chunk. This size does NOT include the tag and size itself, only the following contents. The ChunkSize is useful for determining the number of subcomponents, but if you're writing a non-complete MDX loader it's very useful for skipping whole chunks. Just read the tag and size then skip that many bytes to start reading the next chunk.

Some structures have ID's to reference other objects. These are 0-based indexes referencing the object in the order they appear in the file. The special value 0xFFFFFFFF (or -1 in signed format) represents "No ID", or in some cases "Many IDs". In the latter case the reference has to be made some other way, usually from the other object.

[edit] Components

[edit] Mdx

This is the root structure and is basically the entire file. All other components are subcomponents to this. Depending on the type some subcomponents can be left out, others have to be present.

struct Mdx
{
  UINT32 'MDLX';

  {VersionChunk};
  {ModelChunk};
  {SequenceChunk};
  {GlobalSequenceChunk};
  {MaterialChunk};
  {TextureChunk};
  {TextureAnimationChunk};
  {GeosetChunk};
  {GeosetAnimationChunk};
  {BoneChunk};
  {LightChunk};
  {HelperChunk};
  {AttachmentChunk};
  {PivotPointChunk};
  {ParticleEmitterChunk};
  {ParticleEmitter2Chunk};
  {RibbonEmitterChunk};
  {EventObjectChunk};
  {CameraChunk};
  {CollisionShapeChunk};
};

[edit] Node

This is not a component by itself but a shared structure containing data used by several other components. It's the base for the node hiearchy connecting parts together.

struct NodeTranslation
{
  UINT32 'KGTR';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct TranslationTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[3] Translation;

    if(InterpolationType > 1)
    {
      FLOAT[3] InTan;
      FLOAT[3] OutTan;
    }
  };
};
struct NodeRotation
{
  UINT32 'KGRT';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct RotationTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[4] Rotation;

    if(InterpolationType > 1)
    {
      FLOAT[4] InTan;
      FLOAT[4] OutTan;
    }
  };
};
struct NodeScaling
{
  UINT32 'KGSC';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[3] Scaling;

    if(InterpolationType > 1)
    {
      FLOAT[3] InTan;
      FLOAT[3] OutTan;
    }
  };
};
struct Node
{
  UINT32 InclusiveSize;

  STRING[80] Name;

  UINT32 ObjectId;
  UINT32 ParentId;
  UINT32 Flags;                        //0        - Helper
                                       //#1       - DontInheritTranslation
                                       //#2       - DontInheritRotation
                                       //#4       - DontInheritScaling
                                       //#8       - Billboarded
                                       //#16      - BillboardedLockX
                                       //#32      - BillboardedLockY
                                       //#64      - BillboardedLockZ
                                       //#128     - CameraAnchored
                                       //#256     - Bone
                                       //#512     - Light
                                       //#1024    - EventObject
                                       //#2048    - Attachment
                                       //#4096    - ParticleEmitter
                                       //#8192    - CollisionShape
                                       //#16384   - RibbonEmitter
                                       //#32768   - Unshaded / EmitterUsesMdl
                                       //#65536   - SortPrimitivesFarZ / EmitterUsesTga
                                       //#131072  - LineEmitter
                                       //#262144  - Unfogged
                                       //#524288  - ModelSpace
                                       //#1048576 - XYQuad

  {NodeTranslation}
  {NodeRotation}
  {NodeScaling}
};

[edit] Version

This simple structure tells which model version the MDX file has. It's usually 800 (for Warcraft 3 models at least).

struct VersionChunk
{
  UINT32 'VERS';
  UINT32 ChunkSize;

  UINT32 Version;                       //Currently 800
};

[edit] Model

This structure keeps some generic model information like its name.

struct ModelChunk
{
  UINT32 'MODL';
  UINT32 ChunkSize;

  STRING[80] Name;
  STRING[260] AnimationFileName;

  FLOAT BoundsRadius;
  FLOAT[3] MinimumExtent;
  FLOAT[3] MaximumExtent;
  UINT32 BlendTime;
};

[edit] Sequence

Sequences tells which animations can be played and in which intervals they exist. All animation data exists in one huge track, this structure splits that track into lesser logical animations.

struct SequenceChunk
{
  UINT32 'SEQS';
  UINT32 ChunkSize;

  struct Sequence[NrOfSequences]       //NrOfSequences = ChunkSize / 132
  {
    STRING[80] Name;

    UINT32 IntervalStart;
    UINT32 IntervalEnd;
    FLOAT MoveSpeed;
    UINT32 Flags;                      //0 - Looping
                                       //1 - NonLooping
    FLOAT Rarity;
    UINT32 SyncPoint;

    FLOAT BoundsRadius;
    FLOAT[3] MinimumExtent;
    FLOAT[3] MaximumExtent;
  };
};

[edit] Global Sequence

Apart from the main animation track a number of so called Global Sequences can be used for separate tracks. This is useful for animations that does not depend on the currently selected Sequence. As an example the propeller of a Gyrocopter uses a Global Sequence since it does not depend on whether its moving, standing still etc... This prevents the propeller from jumping or resetting its location when an animation is looping or being switched.

struct GlobalSequenceChunk
{
  UINT32 'GLBS';
  UINT32 ChunkSize;

  struct GlobalSequence[NrOfGlobalSequences]  //NrOfGlobalSequences = ChunkSize / 4
  {
    UINT32 Duration;
  };
};

[edit] Material

Materials tells what properties the skin of the model has, which texture is used how many layers are rendered etc...

struct MaterialAlpha
{
  UINT32 'KMTA';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Alpha;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct MaterialTextureId
{
  UINT32 'KMTF';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    UINT32 TextureId;

    if(InterpolationType > 1)
    {
      UINT32 InTan;
      UINT32 OutTan;
    }
  };
};
struct MaterialLayer
{
  UINT32 'LAYS';
  UINT32 NrOfLayers;

  struct Layer[NrOfLayers]
  {
    UINT32 InclusiveSize;

    UINT32 FilterMode;                 //0 - None
                                       //1 - Transparent
                                       //2 - Blend
                                       //3 - Additive
                                       //4 - AddAlpha
                                       //5 - Modulate
                                       //6 - Modulate2x

    UINT32 ShadingFlags;               //#1   - Unshaded
                                       //#2   - SphereEnvironmentMap
                                       //#4   - ???
                                       //#8   - ???
                                       //#16  - TwoSided
                                       //#32  - Unfogged
                                       //#64  - NoDepthTest
                                       //#128 - NoDepthSet

    UINT32 TextureId;
    UINT32 TextureAnimationId;
    UINT32 CoordId;
    FLOAT Alpha;

    {MaterialAlpha}
    {MaterialTextureId}
  };
};
struct MaterialChunk
{
  UINT32 'MTLS';
  UINT32 ChunkSize;

  struct Material[NrOfMaterials]
  {
    UINT32 InclusiveSize;

    UINT32 PriorityPlane;
    UINT32 Flags;                      //#1  - ConstantColor
                                       //#2  - ???
                                       //#4  - ???
                                       //#8  - SortPrimitivesNearZ
                                       //#16 - SortPrimitivesFarZ
                                       //#32 - FullResolution

    {MaterialLayer}
  };
};

[edit] Texture

The texture tells how the surface of the skin looks like. It's usually referencing a predefined picture but can be replaceable meaning the game decides which texture to use. One common use of this is so called team colors, which tells if the unit should be painted red or blue (like player 1 or player 2).

struct TextureChunk
{
  UINT32 'TEXS';
  UINT32 ChunkSize;

  struct Texture[NrOfTextures]         //NrOfTextures = ChunkSize / 268
  {
    UINT32 ReplaceableId;

    STRING[260] FileName;
    UINT32 Flags;                      //#1 - WrapWidth
                                       //#2 - WrapHeight
  };
};

[edit] Texture Animation

This structure allows for more advanced texture manipulation, the texture coordinates can be animated for nice effects. One example is the Water Elemental whose water texture seems to be flowing.

struct TextureTranslation
{
  UINT32 'KTAT';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct TranslationTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[3] Translation;

    if(InterpolationType > 1)
    {
      FLOAT[3] InTan;
      FLOAT[3] OutTan;
    }
  };
};
struct TextureRotation
{
  UINT32 'KTAR';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct TranslationTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[4] Rotation;

    if(InterpolationType > 1)
    {
      FLOAT[4] InTan;
      FLOAT[4] OutTan;
    }
  };
};
struct TextureScaling
{
  UINT32 'KTAS';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct TranslationTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[3] Scaling;

    if(InterpolationType > 1)
    {
      FLOAT[3] InTan;
      FLOAT[3] OutTan;
    }
  };
};
struct TextureAnimationChunk
{
  UINT32 'TXAN';
  UINT32 ChunkSize;

  struct TextureAnimation[NrOfTextureAnimations]
  {
    UINT32 InclusiveSize;

    {TextureTranslation}
    {TextureRotation}
    {TextureScaling}
  };
};

[edit] Geoset

The Geoset is a collection of vertices and faces forming the actual shape of the model. Advanced models usually have several geosets since each geoset can only have one material.

struct GeosetChunk
{
  UINT32 'GEOS';
  UINT32 ChunkSize;

  struct Geoset[NrOfGeosets]
  {
    UINT32 InclusiveSize;

    UINT32 'VRTX';
    UINT32 NrOfVertexPositions;

    struct VertexPosition[NrOfVertexPositions]
    {
      FLOAT[3] Position;
    };

    UINT32 'NRMS';
    UINT32 NrOfVertexNormals;

    struct VertexNormal[NrOfVertexNormals]
    {
      FLOAT[3] Normal;
    };

    UINT32 'PTYP';
    UINT32 NrOfFaceTypeGroups;

    struct FaceTypeGroup[NrOfFaceTypeGroups]
    {
      UINT32 FaceType;                 //4   - Triangles
                                       //??? - Triangle fan
                                       //??? - Triangle strip
                                       //??? - Quads
                                       //??? - Quad strip
    };

    UINT32 'PCNT';
    UINT32 NrOfFaceGroups;

    struct FaceGroup[NrOfFaceGroups]
    {
      UINT32 NrOfIndexes;
    };

    UINT32 'PVTX';
    UINT32 TotalNrOfIndexes;

    struct Face[TotalNrOfFaces]        //TotalNrOfFaces = TotalNrOfIndexes / 3
    {
      UINT16 Index1;
      UINT16 Index2;
      UINT16 Index3;
    };

    UINT32 'GNDX';
    UINT32 NrOfVertexGroups;

    struct VertexGroup[NrOfVertexGroups]
    {
      UINT8 MatrixGroup;
    };

    UINT32 'MTGC';
    UINT32 NrOfMatrixGroups;

    struct MatrixGroup[NrOfMatrixGroups]
    {
      UINT32 MatrixGroupSize;
    };

    UINT32 'MATS';
    UINT32 NrOfMatrixIndexes;

    struct MatrixIndex[NrOfMatrixIndexes]
    {
      UINT32 MatrixIndex;
    };

    UINT32 MaterialId;
    UINT32 SelectionGroup;
    UINT32 SelectionFlags;             //0  - None
                                       //#1 - ???
                                       //#2 - ???
                                       //#4 - Unselectable

    FLOAT BoundsRadius;
    FLOAT[3] MinimumExtent;
    FLOAT[3] MaximumExtent;

    UINT32 NrOfExtents;

    struct Extent[NrOfExtents]
    {
      FLOAT[3] MinimumExtent;
      FLOAT[3] MaximumExtent;
    };

    UINT32 'UVAS';
    UINT32 NrOfTextureVertexGroups;

    UINT32 'UVBS';
    UINT32 NrOfVertexTexturePositions;

    struct VertexTexturePosition[NrOfVertexTexturePositions]
    {
      FLOAT[2] TexturePosition;
    };
  };
};

[edit] Geoset Animation

This structure allows for advanced geoset handling, like animating the tinted color or the alpha (visibility).

struct GeosetAlpha
{
  UINT32 'KGAO';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Alpha;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct GeosetColor
{
  UINT32 'KGAC';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[3] Color;

    if(InterpolationType > 1)
    {
      FLOAT[3] InTan;
      FLOAT[3] OutTan;
    }
  };
};
struct GeosetAnimationChunk
{
  UINT32 'GEOA';
  UINT32 ChunkSize;

  struct GeosetAnimation[NrOfGeosetAnimations]
  {
    UINT32 InclusiveSize;

    FLOAT Alpha;
    UINT32 Flags;                      //#1 - DropShadow
                                       //#2 - Color
    FLOAT[3] Color;

    UINT32 GeosetId;

    {GeosetAlpha}
    {GeosetColor}
  };
};

[edit] Bone

Together with Helpers Bones constructs the basic hiearchy of the model. Assume a human model, bones form the basic shapes like torso, head, legs and arms. Helpers are the inner nodes while Bones are the outer nodes (who are connected to geosets).

struct BoneChunk
{
  UINT32 'BONE';
  UINT32 ChunkSize;

  struct Bone[NrOfBones]
  {
    Node;

    UINT32 GeosetId;
    UINT32 GeosetAnimationId;
  };
};

[edit] Light

Lights are, well, lights. They illuminate the model in various ways.

struct LightVisibility
{
  UINT32 'KLAV';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Visibility;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct LightColor
{
  UINT32 'KLAC';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[3] Color;

    if(InterpolationType > 1)
    {
      FLOAT[3] InTan;
      FLOAT[3] OutTan;
    }
  };
};
struct LightIntensity
{
  UINT32 'KLAI';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Intensity;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct LightAmbientColor
{
  UINT32 'KLBC';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[3] AmbientColor;

    if(InterpolationType > 1)
    {
      FLOAT[3] InTan;
      FLOAT[3] OutTan;
    }
  };
};
struct LightAmbientIntensity
{
  UINT32 'KLBI';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT AmbientIntensity;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct LightChunk
{
  UINT32 'LITE';
  UINT32 ChunkSize;

  struct Light[NrOfLights]
  {
    UINT32 InclusiveSize;

    Node;

    UINT32 Type;                       //0 - Omnidirectional
                                       //1 - Directional
                                       //2 - Ambient
    FLOAT AttenuationStart;
    FLOAT AttenuationEnd;
    FLOAT[3] Color;
    FLOAT Intensity;
    FLOAT[3] AmbientColor;
    FLOAT AmbientIntensity;

    {LightVisibility}
    {LightColor}
    {LightIntensity}
    {LightAmbientColor}
    {LightAmbientIntensity}
  };
};

[edit] Helper

Together with Bones Helpers constructs the basic hiearchy of the model. Assume a human model, bones form the basic shapes like torso, head, legs and arms. Helpers are the inner nodes ()who connects other Helpers or Bones while Bones are the outer nodes .

struct HelperChunk
{
  UINT32 'HELP';
  UINT32 ChunkSize;

  struct Helper[NrOfHelpers]
  {
    Node;
  };
};

[edit] Attachment

Attachments defines points where stuff can connect to. One of the most common uses are for special effects which adds visual enhancements to these areas. For example Bloodlust adds a glowing red model at both hands while Stun adds a whirlwind model at the head.

struct AttachmentVisibility
{
  UINT32 'KATV';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Visibility;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct AttachmentChunk
{
  UINT32 'ATCH';
  UINT32 ChunkSize;

  struct Attachment[NrOfAttachments]
  {
    UINT32 InclusiveSize;

    Node;

    STRING[260] Path;
    UINT32 AttachmentId;               //First attachment - 0, second - 1 etc...

    {AttachmentVisibility}
  };
};

[edit] Pivot Point

Pivot points defines the origo for geometrical transformations. This is especiall important for rotations and scalings since they give different results depending around which point the model is rotated/scaled.

struct PivotPointChunk
{
  UINT32 'PIVT';
  UINT32 ChunkSize;

  struct PivotPoint[NrOfPivotPoints]   //NrOfPivotPoints = ChunkSize / 12
  {
    FLOAT[3] Position;
  };
};

[edit] Particle Emitter

The particle emitter is a simple emitter which can spawn models or textures. It's most useful for spawning models as a Particle Emitter 2 gives much more freedom for texture spawning.

struct ParticleEmitterVisibility
{
  UINT32 'KPEV';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Visibility;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct ParticleEmitterChunk
{
  UINT32 'PREM';
  UINT32 ChunkSize;

  struct ParticleEmitter[NrOfParticleEmitters]
  {
    UINT32 InclusiveSize;

    Node;

    FLOAT EmissionRate;
    FLOAT Gravity;
    FLOAT Longitude;
    FLOAT Latitude;

    STRING[260] SpawnModelFileName;

    FLOAT LifeSpan;
    FLOAT InitialVelocity;

    {ParticleEmitterVisibility}
  };
};

[edit] Particle Emitter 2

This particle emitter spawns textures that can be animated in numerous ways. Particles are used for adding nice effects to a model. This may include sparks, blood, fire and whatever your imagination comes up with.

struct ParticleEmitter2Visibility
{
  UINT32 'KP2V';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Visibility;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct ParticleEmitter2EmissionRate
{
  UINT32 'KP2E';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT EmissionRate;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct ParticleEmitter2Width
{
  UINT32 'KP2W';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Width;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct ParticleEmitter2Length
{
  UINT32 'KP2N';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Length;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct ParticleEmitter2Speed
{
  UINT32 'KP2S';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Speed;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct ParticleEmitter2Chunk
{
  UINT32 'PRE2';
  UINT32 ChunkSize;

  struct ParticleEmitter2[NrOfParticleEmitters2]
  {
    UINT32 InclusiveSize;

    Node;

    FLOAT Speed;
    FLOAT Variation;
    FLOAT Latitude;
    FLOAT Gravity;
    FLOAT Lifespan;
    FLOAT EmissionRate;
    FLOAT Length;
    FLOAT Width;

    UINT32 FilterMode;                 //0 - Blend
                                       //1 - Additive
                                       //2 - Modulate
                                       //3 - Modulate2x
                                       //4 - AlphaKey

    UINT32 Rows;
    UINT32 Columns;
    UINT32 HeadOrTail;                 //0 - Head
                                       //1 - Tail
                                       //2 - Both

    FLOAT TailLength;
    FLOAT Time;

    FLOAT[3][3] SegmentColor;
    UINT8[3] SegmentAlpha;
    FLOAT[3] SegmentScaling;

    UINT32 HeadIntervalStart
    UINT32 HeadIntervalEnd
    UINT32 HeadIntervalRepeat
    UINT32 HeadDecayIntervalStart
    UINT32 HeadDecayIntervalEnd
    UINT32 HeadDecayIntervalRepeat
    UINT32 TailIntervalStart
    UINT32 TailIntervalEnd
    UINT32 TailIntervalRepeat
    UINT32 TailDecayIntervalStart
    UINT32 TailDecayIntervalEnd
    UINT32 TailDecayIntervalRepeat

    UINT32 TextureId;
    UINT32 Squirt;                     //0 - No Squirt
                                       //1 - Squirt
    UINT32 PriorityPlane;
    UINT32 ReplaceableId;

    {ParticleEmitter2Visibility}
    {ParticleEmitter2EmissionRate}
    {ParticleEmitter2Width}
    {ParticleEmitter2Length}
    {ParticleEmitter2Speed}
  };
};

[edit] Ribbon Emitter

A ribbon emitter is kind of a particle emitter though not quite. It spawns a long textured ribbon along the path the emitter moves. It's worth noting that if the ribbon emitter doesn't move at all no ribbon will be visible since the length will be 0.

struct RibbonEmitterVisibility
{
  UINT32 'KRVS';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Visibility;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct RibbonEmitterHeightAbove
{
  UINT32 'KRHA';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT HeightAbove;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct RibbonEmitterHeightBelow
{
  UINT32 'KRHB';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct ScalingTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT HeightBelow;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct RibbonEmitterChunk
{
  UINT32 'RIBB';
  UINT32 ChunkSize;

  struct RibbonEmitter[NrOfRibbonEmitters]
  {
    UINT32 InclusiveSize;

    Node;

    FLOAT HeightAbove;
    FLOAT HeightBelow;
    FLOAT Alpha;
    FLOAT[3] Color;
    FLOAT LifeSpan;

    UINT32 ???;                         //Always 0?

    UINT32 EmissionRate;
    UINT32 Rows;
    UINT32 Columns;
    UINT32 MaterialId;
    FLOAT Gravity;

    {RibbonEmitterVisibility}
    {RibbonEmitterHeightAbove}
    {RibbonEmitterHeightBelow}
  };
};

[edit] Event Object

Certain events can be triggered during an animation. This includes playing sounds, spawning footprints and more. What is triggered is decided by its name which follows a set structure (see the Blizzard Art Tools Documentation for a huge list).

struct EventObjectTrack
{
  UINT32 'KEVT';
  UINT32 NrOfTracks;

  UINT32 GlobalSequenceId;

  struct Track[NrOfTracks]
  {
    UINT32 Time;
  };
};
struct EventObjectChunk
{
  UINT32 'EVTS';
  UINT32 ChunkSize;

  struct EventObject[NrOfEventObjects]
  {
    Node;

    {EventObjectTrack}
  };
};

[edit] Camera

The camera has a few uses perhaps most importantly for the portrait that is showed at the bottom of the game screen.

struct CameraPositionTranslation
{
  UINT32 'KCTR';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct TranslationTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[3] Translation;

    if(InterpolationType > 1)
    {
      FLOAT[3] InTan;
      FLOAT[3] OutTan;
    }
  };
};
struct CameraTargetTranslation
{
  UINT32 'KTTR';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct TranslationTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT[3] Translation;

    if(InterpolationType > 1)
    {
      FLOAT[3] InTan;
      FLOAT[3] OutTan;
    }
  };
};
struct CameraRotation
{
  UINT32 'KCRL';

  UINT32 NrOfTracks;
  UINT32 InterpolationType;            //0 - None
                                       //1 - Linear
                                       //2 - Hermite
                                       //3 - Bezier
  UINT32 GlobalSequenceId;

  struct TranslationTrack[NrOfTracks]
  {
    UINT32 Time;
    FLOAT Rotation;

    if(InterpolationType > 1)
    {
      FLOAT InTan;
      FLOAT OutTan;
    }
  };
};
struct CameraChunk
{
  UINT32 'CAMS';
  UINT32 ChunkSize;

  struct Camera[NrOfCameras]
  {
    UINT32 InclusiveSize;

    STRING[80] Name;

    FLOAT[3] Position;
    FLOAT FieldOfView;
    FLOAT FarClippingPlane;
    FLOAT NearClippingPlane;
    FLOAT[3] TargetPosition;

    {CameraPositionTranslation}
    {CameraTargetTranslation}
    {CameraRotation}
  };
};

[edit] Collision Shape

Collision shapes defines a few bounding boxes and bounding spheres that allows selection of the model using the mouse cursor and helps in frustum culling (removing objects outside the screen).

struct CollisionShapeChunk
{
  UINT32 'CLID';
  UINT32 ChunkSize;

  struct CollisionShape[NrOfCollisionShapes]
  {
    Node;

    UINT32 Type;                       //0 - Box
                                       //1 - ???
                                       //2 - Sphere

                                       //NrOfVertices = 2 (if Type == 0)
    struct Vertex[NrOfVertices]        //NrOfVertices = 1 (if Type == 2)
    {
      FLOAT[3] Position;
    };

    if(Type == 2)
    {
      FLOAT BoundsRadius;
    }
  };
};

[edit] References and Credits