M2/Cata
From WoWDev
Some minor changes in the current release.
Contents |
Header
The header has mostly the layout of number-offset pairs, containing the number of a particular record in the file, and the offset. These appear at fixed places in the header. Record sizes are not specified in the file.
The header can be 0x130 or 0x138 bytes big.
| Offset | Type | Name | Description | |
|---|---|---|---|---|
| 0x000 | char[4] | Magic | "MD20" | |
| 0x004 | uint32 | Version | 0x09 01 00 00 (first digit of the build the format was last updated), Patch12319 0x10 01 00 00 | |
| 0x008 | uint32 | lName | Length of the model's name | |
| 0x00C | uint32 | ofsName | Offset to the name | |
| 0x010 | uint32 | GlobalModelFlags | 1: tilt x, 2: tilt y, 4:, 8: add another field in header, 16: ; (no other flags as of 3.1.1); list at M2/Cata/flags | |
| 0x014 | uint32 | nGlobalSequences | ||
| 0x018 | uint32 | ofsGlobalSequences | A list of timestamps. | |
| 0x01C | uint32 | nAnimations | ||
| 0x020 | uint32 | ofsAnimations | Information about the animations in the model. | |
| 0x024 | uint32 | nAnimationLookup | ||
| 0x028 | uint32 | ofsAnimationLookup | Mapping of global IDs to the entries in the Animation sequences block. | |
| 0x02C | uint32 | nBones | ||
| 0x030 | uint32 | ofsBones | Information about the bones in this model. | |
| 0x034 | uint32 | nKeyBoneLookup | ||
| 0x038 | uint32 | ofsKeyBoneLookup | Lookup table for key skeletal bones. | |
| 0x03C | uint32 | nVertices | ||
| 0x040 | uint32 | ofsVertices | Vertices of the model. | |
| 0x044 | uint32 | nViews | Views (LOD) are now in .skins. | |
| 0x048 | uint32 | nColors | ||
| 0x04C | uint32 | ofsColors | Color definitions. | |
| 0x050 | uint32 | nTextures | ||
| 0x054 | uint32 | ofsTextures | Textures of this model. | |
| 0x058 | uint32 | nTransparency | ||
| 0x05C | uint32 | ofsTransparency | Transparency of textures. | |
| 0x060 | uint32 | nUVAnimation | ||
| 0x064 | uint32 | ofsUVAnimation | ||
| 0x068 | uint32 | nTexReplace | ||
| 0x06C | uint32 | ofsTexReplace | Replaceable Textures. | |
| 0x070 | uint32 | nRenderFlags | ||
| 0x074 | uint32 | ofsRenderFlags | Blending modes / render flags. | |
| 0x078 | uint32 | nBoneLookupTable | ||
| 0x07C | uint32 | ofsBoneLookupTable | A bone lookup table. | |
| 0x080 | uint32 | nTexLookup | ||
| 0x084 | uint32 | ofsTexLookup | The same for textures. | |
| 0x088 | uint32 | nUnk1 | ||
| 0x08C | uint32 | ofsUnk1 | This was texture units in 3.x | |
| 0x090 | uint32 | nTransLookup | ||
| 0x094 | uint32 | ofsTransLookup | Everything needs its lookup. Here are the transparencies. | |
| 0x098 | uint32 | nUVAnimLookup | ||
| 0x09C | uint32 | ofsUVAnimLookup | ||
| 0x0A0 | Vec3F[2] | VertexBox | ||
| 0x0B8 | float | VertexRadius | ||
| 0x0BC | Vec3F[2] | BoundingBox | ||
| 0x0D4 | float | BoundingRadius | ||
| 0x0D8 | uint32 | nBoundingTriangles | ||
| 0x0DC | uint32 | ofsBoundingTriangles | Our bounding volumes. Similar structure like in the old ofsViews. | |
| 0x0E0 | uint32 | nBoundingVertices | ||
| 0x0E4 | uint32 | ofsBoundingVertices | ||
| 0x0E8 | uint32 | nBoundingNormals | ||
| 0x0EC | uint32 | ofsBoundingNormals | ||
| 0x0F0 | uint32 | nAttachments | ||
| 0x0F4 | uint32 | ofsAttachments | Attachments are for weapons etc. | |
| 0x0F8 | uint32 | nAttachLookup | ||
| 0x0FC | uint32 | ofsAttachLookup | Of course with a lookup. | |
| 0x100 | uint32 | nEvents | ||
| 0x104 | uint32 | ofsEvents | Used for playing sounds when dying and a lot else. | |
| 0x108 | uint32 | nLights | ||
| 0x10C | uint32 | ofsLights | Lights are mainly used in loginscreens but in wands and some doodads too. | |
| 0x110 | uint32 | nCameras | ||
| 0x114 | uint32 | ofsCameras | The cameras are present in most models for having a model in the Character-Tab. | |
| 0x118 | uint32 | nCameraLookup | ||
| 0x11C | uint32 | ofsCameraLookup | And lookup-time again. | |
| 0x120 | uint32 | nRibbonEmitters | ||
| 0x124 | uint32 | ofsRibbonEmitters | Things swirling around. See the CoT-entrance for light-trails. | |
| 0x128 | uint32 | nParticleEmitters | ||
| 0x12C | uint32 | ofsParticleEmitters | Spells and weapons, doodads and loginscreens use them. Blood dripping of a blade? Particles. | |
| 0x130 | uint32 | nUnknown2 | This field is getting added in models with the 8-flag only. If that flag is not set, this field does not exist! | |
| 0x134 | uint32 | ofsUnknown2 | It has a array out of shorts. Its related to renderflags. |
Textures
- Textures are defined globally in a list, additionally, a lookup table is given, referenced during rendering, to select textures.
- First is a list of nTextures texture definition records, 16 bytes per record, starting at ofsTextures.
After it comes a string block with the texture filenames, which seems to have the same structure like the MOTX-Chunk in WMOs(see WMO), the "empty aligtments" are just the zeros were non "0 - hardcoded" type textures point too.
| Offset | Type | Name | Description |
|---|---|---|---|
| 0x000 | uint32 | Type | The type of the texture. See below. |
| 0x004 | uint32 | Flags | Textures have some flags. See below too. |
| 0x008 | uint32 | lenFilename | Here is the length of the filename, if the type is not "0 - hardcoded" then it's just 1 and points to a zero |
| 0x00C | uint32 | ofsFilename | And the offset to the filename. |
Texture Types
Texture type is 0 for regular textures, nonzero for skinned textures (filename not referenced in the M2 file!) For instance, in the NightElfFemale model, her eye glow is a type 0 texture and has a file name, the other 3 textures have types of 1, 2 and 6. The texture filenames for these come from client database files:
- DBFilesClient\CharSections.dbc
- DBFilesClient\CreatureDisplayInfo.dbc
- DBFilesClient\ItemDisplayInfo.dbc
- (possibly more)
| Value | Meaning | |
|---|---|---|
| 0 | Texture given in filename | |
| 1 | Body + clothes | |
| 2 | Item, Capes ("Item\ObjectComponents\Cape\*.blp") | |
| 3 | Unknown - Used on several models but not used in the client as far as I see. Armor Reflect? | |
| 6 | Hair, beard | |
| 8 | Tauren fur | |
| 9 | Used on inventory art M2s (1): inventoryartgeometry.m2 and inventoryartgeometryold.m2 | |
| 10 | Only used in quillboarpinata.m2. I can't even find something referencing that file. Oo Is it used? | |
| 11 | Skin for creatures or gameobjects #1 | |
| 12 | Skin for creatures or gameobjects #2 | |
| 13 | Skin for creatures or gameobjects #3 | |
| 14 | Used on inventory art M2s (2): ui-buffon.m2 and forcedbackpackitem.m2
(LUA::Model:ReplaceIconTexture("texture")) | |
| 15 | New in Cataclysm, eg Goblin Character Model | |
| 16 | New in Cataclysm, eg Goblin Character Model | |
| 17 | New in Cataclysm, eg Goblin Character Model |
Flags
| Value | Meaning | |
|---|---|---|
| 1 | Texture wrap X | |
| 2 | Texture wrap Y |
Texture lookup table
- nTexLookup items starting at ofsTexLookup.
| Offset | Type | Name | Description | |
|---|---|---|---|---|
| 0x00 | uint16 | TextureId | Array indices (0 to n-1). |
Replacable texture lookup
- nTexReplace 16-bit integers starting at ofsTexReplace.
| Offset | Type | Name | Description | |
|---|---|---|---|---|
| 0x00 | int16 | TextureID | Array indices (0 to n-1). |
A reverse lookup table for 'replaced' textures, mapping replacable ids to texture indices or -1. Only goes up to the maximum id used in the model.
The table may look like this:
| Type | TextureID | |
|---|---|---|
| HARDCODED | 0 | |
| BODY | -1 | |
| ITEM | -1 | |
| UNKNOWN3 | -1 | |
| UNKNOWN4 | -1 | |
| UNKNOWN5 | -1 | |
| HAIRBEARD | -1 | |
| UNKNOWN7 | -1 | |
| TAURENFUR | -1 | |
| UNKNOWN9 | -1 | |
| UNKNOWN10 | -1 | |
| CREATURESKIN1 | 2 | |
| CREATURESKIN2 | 1 | |
| CREATURESKIN3 | -1 |
Its strange, that HARDCODED is in the list, as a model can have more than one of course. Its just the last one written to the file.
One should investigate the unknown types. Maybe they are usable for something nice.
Cameras
Complete and right as of 17-AUG-09 (3.0.9 or higher)
- nCameras records of 0x64 bytes starting at ofsCameras.
These blocks are present in the "flyby" camera models which completely lack geometry and the main menu backdrop models which are supposed to have a fixed camera. Additionally, characters and monsters also have this block. The reason that non-mainmenu and non-geometry M2s have cameras was is you can see the unit's portrait and the character info tab.
| Offset | Type | Name | Description | |
|---|---|---|---|---|
| 0x00 | uint32 | Type | 0: potrait, 1: characterinfo; -1: else (flyby etc.); referenced backwards in the lookup table. | |
| 0x04 | float | FarClipping | Where it stops to be drawn. | |
| 0x08 | float | NearClipping | Far and near. Both of them. | |
| 0x0C | ABlock | TranslationPos | How the camera's position moves. Should be 3*3 floats. (WoW parses 36 bytes = 3*3*sizeof(float)) | |
| 0x20 | float | Position[3] | Where the camera is located. | |
| 0x2C | ABlock | TranslationTar | How the target moves. Should be 3*3 floats. | |
| 0x40 | float | Target[3] | Where the camera points to. | |
| 0x4C | ABlock | Scaling | The camera can have some roll-effect. Its 0 to 2*Pi. 3 Floats! | |
| 0x60 | ABlock | AnimBlock4 | One Float. |
Camera lookup table
Complete and right as of 17-AUG-09 (3.0.9 or higher)
- nCameraLookup 16-bit integers starting at ofsCameraLookup.
This block lists the different cameras existant in the model. The index in the array is also the type. CameraLookupTable[1] is always the character tab camera.
| Offset | Type | Name | Description | |
|---|---|---|---|---|
| 0x00 | uint16 | CameraId | All cameras by type. Array indices (0 to n-1). |
Particles
Patch 12319 had changed the particle structure.
