M2: Difference between revisions

From wowdev
Jump to navigation Jump to search
(k, so new style overall xD)
Line 11: Line 11:
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 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.


'''Offset Type Name Description'''
''0x000'' char[4] Magic "MD20"
''0x004'' uint32 Version 0x80100000 (first digit of the build the format was last updated)
''0x008'' uint32 lName Length of the model's name
''0x00C'' uint32 ofsName Offset to the name
''0x010'' uint32 GlobalModelFlags (0,1,3 seen), connected to field 4 of [[CreatureModelData.dbc]]?
''0x014'' uint32 nGlobalSequences
''0x018'' uint32 [[M2/WotLK#Global_sequences|ofsGlobalSequences]] A list of timestamps.
''0x01C'' uint32 nAnimations
''0x020'' uint32 [[M2/WotLK#Animation_sequences|ofsAnimations]] Information about the animations in the model.
''0x024'' uint32 nAnimationLookup
''0x028'' uint32 [[M2/WotLK#Animation_Lookup|ofsAnimationLookup]] Mapping of [[M2/WotLK#Animation_sequences|global IDs]] to the entries in the [[M2/WotLK#Animation_sequences|Animation sequences]] block.
''0x02C'' uint32 nBones
''0x030'' uint32 [[M2/WotLK#Bones|ofsBones]] Information about the bones in this model.
''0x034'' uint32 nKeyBoneLookup
''0x038'' uint32 [[M2/WotLK#Key-Bone_Lookup|ofsKeyBoneLookup]] Lookup table for key skeletal bones.
''0x03C'' uint32 nVertices
''0x040'' uint32 [[M2/WotLK#Vertices|ofsVertices]] Vertices of the model.
''0x044'' uint32 nViews [[M2/WotLK#Views_.28LOD.29|Views (LOD)]] are now in [[M2/WotLK/.skin|.skins]].
''0x048'' uint32 nColors
''0x04C'' uint32 [[M2/WotLK#Colors|ofsColors]] Color definitions.
''0x050'' uint32 nTextures
''0x054'' uint32 [[M2/WotLK#Texture_definitions|ofsTextures]] Textures of this model. Now .skins?
''0x058'' uint32 nTransparency
''0x05C'' uint32 [[M2/WotLK#Transparency|ofsTransparency]] Transparency of textures.
''0x060'' uint32 nTextureanimations
''0x064'' uint32 [[M2/WotLK#Texture_animations|ofsTextureanimations]]
''0x068'' uint32 nTexReplace
''0x06C'' uint32 [[M2/WotLK#Replacable_texture_lookup|ofsTexReplace]] Replaceable Textures.
''0x070'' uint32 nRenderFlags
''0x074'' uint32 [[M2/WotLK#Render_flags|ofsRenderFlags]] Blending modes / render flags.
''0x078'' uint32 nBoneLookupTable
''0x07C'' uint32 [[M2/WotLK#Bone_Lookup_Table|ofsBoneLookupTable]] A bone lookup table.
''0x080'' uint32 nTexLookup
''0x084'' uint32 [[M2/WotLK#Texture_lookup_table|ofsTexLookup]] The same for textures.
''0x088'' uint32 nTexUnits
''0x08C'' uint32 [[M2/WotLK#Texture_unit_lookup_table|ofsTexUnits]] And texture units. Somewhere they have to be too.
''0x090'' uint32 nTransLookup
''0x094'' uint32 [[M2/WotLK#Transparency_lookup_table|ofsTransLookup]] Everything needs its lookup. Here are the transparencies.
''0x098'' uint32 nTexAnimLookup
''0x09C'' uint32 [[M2/WotLK#Texture_animation_lookup_table|ofsTexAnimLookup]] Wait. Do we have animated Textures? Wasn't ofsTexAnims deleted? oO
''0x0A0'' float theFloats[14] Noone knows. Meeh, they are here.
''0x0D8'' uint32 nBoundingTriangles
''0x0DC'' uint32 [[M2/WotLK#Triangles|ofsBoundingTriangles]] Our bounding volumes. Similar structure like in the old ofsViews.
''0x0E0'' uint32 nBoundingVertices
''0x0E4'' uint32 [[M2/WotLK#Vertices_2|ofsBoundingVertices]]
''0x0E8'' uint32 nBoundingNormals
''0x0EC'' uint32 [[M2/WotLK#Normals|ofsBoundingNormals]]
''0x0F0'' uint32 nAttachments
''0x0F4'' uint32 [[M2/WotLK#Block_1|ofsAttachments]] Attachments are for weapons etc.
''0x0F8'' uint32 nAttachLookup
''0x0FC'' uint32 [[M2/WotLK#Attachment_Lookup|ofsAttachLookup]] Of course with a lookup.
''0x100'' uint32 nAttachments_2
''0x104'' uint32 [[M2/WotLK#Block_2|ofsAttachments_2]] And some second block.
''0x108'' uint32 nLights
''0x10C'' uint32 [[M2/WotLK#Lights|ofsLights]] Lights are mainly used in loginscreens but in wands and some doodads too.
''0x110'' uint32 nCameras
''0x114'' uint32 [[M2/WotLK#Cameras|ofsCameras]] The cameras are present in most models for having a model in the Character-Tab.
''0x118'' uint32 nCameraLookup
''0x11C'' uint32 [[M2/WotLK#Camera_lookup_table|ofsCameraLookup]] And lookup-time again.
''0x120'' uint32 nRibbonEmitters
''0x124'' uint32 [[M2/WotLK#Ribbon_emitters|ofsRibbonEmitters]] Things swirling around. See the CoT-entrance for light-trails.
''0x128'' uint32 nParticleEmitters
''0x12C'' uint32 [[M2/WotLK#Particle_emitters|ofsParticleEmitters]] Spells and weapons, doodads and loginscreens use them. Blood dripping of a blade? Particles.


{| style="background:#FCFCFC; color:black"
|
! width="70"| Offset
! width="70" | Type
! width="80" | Name
! width="500"| Description
|-
|||0x000 || char[4] || Magic || "MD20"
|-
|||0x004||uint32||Version||0x80100000 (first digit of the build the format was last updated)
|-
|||0x008||uint32||lName|| Length of the model's name
|-
|||0x00C||uint32||ofsName||Offset to the name
|-
|||0x010||uint32||GlobalModelFlags||(0,1,3 seen), connected to field 4 of [[CreatureModelData.dbc]]?
|-
|||0x014||uint32||nGlobalSequences
|-
|||0x018||uint32||[[M2/WotLK#Global_sequences|ofsGlobalSequences]]||A list of timestamps.
|-
|||0x01C||uint32||nAnimations
|-
|||0x020||uint32||[[M2/WotLK#Animation_sequences|ofsAnimations]]||Information about the animations in the model.
|-
|||0x024||uint32||nAnimationLookup
|-
|||0x028||uint32||[[M2/WotLK#Animation_Lookup|ofsAnimationLookup]]||Mapping of [[M2/WotLK#Animation_sequences|global IDs]] to the entries in the [[M2/WotLK#Animation_sequences|Animation sequences]] block.
|-
|||0x02C||uint32||nBones
|-
|||0x030||uint32||[[M2/WotLK#Bones|ofsBones]]||Information about the bones in this model.
|-
|||0x034||uint32||nKeyBoneLookup
|-
|||0x038||uint32||[[M2/WotLK#Key-Bone_Lookup|ofsKeyBoneLookup]]||Lookup table for key skeletal bones.
|-
|||0x03C||uint32||nVertices
|-
|||0x040||uint32||[[M2/WotLK#Vertices|ofsVertices]]||Vertices of the model.
|-
|||0x044||uint32||nViews||[[M2/WotLK#Views_.28LOD.29|Views (LOD)]] are now in [[M2/WotLK/.skin|.skins]].
|-
|||0x048||uint32||nColors
|-
|||0x04C||uint32||[[M2/WotLK#Colors|ofsColors]]|| Color definitions.
|-
|||0x050||uint32||nTextures
|-
|||0x054||uint32||[[M2/WotLK#Texture_definitions|ofsTextures]]||Textures of this model. Now .skins?
|-
|||0x058||uint32||nTransparency
|-
|||0x05C||uint32||[[M2/WotLK#Transparency|ofsTransparency]]||Transparency of textures.
|-
|||0x060||uint32||nTextureanimations
|-
|||0x064||uint32||[[M2/WotLK#Texture_animations|ofsTextureanimations]]
|-
|||0x068||uint32||nTexReplace
|-
|||0x06C||uint32||[[M2/WotLK#Replacable_texture_lookup|ofsTexReplace]]||Replaceable Textures.
|-
|||0x070||uint32||nRenderFlags
|-
|||0x074||uint32||[[M2/WotLK#Render_flags|ofsRenderFlags]]||Blending modes / render flags.
|-
|||0x078||uint32||nBoneLookupTable
|-
|||0x07C||uint32||[[M2/WotLK#Bone_Lookup_Table|ofsBoneLookupTable]]||A bone lookup table.
|-
|||0x080||uint32||nTexLookup
|-
|||0x084||uint32||[[M2/WotLK#Texture_lookup_table|ofsTexLookup]]||The same for textures.
|-
|||0x088||uint32||nTexUnits
|-
|||0x08C||uint32||[[M2/WotLK#Texture_unit_lookup_table|ofsTexUnits]]||And texture units. Somewhere they have to be too.
|-
|||0x090||uint32||nTransLookup
|-
|||0x094||uint32||[[M2/WotLK#Transparency_lookup_table|ofsTransLookup]]||Everything needs its lookup. Here are the transparencies.
|-
|||0x098||uint32||nTexAnimLookup
|-
|||0x09C||uint32||[[M2/WotLK#Texture_animation_lookup_table|ofsTexAnimLookup]]||Wait. Do we have animated Textures? Wasn't ofsTexAnims deleted? oO
|-
|||0x0A0||float||theFloats[14]||Noone knows. Meeh, they are here.
|-
|||0x0D8||uint32||nBoundingTriangles
|-
|||0x0DC||uint32||[[M2/WotLK#Triangles|ofsBoundingTriangles]]||Our bounding volumes. Similar structure like in the old ofsViews.
|-
|||0x0E0||uint32||nBoundingVertices
|-
|||0x0E4||uint32||[[M2/WotLK#Vertices_2|ofsBoundingVertices]]
|-
|||0x0E8||uint32||nBoundingNormals
|-
|||0x0EC||uint32||[[M2/WotLK#Normals|ofsBoundingNormals]]
|-
|||0x0F0||uint32||nAttachments
|-
|||0x0F4||uint32||[[M2/WotLK#Block_1|ofsAttachments]]||Attachments are for weapons etc.
|-
|||0x0F8||uint32||nAttachLookup
|-
|||0x0FC||uint32||[[M2/WotLK#Attachment_Lookup|ofsAttachLookup]]||Of course with a lookup.
|-
|||0x100||uint32||nAttachments_2
|-
|||0x104||uint32||[[M2/WotLK#Block_2|ofsAttachments_2]]||And some second block.
|-
|||0x108||uint32||nLights
|-
|||0x10C||uint32||[[M2/WotLK#Lights|ofsLights]]||Lights are mainly used in loginscreens but in wands and some doodads too.
|-
|||0x110||uint32||nCameras
|-
|||0x114||uint32||[[M2/WotLK#Cameras|ofsCameras]]||The cameras are present in most models for having a model in the Character-Tab.
|-
|||0x118||uint32||nCameraLookup
|-
|||0x11C||uint32||[[M2/WotLK#Camera_lookup_table|ofsCameraLookup]]||And lookup-time again.
|-
|||0x120||uint32||nRibbonEmitters
|-
|||0x124||uint32||[[M2/WotLK#Ribbon_emitters|ofsRibbonEmitters]]||Things swirling around. See the CoT-entrance for light-trails.
|-
|||0x128||uint32||nParticleEmitters
|-
|||0x12C||uint32||[[M2/WotLK#Particle_emitters|ofsParticleEmitters]]||Spells and weapons, doodads and loginscreens use them. Blood dripping of a blade? Particles.
|}
= Skeleton and animation =
= Skeleton and animation =


Line 91: Line 160:
A list of timestamps that act as upper limits for global sequence ranges.
A list of timestamps that act as upper limits for global sequence ranges.


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint32 Timestamp Entry
|
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x00||uint32||Timestamp||Entry
|}


==  Animation sequences ==
==  Animation sequences ==
Line 99: Line 175:
List of animations present in the model.  
List of animations present in the model.  


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 AnimationID Animation id in [[AnimationData.dbc]]
|
''0x02'' uint16 SubAnimationID Sub-animation id: Which number in a row of animations this one is.  
! width="70" | Offset
''0x04'' uint32 Length The length (timestamps) of the animation.
! width="70" | Type
''0x08'' float MovingSpeed As 2.x says: moving speed for walk/run animations.
! width="90" | Name
''0x0C'' uint32 Flags Most likely. All flags I saw: 0b01101101
! width="500"| Description
''0x10'' uint32 Flags 2 Only the first 4 bits are the actual flags. The rest is 1. Seen flags: 0,3,6,7
|-
''0x14'' uint32 Unknown 1 These two are connected. Most of the time, they are 0.
|||0x00||uint16||AnimationID||Animation id in [[AnimationData.dbc]]
''0x16'' uint32 Unknown 2 But if there is data in one, there is data in both of them.
|-
''0x1C'' uint32 PlaybackSpeed Values: 0, 50, 100, 150, 200, 250, 300, 350, 500.  
|||0x02||uint16||SubAnimationID||Sub-animation id: Which number in a row of animations this one is.  
''0x20'' float BoundingBox[6] A Bounding Box made out of 2 vectors.
|-
''0x38'' float Radius The radius.
|||0x04||uint32||Length||The length (timestamps) of the animation.
''0x3C'' int16 NextAnimation Id of the following animation of this AnimationID, points to an Index or is -1 if none.
|-
''0x3E'' uint16 Index Id in the list of animations.
|||0x08||float||MovingSpeed||As 2.x says: moving speed for walk/run animations.
|-
|||0x0C||uint32||Flags||Most likely. All flags I saw: 0b01101101
|-
|||0x10||uint32||Flags 2||Only the first 4 bits are the actual flags. The rest is 1. Seen flags: 0,3,6,7
|-
|||0x14||uint32||Unknown 1||These two are connected. Most of the time, they are 0.
|-
|||0x16||uint32||Unknown 2||But if there is data in one, there is data in both of them.
|-
|||0x1C||uint32||PlaybackSpeed||Values: 0, 50, 100, 150, 200, 250, 300, 350, 500.  
|-
|||0x20||float||BoundingBox[6]||A Bounding Box made out of 2 vectors.
|-
|||0x38||float||Radius||The radius.
|-
|||0x3C||int16||NextAnimation||Id of the following animation of this AnimationID, points to an Index or is -1 if none.
|-
|||0x3E||uint16||Index||Id in the list of animations.
|}


==  Animation Lookup ==
==  Animation Lookup ==
Line 119: Line 214:
Lookup table for Animations in [[AnimationData.dbc]].
Lookup table for Animations in [[AnimationData.dbc]].


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 AnimationID Index at [[M2/WotLK#Animation_sequences|ofsAnimations]] which represents the animation in [[AnimationData.dbc]]. -1 if none.
|
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x00||uint16||AnimationID||Index at [[M2/WotLK#Animation_sequences|ofsAnimations]] which represents the animation in [[AnimationData.dbc]]. -1 if none.
|}


==  Bones ==
==  Bones ==
*'''nBones records of 0x5C bytes starting at ofsBones.'''
*'''nBones records of 0x5C bytes starting at ofsBones.'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' int32 AnimationSeq Index into [[M2/WotLK#Animation_sequences|Animation sequences]] or -1.
|
''0x04'' uint32 Flags Only known flags: 8 - billborded and 512 - transformed
! width="70" | Offset
''0x08'' int16 ParentBone Parent bone ID or -1 if there is none.
! width="70" | Type
''0x0C'' uint16 GeosetID A geoset for this bone.
! width="90" | Name
''0x10'' int32 Unknown 4 bytes that have been in since TBC. Noone knows what they are for.
! width="500"| Description
''0x14'' [[M2/WotLK#Standard_animation_block|ABlock]] Translation An animationblock for translation. Should be 3*floats.
|-
''0x28'' [[M2/WotLK#Standard_animation_block|ABlock]] Rotation An animationblock for rotation. Should be 4*shorts, see [[Quaternion_values_and_2.x|Quaternion values and 2.x]].
|||0x00||int32||AnimationSeq||Index into [[M2/WotLK#Animation_sequences|Animation sequences]] or -1.
''0x3C'' [[M2/WotLK#Standard_animation_block|ABlock]] Scaling An animationblock for scaling. Should be 3*floats.
|-
''0x50'' float PivotPoint[3] The pivot point of that bone. Its a vector.
|||0x04||uint32||Flags||Only known flags: 8 - billborded and 512 - transformed
|-
|||0x08||int16||ParentBone||Parent bone ID or -1 if there is none.
|-
|||0x0C||uint16||GeosetID||A geoset for this bone.
|-
|||0x10||int32||Unknown||4 bytes that have been in since TBC. Noone knows what they are for.
|-
|||0x14||[[M2/WotLK#Standard_animation_block|ABlock]]||Translation||An animationblock for translation. Should be 3*floats.
|-
|||0x28||[[M2/WotLK#Standard_animation_block|ABlock]]||Rotation||An animationblock for rotation. Should be 4*shorts, see [[Quaternion_values_and_2.x|Quaternion values and 2.x]].
|-
|||0x3C||[[M2/WotLK#Standard_animation_block|ABlock]]||Scaling||An animationblock for scaling. Should be 3*floats.
|-
|||0x50||float||PivotPoint[3]||The pivot point of that bone. Its a vector.
|}


The bone indices in the vertex definitions seem to index into this data.
The bone indices in the vertex definitions seem to index into this data.
Line 146: Line 263:
Lookup table for bones that transform geometry. Referenced in the various geoset definitions.
Lookup table for bones that transform geometry. Referenced in the various geoset definitions.


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 Bone Which bone. -1 if there is none.  
|
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x00||uint16||Bone||Which bone. -1 if there is none.
|}


== Key-Bone Lookup ==
== Key-Bone Lookup ==
Line 153: Line 277:
Its a lookup table for key skeletal bones like hands, arms, legs, etc. nKeyBoneLookup is 21 for the most models. At static models it is mostly 1.
Its a lookup table for key skeletal bones like hands, arms, legs, etc. nKeyBoneLookup is 21 for the most models. At static models it is mostly 1.


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 Bone Which bone. -1 if there is none.  
|
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x00||uint16||Bone||Which bone. -1 if there is none.
|}


=  Geometry and rendering =
=  Geometry and rendering =
Line 161: Line 292:
*'''nVertices entries of 48 bytes per vertex (at ofsVertices)'''
*'''nVertices entries of 48 bytes per vertex (at ofsVertices)'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' float Position[3] A vector to the position of the vertex.
|
''0x0C'' uint8 BoneWeight[4] The vertex weight for 4 bones.
! width="70" | Offset
''0x10'' uint8 BoneIndices[4] Which are referenced here.
! width="70" | Type
''0x14'' float Normal[3] A normal vector.
! width="90" | Name
''0x20'' float TextureCoords[2] Coordinates for a texture.
! width="500"| Description
''0x28'' float Unknown[2] Null?
|-
|||0x00||float||Position[3]||A vector to the position of the vertex.
|-
|||0x0C||uint8||BoneWeight[4]||The vertex weight for 4 bones.
|-
|||0x10||uint8||BoneIndices[4]||Which are referenced here.
|-
|||0x14||float||Normal[3]||A normal vector.
|-
|||0x20||float||TextureCoords[2]||Coordinates for a texture.
|-
|||0x28||float||Unknown[2]||Null?
|}


Models, too, use a Z-up coordinate systems, so in order to convert to Y-up, the X, Y, Z values become (X, -Z, Y).
Models, too, use a Z-up coordinate systems, so in order to convert to Y-up, the X, Y, Z values become (X, -Z, Y).
Line 181: Line 324:
*'''nRenderFlags (uint16, uint16) pairs starting at ofsRenderFlags'''
*'''nRenderFlags (uint16, uint16) pairs starting at ofsRenderFlags'''


'''Offset Description'''
{| style="background:#FCFCFC; color:black"
0x00 Flags
|
0x02 Blending mode
! width="70" | Offset
! width="200"| Description
|-
|||0x00||Flags
|-
|||0x02||Blending mode
|}
 


*'''Flags:'''
*'''Flags:'''
'''Flag Meaning'''
 
0x01 Unlit
{| style="background:#FCFCFC; color:black"
0x02 Unfogged?
|
0x04 Two-sided (no backface culling if set)
! width="70" | Flag
0x08 ? (probably billboarded)
! width="300"| Meaning
0x10 Disable z-buffer?
|-
||| 0x01 ||Unlit
|-
||| 0x02||Unfogged?
|-
|||0x04||Two-sided (no backface culling if set)
|-
|||0x08||? (probably billboarded)
|-
|||0x10||Disable z-buffer?
|}


*'''Blending mode'''
*'''Blending mode'''
'''Value Meaning'''
{| style="background:#FCFCFC; color:black"
0 Opaque
|
1 Alpha testing only
! width="70" | Value
2 Alpha blending
! width="300"| Meaning
3 Additive?
|-
4 Additive alpha?
||| 0|| Opaque
5 Modulate?
|-
6 Used in the Deeprun Tram subway glass, supposedly (src=dest_color, dest=src_color) (?)
||| 1|| Alpha testing only
 
|-
||| 2 ||Alpha blending
|-
||| 3 ||Additive?
|-
||| 4 ||Additive alpha?
|-
||| 5 ||Modulate?
|-
||| 6 || Used in the Deeprun Tram subway glass, supposedly (src=dest_color, dest=src_color) (?)
|}
''Most of these blend values are taken from the MDL docs, but they sort of work (like additive blending for light shafts and such)''
''Most of these blend values are taken from the MDL docs, but they sort of work (like additive blending for light shafts and such)''


Line 208: Line 378:
*'''nTexUnits 16-bit integers starting at ofsTexUnits.'''
*'''nTexUnits 16-bit integers starting at ofsTexUnits.'''


  '''Offset Type Name Description'''
  {|style="background:#FCFCFC; color:black"
''0x00'' int16 Unit Values are -1, 0 or 1. See below.
|
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x00||int16||Unit||Values are -1, 0 or 1. See below.
|}


For models that use multitexturing, this maps given texture unit numbers into actual texture unit numbers (0 or 1).
For models that use multitexturing, this maps given texture unit numbers into actual texture unit numbers (0 or 1).
Line 224: Line 401:
*'''nTexReplace 16-bit integers starting at ofsTexReplace.'''
*'''nTexReplace 16-bit integers starting at ofsTexReplace.'''


  '''Offset Type Name Description'''
 
''0x00'' uint16 TextureID Array indices (0 to n-1).
  {|style="background:#FCFCFC; color:black"
|
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| 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.
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.
Line 234: Line 420:
*'''nColors records starting at ofsColors, followed by data referenced in these records.'''
*'''nColors records starting at ofsColors, followed by data referenced in these records.'''


  '''Offset Type Name Description'''
  {|style="background:#FCFCFC; color:black"
''0x00'' [[M2/WotLK#Standard_animation_block|ABlock]] Color Three floats. One for each color.
|
''0x14'' [[M2/WotLK#Standard_animation_block|ABlock]] Alpha A short for the alpha value. 0 - transparent, 0xFFFF - opaque.
! width="70" | Offset
 
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x00||[[M2/WotLK#Standard_animation_block|ABlock]]||Color||Three floats. One for each color.
|-
|||0x14||[[M2/WotLK#Standard_animation_block|ABlock]]||Alpha||A short for the alpha value. 0 - transparent, 0xFFFF - opaque.
|}
For some swirling portals and volumetric lights, these define vertex colors. Referenced from the Texture Unit blocks in the LOD part. Contains a separate timeline for transparency values. If no animation is used, the given value is constant.
For some swirling portals and volumetric lights, these define vertex colors. Referenced from the Texture Unit blocks in the LOD part. Contains a separate timeline for transparency values. If no animation is used, the given value is constant.


Line 243: Line 436:
*'''nTransLookup 16-bit integers starting at ofsTransLookup.'''
*'''nTransLookup 16-bit integers starting at ofsTransLookup.'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 TransparencyId Array indices (0 to n-1).
|
 
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x00||uint16||TransparencyId||Array indices (0 to n-1).
|}
Contains indices into the Transparency block. Used by the texture unit definitions in the LOD block.
Contains indices into the Transparency block. Used by the texture unit definitions in the LOD block.


Line 251: Line 450:
*'''nTransparency AnimationBlocks at ofsTransparency, followed by data referenced in these records.
*'''nTransparency AnimationBlocks at ofsTransparency, followed by data referenced in these records.


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x10'' [[M2/WotLK#Standard_animation_block|ABlock]] Alpha A short for the alpha value. 0 - transparent, 0xFFFF - opaque.
|
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x10||[[M2/WotLK#Standard_animation_block|ABlock]]||Alpha||A short for the alpha value. 0 - transparent, 0xFFFF - opaque.
|}


Specifies global transparency values in addition to the values given in the Color block. I assume these are multiplied together eventually.
Specifies global transparency values in addition to the values given in the Color block. I assume these are multiplied together eventually.
Line 263: Line 469:
*'''nTexLookup items starting at ofsTexLookup.'''
*'''nTexLookup items starting at ofsTexLookup.'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 TextureId Array indices (0 to n-1).
|
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x00||uint16||TextureId||Array indices (0 to n-1).
|}


===Texture definitions ===
===Texture definitions ===
*'''First is a list of nTextures texture definition records, 16 bytes per record, starting at ofsTextures.''' After it comes a zero-padded string block with the texture filenames which are referenced in the block if the texture is hardcoded.
*'''First is a list of nTextures texture definition records, 16 bytes per record, starting at ofsTextures.'''  


'''Offset Type Name Description'''
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.
  ''0x000'' uint32 Type The type of the texture. See below.
 
''0x002'' uint16 Unknown What do I know? Most likely just padding.
{| style="background:#FCFCFC; color:black"
''0x004'' uint16 Flags Textures have some flags. See below too.
|-
''0x008'' uint32 lenFilename If the Type is "0 - hardcoded" then here is the length.
! width="70" | Offset
''0x00C'' uint32 ofsFilename And the offset to the filename.
! width="70" | Type  
! width="90" | Name  
! width="500" | Description
|-
| 0x000 || uint32|| Type || The type of the texture. See below.
|-
| 0x002 || uint16|| Unknown || What do I know? Most likely just padding.
|-
|0x004||uint16||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 Types====
Line 284: Line 510:
*(possibly more)
*(possibly more)


'''Value Meaning'''
0 Texture given in filename
1 Body + clothes
2 Cape
6 Hair, beard
8 Tauren fur
11 Skin for creatures #1
12 Skin for creatures #2
13 Skin for creatures #3


{|style="background:#FCFCFC; color:black"
|
! width="70" | Value
! width="200"| Meaning
|-
||| 0|| Texture given in filename
|-
||| 1|| Body + clothes
|-
||| 2||Cape
|-
||| 6 ||Hair, beard
|-
||| 8||Tauren fur
|-
||| 11||Skin for creatures #1
|-
||| 12||Skin for creatures #2
|-
||| 13||Skin for creatures #3
|}
====Flags====
====Flags====
'''Value Meaning'''
{|style="background:#FCFCFC; color:black"
1 Texture wrap X
|
2 Texture wrap Y
! width="70" | Value
 
! width="200"| Meaning
|-
||| 1||Texture wrap X
|-
||| 2||Texture wrap Y
|}
===Texture animation lookup table ===
===Texture animation lookup table ===
*'''nTexAnimLookup items starting at ofsTexAnimLookup.'''
*'''nTexAnimLookup items starting at ofsTexAnimLookup.'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 AnimatedTextureId Array indices (0 to n-1). -1 for a static texture.
|
 
! width="70" | Offset
! width="70" | Type
! width="90" | Name
! width="500"| Description
|-
|||0x00||uint16||AnimatedTextureId||Array indices (0 to n-1). -1 for a static texture.
|}
=== Texture animations ===
=== Texture animations ===
*'''This block contains definitions for texture animations,''' for example, flowing water or lava in some models. The keyframe values are used in the texture transform matrix.
*'''This block contains definitions for texture animations,''' for example, flowing water or lava in some models. The keyframe values are used in the texture transform matrix.


nTexAnims records of 0x54 bytes starting at ofsTexAnims, followed by data referenced in these records.
nTexAnims records of 0x54 bytes starting at ofsTexAnims, followed by data referenced in these records.
'''Offset Type Description'''
{|style="background:#FCFCFC; color:black"
0x00 AnimationBlock (float, float, float) Translation
|
0x1C AnimationBlock (float, float, float ???) Rotation?
! width="70" | Offset
0x38 AnimationBlock (float, float, float) Scaling?
! width="120" | Type
 
! width="500"| Description
|-
|||0x00|| AnimationBlock (float, float, float)||Translation
|||0x1C|| AnimationBlock (float, float, float ???)||Rotation?
|||0x38|| AnimationBlock (float, float, float)||Scaling?
|}
The three subrecords specify texture transforms. Translation seems to work, producing nice flowing lava and waterfalls.
The three subrecords specify texture transforms. Translation seems to work, producing nice flowing lava and waterfalls.


Line 322: Line 576:


The records have the following structure:
The records have the following structure:
'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint32 Unknown Always (as I have seen): -1.
|
''0x04'' uint32 BoneID A bone to attach to.
! width="70" | Offset
''0x08'' float Position[3] And a position, relative to that bone.
! width="90" | Type
''0x14'' int32 nTextures Number of referenced textures.
! width="120"|Name
''0x18'' int32 ofsTextures Offset to the referenced textures.
! width="500"| Description
''0x1C'' int32 nUnkRef Number of some referenced integers.
|-
''0x20'' int32 ofsUnkRef Offset to the integers.
|||0x00|| uint32||Unknown ||Always (as I have seen): -1.
''0x24'' [[M2/WotLK#Standard_animation_block|ABlock]] Color A color in three floats.
|-
''0x38'' [[M2/WotLK#Standard_animation_block|ABlock]] Opacity And an alpha value in a short, where: 0 - transparent, 0xFFFF - opaque.
|||0x04|| uint32 ||BoneID || A bone to attach to.
''0x4C'' [[M2/WotLK#Standard_animation_block|ABlock]] Above The height above.  
|-
''0x60'' [[M2/WotLK#Standard_animation_block|ABlock]] Below The height below. Do not set these to the same!
|||0x08||float||Position[3]|| And a position, relative to that bone.
''0x74'' float Resolution This defines how smooth the ribbon is. A low value may produce a lot of edges.
|-
''0x78'' float Length The length aka Lifespan.
|||0x14|| int32|| nTextures|| Number of referenced textures.
''0x7C'' float UnknownFloat Usually 0
|-
''0x80'' short UnknownShorts[2] Maybe these are blending modes. Pairs of {1,1} for example.
|||0x18|| int32|| ofsTextures|| Offset to the referenced textures.
''0x84'' [[M2/WotLK#Standard_animation_block|ABlock]] UnknownABlock1 The value on these two are integers. First one is 0 all the time.
|-
''0x98'' [[M2/WotLK#Standard_animation_block|ABlock]] UnknownABlock2 And the second one is 1.
|||0x1C|| int32|| nUnkRef ||Number of some referenced integers.
 
|-
|||0x20|| int32|| ofsUnkRef|| Offset to the integers.
|-
|||0x24|| [[M2/WotLK#Standard_animation_block|ABlock]]||Color||A color in three floats.
|-
|||0x38|| [[M2/WotLK#Standard_animation_block|ABlock]]||Opacity|| And an alpha value in a short, where: 0 - transparent, 0xFFFF - opaque.
|-
|||0x4C|| [[M2/WotLK#Standard_animation_block|ABlock]] ||Above||The height above.  
|-
|||0x60|| [[M2/WotLK#Standard_animation_block|ABlock]]||Below||The height below. Do not set these to the same!
|-
|||0x74|| float||Resolution||This defines how smooth the ribbon is. A low value may produce a lot of edges.
|-
|||0x78|| float|| Length || The length aka Lifespan.
|-
|||0x7C|| float|| UnknownFloat|| Usually 0
|-
|||0x80|| short|| UnknownShorts[2]||Maybe these are blending modes. Pairs of {1,1} for example.
|-
|||0x84|| [[M2/WotLK#Standard_animation_block|ABlock]]||UnknownABlock1||The value on these two are integers. First one is 0 all the time.
|-
|||0x98|| [[M2/WotLK#Standard_animation_block|ABlock]]|| UnknownABlock2|| And the second one is 1.
|}
Some models that contain ribbon emitters and are viewable in the game world are: Wisps in BFD, Al'ar the Phoenix in Tempest Keep and any other phoenix models and the energy trails in the COT (not the actual instance, but the entrance cave in Tanaris Desert). Other models with ribbon emitters are spells and effects.
Some models that contain ribbon emitters and are viewable in the game world are: Wisps in BFD, Al'ar the Phoenix in Tempest Keep and any other phoenix models and the energy trails in the COT (not the actual instance, but the entrance cave in Tanaris Desert). Other models with ribbon emitters are spells and effects.


Line 348: Line 624:
*'''nParticleEmitters records starting at ofsParticleEmitters, followed by data referenced in these records.'''
*'''nParticleEmitters records starting at ofsParticleEmitters, followed by data referenced in these records.'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x000'' uint32 Unknown Always (as I have seen): -1.
|
''0x004'' uint32 Flags There are more flags now. Known: 0x1000  - do not billboard.
! width="70" | Offset
''0x008'' float Position[3] The position. Relative to the following bone.
! width="90" | Type
''0x014'' uint16 Bone The [[M2/WotLK#Bones|bone]] its attached to.
! width="120" |Name
''0x016'' uint16 Texture And the [[M2/WotLK#Texture_definitions|texture]] that is used.
! width="500"| Description
''0x018'' uint32 nReferences1 The first number of integers referenced.
|-
''0x01C'' uint32 ofsReferences1 And the matching offset.
|||0x000||uint32||Unknown|| Always (as I have seen): -1.
''0x020'' uint32 nReferences2 The second number of integers referenced.
|-
''0x024'' uint32 ofsReferences2 And the matching offset again.
|||0x004|| uint32||Flags|| There are more flags now. Known: 0x1000  - do not billboard.
''0x028'' uint8 BlendingType A blending type for the particle. Maybe the same as at the renderflags.
|-
''0x029'' uint16 EmitterType 1 - Plane (rectangle), 2 - Sphere, 3 - Spline? (can't be bothered to find one)
|||0x008|| float||Position[3]|| The position. Relative to the following bone.
''0x02B'' uint16 ParticleType Found below.
|-
''0x02D'' uint8 Padding
|||0x014|| uint16||Bone|| The [[M2/WotLK#Bones|bone]] its attached to.
''0x02E'' uint16 TextureTileRotation Rotation for the texture tile. (Values: -1,0,1)
|-
''0x030'' uint16 TextureRows How many different frames are on that texture? People should learn what rows and cols are.
|||0x016|| uint16||Texture || And the [[M2/WotLK#Texture_definitions|texture]] that is used.
''0x032'' uint16 TextureCols Its different everywhere. I just took it random.  
|-
''0x034'' [[M2/WotLK#Standard_animation_block|ABlock]] EmissionSpeed All of the following blocks should be floats.
|||0x018|| uint32||nReferences1 ||The first number of integers referenced.
''0x048'' [[M2/WotLK#Standard_animation_block|ABlock]] SpeedVariation Variation in the flying-speed. (range: 0 to 1)
|-
''0x05C'' [[M2/WotLK#Standard_animation_block|ABlock]] VerticalRange Drifting away vertically. (range: 0 to pi)
|||0x01C|| uint32||ofsReferences1|| And the matching offset.
''0x070'' [[M2/WotLK#Standard_animation_block|ABlock]] HorizontalRange They can do it horizontally too! (range: 0 to 2*pi)
|-
''0x084'' [[M2/WotLK#Standard_animation_block|ABlock]] Gravity Fall down, apple!
|||0x020|| uint32||nReferences2|| The second number of integers referenced.
''0x098'' [[M2/WotLK#Standard_animation_block|ABlock]] Lifespan Everyone has to die.
|-
''0x0AC'' uint32 unknownPadding I don't know what these two values should do..
|||0x024|| uint32||ofsReferences2 ||And the matching offset again.
''0x0B0'' [[M2/WotLK#Standard_animation_block|ABlock]] EmissionRate Stread your particles, emitter.
|-
''0x0C4'' uint32 unknownPadding2 It could have been an array without them..
|||0x028|| uint8||BlendingType|| A blending type for the particle. Maybe the same as at the renderflags.
''0x0C8'' [[M2/WotLK#Standard_animation_block|ABlock]] EmissionAreaLength Well, you can do that in this area.
|-
''0x0DC'' [[M2/WotLK#Standard_animation_block|ABlock]] EmissionAreaWidth
|||0x029|| uint16||EmitterType|| 1 - Plane (rectangle), 2 - Sphere, 3 - Spline? (can't be bothered to find one)
''0x0F0'' [[M2/WotLK#Standard_animation_block|ABlock]] Gravity2 A second gravity? Its strong.
|-
''0x104'' [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] ParticleColor This one points to 3 floats defining red, green and blue.
|||0x02B|| uint16||ParticleType|| Found below.
''0x114'' [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] ParticleOpacity? Looks like opacity (short) --Igor; Most likely they all have 3 timestamps for {start, middle, end}.
|-
''0x124'' [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] ParticleSizes It carries two floats per key. (x and y scale)
|||0x02D|| uint8||Padding
''0x134'' int32 UnknownFields[10] Always 0 as far as I see. Indices into the tiles on the texture?
|-
''0x15C'' float UnknownFloats1[3] They have something to do with the spread.
|||0x02E|| uint16||TextureTileRotation||Rotation for the texture tile. (Values: -1,0,1)
''0x168'' float Scale[3] Wheey, its the scale!
|-
''0x174'' float Slowdown Slowpoke is slow.
|||0x030|| uint16||TextureRows|| How many different frames are on that texture? People should learn what rows and cols are.
''0x178'' float UnknownFloats2[2] More unknown fields.
|-
''0x180'' float Rotation As a single value? Most likely only one axis then..
|||0x032|| uint16||TextureCols|| Its different everywhere. I just took it random.  
''0x184'' float UnknownFloats3[2] More unknown fields.
|-
''0x18C'' float Rot1[3]                 Model Rotation 1  
|||0x034|| [[M2/WotLK#Standard_animation_block|ABlock]] ||EmissionSpeed|| All of the following blocks should be floats.
''0x198'' float Rot2[3]                 Model Rotation 2
|-
''0x1A4'' float Trans[3]               Model Translation
|||0x048|| [[M2/WotLK#Standard_animation_block|ABlock]] ||SpeedVariation|| Variation in the flying-speed. (range: 0 to 1)
''0x1B0'' float UnknownFloats4[6] Unknown, unknown, unknown, unknown, unknown...
|-
''0x1C8'' [[M2/WotLK#Standard_animation_block|ABlock]] EnabledIn Maybe this has integers again. Has been in the earlier documentations. Enabled Anim Block.
|||0x05C|| [[M2/WotLK#Standard_animation_block|ABlock]] ||VerticalRange|| Drifting away vertically. (range: 0 to pi)
 
|-
|||0x070|| [[M2/WotLK#Standard_animation_block|ABlock]] ||HorizontalRange|| They can do it horizontally too! (range: 0 to 2*pi)
|-
|||0x084|| [[M2/WotLK#Standard_animation_block|ABlock]] ||Gravity|| Fall down, apple!
|-
|||0x098|| [[M2/WotLK#Standard_animation_block|ABlock]] ||Lifespan|| Everyone has to die.
|-
|||0x0AC|| uint32 ||unknownPadding || I don't know what these two values should do..
|-
|||0x0B0|| [[M2/WotLK#Standard_animation_block|ABlock]] ||EmissionRate|| Stread your particles, emitter.
|-
|||0x0C4|| uint32 ||unknownPadding2 ||It could have been an array without them..
|-
|||0x0C8|| [[M2/WotLK#Standard_animation_block|ABlock]] ||EmissionAreaLength||Well, you can do that in this area.
|-
|||0x0DC|| [[M2/WotLK#Standard_animation_block|ABlock]] ||EmissionAreaWidth
|-
|||0x0F0|| [[M2/WotLK#Standard_animation_block|ABlock]] ||Gravity2|| A second gravity? Its strong.
|-
|||0x104|| [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] ||ParticleColor|| This one points to 3 floats defining red, green and blue.
|-
|||0x114|| [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] ||ParticleOpacity?||Looks like opacity (short) --Igor; Most likely they all have 3 timestamps for {start, middle, end}.
|-
|||0x124|| [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] ||ParticleSizes|| It carries two floats per key. (x and y scale)
|-
|||0x134|| int32 ||UnknownFields[10]||Always 0 as far as I see. Indices into the tiles on the texture?
|-
|||0x15C|| float ||UnknownFloats1[3]||They have something to do with the spread.
|-
|||0x168|| float ||Scale[3]|| Wheey, its the scale!
|-
|||0x174|| float ||Slowdown|| Slowpoke is slow.
|-
|||0x178|| float ||UnknownFloats2[2]||More unknown fields.
|-
|||0x180|| float ||Rotation|| As a single value? Most likely only one axis then..
|-
|||0x184|| float ||UnknownFloats3[2]||More unknown fields.
|-
|||0x18C|| float ||Rot1[3]||Model Rotation 1  
|-
|||0x198|| float ||Rot2[3]||Model Rotation 2
|-
|||0x1A4|| float ||Trans[3]||Model Translation
|-
|||0x1B0|| float ||UnknownFloats4[6]||Unknown, unknown, unknown, unknown, unknown...
|-
|||0x1C8|| [[M2/WotLK#Standard_animation_block|ABlock]] ||EnabledIn||Maybe this has integers again. Has been in the earlier documentations. Enabled Anim Block.
|}
About Slowdown: For a non-zero values, instead of travelling linearly the particles seem to slow down sooner. I can't work out the exact function but for a value of, say, 10, the particles pretty much stay in place. Not the same effect as gravity, though. Speed is multiplied by exp( -slowdown * t ).
About Slowdown: For a non-zero values, instead of travelling linearly the particles seem to slow down sooner. I can't work out the exact function but for a value of, say, 10, the particles pretty much stay in place. Not the same effect as gravity, though. Speed is multiplied by exp( -slowdown * t ).


Line 400: Line 724:


===Particle types===
===Particle types===
'''Value Description'''
{|style="background:#FCFCFC; color:black"
  0 "normal" particle
|
1 large quad from the particle's origin to its position (used in Moonwell water effects)
! width="70" | Value
2 seems to be the same as 0 (found some in the Deeprun Tram blinky-lights-sign thing)
! width="200"| Description
|-
  |||0|| "normal" particle
|-
||| 1 ||large quad from the particle's origin to its position (used in Moonwell water effects)
|-
||| 2||seems to be the same as 0 (found some in the Deeprun Tram blinky-lights-sign thing)
|}


''ParticleType is always 0 and, maybe, now (Flags & 0x40000) != 0 means "particles from origin to position". --Igor''   
''ParticleType is always 0 and, maybe, now (Flags & 0x40000) != 0 means "particles from origin to position". --Igor''   
Line 409: Line 740:
===The Fake-AnimationBlock===
===The Fake-AnimationBlock===
*Its pretty much like the real one but without the "header".
*Its pretty much like the real one but without the "header".
'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x000'' uint32 nTimestamps The number of timestamps.
|
''0x004'' uint32 ofsTimestamps And the offset to them.
! width="70" | Offset
''0x008'' uint32 nKeys The same number again. This time its the number of Keys / Values.
! width="90" | Type
''0x00C'' uint32 ofsKeys And their offset.
! width="120"| Name
 
! width="500"| Description
|-
|||0x000||uint32||nTimestamps|| The number of timestamps.
|-
|||0x004||uint32||ofsTimestamps|| And the offset to them.
|-
|||0x008||uint32||nKeys|| The same number again. This time its the number of Keys / Values.
|-
|||0x00C||uint32||ofsKeys|| And their offset.
|}
=Miscellaneous=
=Miscellaneous=


Line 423: Line 763:
===Vertices===
===Vertices===
*'''nBoundingVertices vertices at ofsBoundingVertices'''.
*'''nBoundingVertices vertices at ofsBoundingVertices'''.
 
{|style="background:#FCFCFC; color:black"
'''Offset Type Name Description'''
|
''0x00'' float Coordinate[3] This defines a vertex in x,y and z values.
! width="70" | Offset
 
! width="90" | Type
! width="120"| Name
! width="500"| Description
|-
|||0x00||float||Coordinate[3]|| This defines a vertex in x,y and z values.
|}
===Triangles===
===Triangles===
*'''nBoundingTriangles triples of uint16s at ofsBoundingTriangles'''.
*'''nBoundingTriangles triples of uint16s at ofsBoundingTriangles'''.


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 Index[3] Specifies three vertices of the list above to build a triangle.
|
! width="70" | Offset
! width="90" | Type
! width="120"| Name
! width="500"| Description
|-
|||0x00||uint16||Index[3]||Specifies three vertices of the list above to build a triangle.
|}
The number nBoundingTriangles once again contains the number of indices used, so divide by 3 to get the number of triangles.
The number nBoundingTriangles once again contains the number of indices used, so divide by 3 to get the number of triangles.
Line 438: Line 790:
*'''nBoundingNormals normals at ofsBoundingNormals'''.
*'''nBoundingNormals normals at ofsBoundingNormals'''.


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' float Vector[3] This defines the normal for each vertex.  
|
 
! width="70" | Offset
! width="90" | Type
! width="120"| Name
! width="500"| Description
|-
|||0x00|||float||Vector[3]||This defines the normal for each vertex.  
|}
Each vertex also has a corresponding normal vector. Therefore, it should be true that nBoundingVertices = nBoundingNormals = nBoundingTriangles / 3.
Each vertex also has a corresponding normal vector. Therefore, it should be true that nBoundingVertices = nBoundingNormals = nBoundingTriangles / 3.


Line 447: Line 805:


The records have the following structure:
The records have the following structure:
'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 Type Types are listed below.
|
  ''0x02'' int16 Bone If its attached to a bone, this is the bone. Else here is a nice -1.
! width="70" | Offset
  ''0x04'' float Position[3] Where is this light?
! width="90" | Type
''0x10'' [[M2/WotLK#Standard_animation_block|ABlock]] AmbientColor The ambient color. Three floats for RGB.
! width="120"| Name
''0x24'' [[M2/WotLK#Standard_animation_block|ABlock]] AmbientIntensity A float for the intensity.
! width="500"| Description
''0x38'' [[M2/WotLK#Standard_animation_block|ABlock]] DiffuseColor The diffuse color. Three floats for RGB.
|-
''0x4C'' [[M2/WotLK#Standard_animation_block|ABlock]] DiffuseIntensity A float for the intensity again.
||| ''0x00''|| uint16|| Type|| Types are listed below.
''0x60'' [[M2/WotLK#Standard_animation_block|ABlock]] AttenuationStart This defines, where the light starts to be.
|-
''0x74'' [[M2/WotLK#Standard_animation_block|ABlock]] AttenuationEnd And where it stops.
||| ''0x02''|| int16|| Bone || If its attached to a bone, this is the bone. Else here is a nice -1.
''0x88'' [[M2/WotLK#Standard_animation_block|ABlock]] Unknown Its an integer and usually 1.
|-
||| ''0x04''|| float|| Position[3] || Where is this light?
|-
||| ''0x10''|| [[M2/WotLK#Standard_animation_block|ABlock]]|| AmbientColor || The ambient color. Three floats for RGB.
|-
||| ''0x24''|| [[M2/WotLK#Standard_animation_block|ABlock]]|| AmbientIntensity|| A float for the intensity.
|-
||| ''0x38''|| [[M2/WotLK#Standard_animation_block|ABlock]]|| DiffuseColor || The diffuse color. Three floats for RGB.
|-
||| ''0x4C'' ||[[M2/WotLK#Standard_animation_block|ABlock]]|| DiffuseIntensity|| A float for the intensity again.
|-
||| ''0x60''|| [[M2/WotLK#Standard_animation_block|ABlock]]|| AttenuationStart|| This defines, where the light starts to be.
|-
||| ''0x74''|| [[M2/WotLK#Standard_animation_block|ABlock]]|| AttenuationEnd || And where it stops.
|-
||| ''0x88''|| [[M2/WotLK#Standard_animation_block|ABlock]]|| Unknown || Its an integer and usually 1.
|}


Two light types:
Two light types:
'''Value Description'''
{|style="background:#FCFCFC; color:black"
0 Directional
|
1 Point light
! width="70" | Value
! width="200"| Description
|-
||| 0 || Directional
|-
|||1 || Point light
|}


==  Cameras ==
==  Cameras ==
*'''nCameras records of 0x64 bytes starting at ofsCameras, followed by data referenced in these records.'''
*'''nCameras records of 0x64 bytes starting at ofsCameras, followed by data referenced in these records.'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint32 BoneID -1 if attached to none? Its also documented as id elsewhere.
|
''0x04'' float FOV No radians, no degrees. Multiply by 35 to get degrees.
! width="70" | Offset
''0x08'' float FarClipping Where it stops to be drawn.
! width="90" | Type
''0x0C'' float NearClipping Far and near. Both of them.
! width="120"| Name
''0x10'' [[M2/WotLK#Standard_animation_block|ABlock]] TranslationPos How the cameras position moves. Should be 3*floats.
! width="500"| Description
''0x24'' float Position[3] Where the camera is located.
|-
''0x30'' [[M2/WotLK#Standard_animation_block|ABlock]] TranslationTar How the target moves. Should be 3*floats.
||| ''0x00''|| uint32 ||BoneID || -1 if attached to none? Its also documented as id elsewhere.
''0x44'' float Target[3] Where the camera points to.
|-
''0x50'' [[M2/WotLK#Standard_animation_block|ABlock]] Scaling The camera can have some roll-effect. Its 0 to 2*Pi.
||| ''0x04''|| float|| FOV || No radians, no degrees. Multiply by 35 to get degrees.
 
|-
||| ''0x08''|| float|| FarClipping || Where it stops to be drawn.
|-
||| ''0x0C''|| float|| NearClipping || Far and near. Both of them.
|-
||| ''0x10'' || [[M2/WotLK#Standard_animation_block|ABlock]] || TranslationPos || How the cameras position moves. Should be 3*floats.
|-
||| ''0x24''|| float|| Position[3] || Where the camera is located.
|-
||| ''0x30'' || [[M2/WotLK#Standard_animation_block|ABlock]] || TranslationTar || How the target moves. Should be 3*floats.
|-
||| ''0x44''|| float|| Target[3] || Where the camera points to.
|-
||| ''0x50''|| [[M2/WotLK#Standard_animation_block|ABlock]] || Scaling || The camera can have some roll-effect. Its 0 to 2*Pi.
|}
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.
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.


Line 483: Line 877:
*'''nCameraLookup 16-bit integers starting at ofsCameraLookup.'''
*'''nCameraLookup 16-bit integers starting at ofsCameraLookup.'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 CameraId All cameras. Array indices (0 to n-1).
|
 
! width="70" | Offset
! width="90" | Type
! width="120"| Name
! width="500"| Description
|-
||| ''0x00''|| uint16||CameraId|| All cameras. Array indices (0 to n-1).
|}
= Attachments =
= Attachments =
== Block 1 ==
== Block 1 ==
*'''nAttachments records of the following structure starting at ofsAttachments, followed by data referenced in these records.'''
*'''nAttachments records of the following structure starting at ofsAttachments, followed by data referenced in these records.'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint32 Id Just an id. Is referenced in the [[M2\WotLK#Attachment_Lookup|lookup-block]] below too.
|
  ''0x04'' uint32 Bone Somewhere it has to be attached.
! width="70" | Offset
  ''0x08'' float Position[3] Relative to that bone of course.
! width="90" | Type
  ''0x14'' [[M2/WotLK#Standard_animation_block|ABlock]] Data Its an integer in the data. It has been 1 on all models I saw. Whatever.
! width="120"| Name
! width="500"| Description
|-
||| ''0x00''|| uint32|| Id || Just an id. Is referenced in the [[M2\WotLK#Attachment_Lookup|lookup-block]] below too.
  |-
||| ''0x04''|| uint32 || Bone || Somewhere it has to be attached.
|-
||| ''0x08''|| float|| Position[3] || Relative to that bone of course.
|-
||| ''0x14'' || [[M2/WotLK#Standard_animation_block|ABlock]] || Data || Its an integer in the data. It has been 1 on all models I saw. Whatever.
|}


This block specifies a bunch of locations on the body - hands, shoulders, head, back, knees etc. It is used to put items on a character. This seems very likely as this block also contains positions for sheathed weapons, a shield, etc.
This block specifies a bunch of locations on the body - hands, shoulders, head, back, knees etc. It is used to put items on a character. This seems very likely as this block also contains positions for sheathed weapons, a shield, etc.


Here's the list of position slots (by ID, or index in block P) for character models:
Here's the list of position slots (by ID, or index in block P) for character models:
'''ID Description ID Description ID Description'''
{|style="background:#FCFCFC; color:black"
0 Left wrist / Mountpoint 12 Back 24 -
|
1 Right palm 13 - 25 -
! width="50" | ID
2 Left palm 14 - 26 Right back sheath
! width="150" | Description
3 Right elbow 15 Bust 27 Left back sheath
! width="50" | ID
4 Left elbow 16 Bust 28 Middle back sheath
! width="150" | Description
5 Right shoulder 17 Face 29 Belly
! width="50" | ID
6 Left shoulder 18 Above character 30 Left back
! width="150" | Description
7 Right knee 19 Ground 31 Right back
|-
8 Left knee 20 Top of head 32 Left hip sheath
||| 0 || Left wrist / Mountpoint || 12 || Back || 24 || -
9 - 21 Left palm 33 Right hip sheath
|-
10 - 22 Right palm 34 Bust
||| 1 || Right palm || 13 || - || 25 || -
11 Helmet 23 - 35 Right palm
|-
 
||| 2 || Left palm || 14 || - || 26 || Right back sheath
|-
||| 3 || Right elbow || 15 || Bust || 27 || Left back sheath
|-
||| 4 || Left elbow || 16 || Bust || 28 || Middle back sheath
|-
||| 5 || Right shoulder || 17 || Face || 29 || Belly
|-
||| 6 || Left shoulder || 18 || Above character || 30 || Left back
|-
||| 7 || Right knee || 19 || Ground || 31 || Right back
|-
||| 8 || Left knee || 20 || Top of head || 32 || Left hip sheath
|-
||| 9 || - || 21 || Left palm || 33 || Right hip sheath
|-
||| 10 || - || 22 || Right palm || 34 || Bust
|-
||| 11 || Helmet || 23 || - || 35 || Right palm
|}
For weapons, usually 5 of these points are present, which correspond to the 5 columns in [[ItemVisuals.dbc]], which in turn has 5 models from [[ItemVisualEffects.dbc]]. This is for the weapon glowy effects and such. The effect ID is the last column in [[ItemDisplayInfo.dbc]]. They take the ids 0 to 4. Mounts take the id 0 for their rider.
For weapons, usually 5 of these points are present, which correspond to the 5 columns in [[ItemVisuals.dbc]], which in turn has 5 models from [[ItemVisualEffects.dbc]]. This is for the weapon glowy effects and such. The effect ID is the last column in [[ItemDisplayInfo.dbc]]. They take the ids 0 to 4. Mounts take the id 0 for their rider.


Line 518: Line 947:
*'''nAttachLookup 16-bit integers starting at ofsAttachLookup.'''
*'''nAttachLookup 16-bit integers starting at ofsAttachLookup.'''


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' uint16 Attachment From 0 to nAttachments-1
|
 
! width="70" | Offset
! width="90" | Type
! width="120"| Name
! width="500"| Description
|-
||| ''0x00'' ||uint16|| Attachment|| From 0 to nAttachments-1
|}
==Block 2==
==Block 2==


Line 527: Line 962:
This might be definitions for weapon attachment slots or something like that... Mostly present on characters, creatures and items.
This might be definitions for weapon attachment slots or something like that... Mostly present on characters, creatures and items.


'''Offset Type Name Description'''
{|style="background:#FCFCFC; color:black"
''0x00'' char Identifier[4] Some kind of ID, starts with '$'. Some identifiers below.
|
  ''0x04'' uint32 Id Just an id. Is referenced in the [[M2/WotLK#Attachment_Lookup|lookup-block]] below too.
! width="70" | Offset
  ''0x08'' uint32 Bone Somewhere it has to be attached.
! width="90" | Type
  ''0x0C'' float Position[3] Relative to that bone of course.
! width="120"| Name
  ''0x08'' uint16 InterpolationType This is some fake-AnimationBlock.
! width="500"| Description
  ''0x0A'' uint16 GlobalSequence Built up like a real one but without values. What the fuck?
|-
  ''0x0C'' uint32 nTimestamps See the documentation on [[M2/WotLK#Standard_animation_block|AnimationBlocks]] at this topic.  
||| ''0x00'' || char|| Identifier[4] || Some kind of ID, starts with '$'. Some identifiers below.
  ''0x10'' uint32 ofsTimestamps Will most likely be the same shit again as in the real ones.
|-
 
||| ''0x04''|| uint32|| Id || Just an id. Is referenced in the [[M2/WotLK#Attachment_Lookup|lookup-block]] below too.
|-
||| ''0x08''|| uint32|| Bone || Somewhere it has to be attached.
|-
||| ''0x0C''|| float|| Position[3] || Relative to that bone of course.
|-
||| ''0x08''|| uint16|| InterpolationType|| This is some fake-AnimationBlock.
|-
||| ''0x0A''|| uint16 ||GlobalSequence || Built up like a real one but without values. What the fuck?
|-
||| ''0x0C''|| uint32|| nTimestamps || See the documentation on [[M2/WotLK#Standard_animation_block|AnimationBlocks]] at this topic.  
|-
||| ''0x10''|| uint32|| ofsTimestamps || Will most likely be the same shit again as in the real ones.
|}
Each record specifies a transformation matrix for attaching another model to a certain point. By translating to the attachment position and then applying the transform matrix of the parent bone, the other model at its default origin will snap right into place. This is how weapons are affixed to the hands, helmets and shoulder armor attached, and spell effects are also positioned this way.
Each record specifies a transformation matrix for attaching another model to a certain point. By translating to the attachment position and then applying the transform matrix of the parent bone, the other model at its default origin will snap right into place. This is how weapons are affixed to the hands, helmets and shoulder armor attached, and spell effects are also positioned this way.


Some position identifiers:
Some position identifiers:
'''ID Description'''
{|style="background:#FCFCFC; color:black"
$TRD Crotch
|
  $CCH Bust
! width="70" | ID
  $BTH In front of head
! width="300"| Description
  $CHD Head
|-
  $SHL, $SHR Left/right shoulder
||| $TRD || Crotch
  $CSL, $CSR Left/right hand
|-
  $BWP, $BWR Right hand (for weapons maybe?)
||| $CCH || Bust
 
|-
||| $BTH || In front of head
|-
||| $CHD || Head
|-
||| $SHL, $SHR || Left/right shoulder
|-
||| $CSL, $CSR || Left/right hand
|-
||| $BWP, $BWR || Right hand (for weapons maybe?)
|}
The rest are either copies of the crotch position, or down on the floor. I suppose these are used to position spell effects (like a levelup flash or something) and damage effects.
The rest are either copies of the crotch position, or down on the floor. I suppose these are used to position spell effects (like a levelup flash or something) and damage effects.

Revision as of 22:46, 16 December 2008

M2 files (also called MDX) contain model objects. Each M2 file describes the vertices, faces, materials, texture names, animations and properties of one model. M2 files don't have a chunked format like most other WoW formats.

Models are used for doodads (decoration objects), players, monsters and really everything in the game except for Terrain and WMOs.

This file describes their structure in the second expansion "Wrath of the Lich King". It is up to date for build 8820 and most likely following ones. It has been made by Xayo and schlumpf. All structures have been overlooked by schlumpf. Enjoy it.

--schlumpf_ 00:50, 23 August 2008 (CEST)

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.


Offset Type Name Description
0x000 char[4] Magic "MD20"
0x004 uint32 Version 0x80100000 (first digit of the build the format was last updated)
0x008 uint32 lName Length of the model's name
0x00C uint32 ofsName Offset to the name
0x010 uint32 GlobalModelFlags (0,1,3 seen), connected to field 4 of CreatureModelData.dbc?
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. Now .skins?
0x058 uint32 nTransparency
0x05C uint32 ofsTransparency Transparency of textures.
0x060 uint32 nTextureanimations
0x064 uint32 ofsTextureanimations
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 nTexUnits
0x08C uint32 ofsTexUnits And texture units. Somewhere they have to be too.
0x090 uint32 nTransLookup
0x094 uint32 ofsTransLookup Everything needs its lookup. Here are the transparencies.
0x098 uint32 nTexAnimLookup
0x09C uint32 ofsTexAnimLookup Wait. Do we have animated Textures? Wasn't ofsTexAnims deleted? oO
0x0A0 float theFloats[14] Noone knows. Meeh, they are here.
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 nAttachments_2
0x104 uint32 ofsAttachments_2 And some second block.
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.

Skeleton and animation

Standard animation block

  • Many values that change with time are specified using blocks like the following.

Please see this for information.

If a global sequence is used, it means there is an implicit interpolation range across all values, and a time range from 0 to the proper global sequence timestamp.

If the interpolation type is 0, in some cases that might mean that no animation is given (like for bones), in other cases it means that a single constant data value should be used (like for colors and effect paramters)

Global sequences

  • nGlobalSequences 32-bit unsigned integers starting at ofsGlobalSequences.

A list of timestamps that act as upper limits for global sequence ranges.

Offset Type Name Description
0x00 uint32 Timestamp Entry

Animation sequences

  • nAnimations 0x40-byte records starting at ofsAnimations.

List of animations present in the model.

Offset Type Name Description
0x00 uint16 AnimationID Animation id in AnimationData.dbc
0x02 uint16 SubAnimationID Sub-animation id: Which number in a row of animations this one is.
0x04 uint32 Length The length (timestamps) of the animation.
0x08 float MovingSpeed As 2.x says: moving speed for walk/run animations.
0x0C uint32 Flags Most likely. All flags I saw: 0b01101101
0x10 uint32 Flags 2 Only the first 4 bits are the actual flags. The rest is 1. Seen flags: 0,3,6,7
0x14 uint32 Unknown 1 These two are connected. Most of the time, they are 0.
0x16 uint32 Unknown 2 But if there is data in one, there is data in both of them.
0x1C uint32 PlaybackSpeed Values: 0, 50, 100, 150, 200, 250, 300, 350, 500.
0x20 float BoundingBox[6] A Bounding Box made out of 2 vectors.
0x38 float Radius The radius.
0x3C int16 NextAnimation Id of the following animation of this AnimationID, points to an Index or is -1 if none.
0x3E uint16 Index Id in the list of animations.

Animation Lookup

  • nAnimationLookup in 16-bit shorts starting at ofsAnimationLookup.

Lookup table for Animations in AnimationData.dbc.

Offset Type Name Description
0x00 uint16 AnimationID Index at ofsAnimations which represents the animation in AnimationData.dbc. -1 if none.

Bones

  • nBones records of 0x5C bytes starting at ofsBones.
Offset Type Name Description
0x00 int32 AnimationSeq Index into Animation sequences or -1.
0x04 uint32 Flags Only known flags: 8 - billborded and 512 - transformed
0x08 int16 ParentBone Parent bone ID or -1 if there is none.
0x0C uint16 GeosetID A geoset for this bone.
0x10 int32 Unknown 4 bytes that have been in since TBC. Noone knows what they are for.
0x14 ABlock Translation An animationblock for translation. Should be 3*floats.
0x28 ABlock Rotation An animationblock for rotation. Should be 4*shorts, see Quaternion values and 2.x.
0x3C ABlock Scaling An animationblock for scaling. Should be 3*floats.
0x50 float PivotPoint[3] The pivot point of that bone. Its a vector.

The bone indices in the vertex definitions seem to index into this data.

The billboarding bit is used for various things:

  • Light halos around lamps must always face the viewer
  • The cannonball stack model (in the Deadmines or Booty Bay), where each cannonball is a crude hemisphere, they always face the viewer to create the illusion of actual cannonballs.

Bone Lookup Table

  • nBoneLookupTable 16-bit integers starting at ofsBoneLookupTable. (values: 0 to nBones-1)

Lookup table for bones that transform geometry. Referenced in the various geoset definitions.

Offset Type Name Description
0x00 uint16 Bone Which bone. -1 if there is none.

Key-Bone Lookup

  • nKeyBoneLookup 16-bit shorts starting at ofsKeyBoneLookup.

Its a lookup table for key skeletal bones like hands, arms, legs, etc. nKeyBoneLookup is 21 for the most models. At static models it is mostly 1.

Offset Type Name Description
0x00 uint16 Bone Which bone. -1 if there is none.

Geometry and rendering

Vertices

  • nVertices entries of 48 bytes per vertex (at ofsVertices)
Offset Type Name Description
0x00 float Position[3] A vector to the position of the vertex.
0x0C uint8 BoneWeight[4] The vertex weight for 4 bones.
0x10 uint8 BoneIndices[4] Which are referenced here.
0x14 float Normal[3] A normal vector.
0x20 float TextureCoords[2] Coordinates for a texture.
0x28 float Unknown[2] Null?

Models, too, use a Z-up coordinate systems, so in order to convert to Y-up, the X, Y, Z values become (X, -Z, Y).

I was wrong. --Hergonan

Views (LOD)

Since there is no ofsViews anymore, this data is now stored in .skin files. More information about them here: M2/WotLK/.skin.

Render flags

  • nRenderFlags (uint16, uint16) pairs starting at ofsRenderFlags
Offset Description
0x00 Flags
0x02 Blending mode


  • Flags:
Flag Meaning
0x01 Unlit
0x02 Unfogged?
0x04 Two-sided (no backface culling if set)
0x08 ? (probably billboarded)
0x10 Disable z-buffer?
  • Blending mode
Value Meaning
0 Opaque
1 Alpha testing only
2 Alpha blending
3 Additive?
4 Additive alpha?
5 Modulate?
6 Used in the Deeprun Tram subway glass, supposedly (src=dest_color, dest=src_color) (?)

Most of these blend values are taken from the MDL docs, but they sort of work (like additive blending for light shafts and such)

Texture unit lookup table

  • nTexUnits 16-bit integers starting at ofsTexUnits.
Offset Type Name Description
0x00 int16 Unit Values are -1, 0 or 1. See below.

For models that use multitexturing, this maps given texture unit numbers into actual texture unit numbers (0 or 1).

Values of -1 seem to mean environment mapping.

One model is of special interest, Creature/KelThuzad/KelThuzad.m2, which is the only one that has an nTexUnits of 3, and has three texture units specified for some of its submeshes. Sure enough, two of those map to 0 and 1, and one maps to -1.

More confusion thanks to my favorite "weird" model, World/Generic/Gnome/Passive Doodads/GnomeMachine/GnomeSubwayGlass.m2, which is the translucent, environment mapped glass tunnel in the Deeprun Tram. It only has a single value in this block, -1, which is used for the single texture layer in both render operations in the model. This and the magic with rendering flags/blend modes make up the neat transparent-reflective glass effect, but confuse me even more about how envmapping and such is handled. (and where it seems to get the bluish color from - is it in the model (no color blocks in this particular model), the wmo, a solid background color, or simply the result of the blending used?)

As a side note, on my (dated) system WoW does every texture unit in a single pass.

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.

Colors and transparency

Colors

  • nColors records starting at ofsColors, followed by data referenced in these records.
Offset Type Name Description
0x00 ABlock Color Three floats. One for each color.
0x14 ABlock Alpha A short for the alpha value. 0 - transparent, 0xFFFF - opaque.

For some swirling portals and volumetric lights, these define vertex colors. Referenced from the Texture Unit blocks in the LOD part. Contains a separate timeline for transparency values. If no animation is used, the given value is constant.

Transparency lookup table

  • nTransLookup 16-bit integers starting at ofsTransLookup.
Offset Type Name Description
0x00 uint16 TransparencyId Array indices (0 to n-1).

Contains indices into the Transparency block. Used by the texture unit definitions in the LOD block.

Transparency

  • nTransparency AnimationBlocks at ofsTransparency, followed by data referenced in these records.
Offset Type Name Description
0x10 ABlock Alpha A short for the alpha value. 0 - transparent, 0xFFFF - opaque.

Specifies global transparency values in addition to the values given in the Color block. I assume these are multiplied together eventually.

Textures

  • Textures are defined globally in a list, additionally, a lookup table is given, referenced during rendering, to select textures.

Texture lookup table

  • nTexLookup items starting at ofsTexLookup.
Offset Type Name Description
0x00 uint16 TextureId Array indices (0 to n-1).

Texture definitions

  • 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.
0x002 uint16 Unknown What do I know? Most likely just padding.
0x004 uint16 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:


Value Meaning
0 Texture given in filename
1 Body + clothes
2 Cape
6 Hair, beard
8 Tauren fur
11 Skin for creatures #1
12 Skin for creatures #2
13 Skin for creatures #3

Flags

Value Meaning
1 Texture wrap X
2 Texture wrap Y

Texture animation lookup table

  • nTexAnimLookup items starting at ofsTexAnimLookup.
Offset Type Name Description
0x00 uint16 AnimatedTextureId Array indices (0 to n-1). -1 for a static texture.

Texture animations

  • This block contains definitions for texture animations, for example, flowing water or lava in some models. The keyframe values are used in the texture transform matrix.

nTexAnims records of 0x54 bytes starting at ofsTexAnims, followed by data referenced in these records.

Offset Type Description
0x00 AnimationBlock (float, float, float) Translation 0x1C AnimationBlock (float, float, float ???) Rotation? 0x38 AnimationBlock (float, float, float) Scaling?

The three subrecords specify texture transforms. Translation seems to work, producing nice flowing lava and waterfalls.

Effects

Ribbon emitters

  • nRibbonEmitters records of 0x9C bytes starting at ofsRibbonEmitters, followed by data referenced in these records.

The records have the following structure:

Offset Type Name Description
0x00 uint32 Unknown Always (as I have seen): -1.
0x04 uint32 BoneID A bone to attach to.
0x08 float Position[3] And a position, relative to that bone.
0x14 int32 nTextures Number of referenced textures.
0x18 int32 ofsTextures Offset to the referenced textures.
0x1C int32 nUnkRef Number of some referenced integers.
0x20 int32 ofsUnkRef Offset to the integers.
0x24 ABlock Color A color in three floats.
0x38 ABlock Opacity And an alpha value in a short, where: 0 - transparent, 0xFFFF - opaque.
0x4C ABlock Above The height above.
0x60 ABlock Below The height below. Do not set these to the same!
0x74 float Resolution This defines how smooth the ribbon is. A low value may produce a lot of edges.
0x78 float Length The length aka Lifespan.
0x7C float UnknownFloat Usually 0
0x80 short UnknownShorts[2] Maybe these are blending modes. Pairs of {1,1} for example.
0x84 ABlock UnknownABlock1 The value on these two are integers. First one is 0 all the time.
0x98 ABlock UnknownABlock2 And the second one is 1.

Some models that contain ribbon emitters and are viewable in the game world are: Wisps in BFD, Al'ar the Phoenix in Tempest Keep and any other phoenix models and the energy trails in the COT (not the actual instance, but the entrance cave in Tanaris Desert). Other models with ribbon emitters are spells and effects.

Parameters from the MDL format that are probably in here somewhere: emission rate, rows, cols ...?

Particle emitters

  • nParticleEmitters records starting at ofsParticleEmitters, followed by data referenced in these records.
Offset Type Name Description
0x000 uint32 Unknown Always (as I have seen): -1.
0x004 uint32 Flags There are more flags now. Known: 0x1000 - do not billboard.
0x008 float Position[3] The position. Relative to the following bone.
0x014 uint16 Bone The bone its attached to.
0x016 uint16 Texture And the texture that is used.
0x018 uint32 nReferences1 The first number of integers referenced.
0x01C uint32 ofsReferences1 And the matching offset.
0x020 uint32 nReferences2 The second number of integers referenced.
0x024 uint32 ofsReferences2 And the matching offset again.
0x028 uint8 BlendingType A blending type for the particle. Maybe the same as at the renderflags.
0x029 uint16 EmitterType 1 - Plane (rectangle), 2 - Sphere, 3 - Spline? (can't be bothered to find one)
0x02B uint16 ParticleType Found below.
0x02D uint8 Padding
0x02E uint16 TextureTileRotation Rotation for the texture tile. (Values: -1,0,1)
0x030 uint16 TextureRows How many different frames are on that texture? People should learn what rows and cols are.
0x032 uint16 TextureCols Its different everywhere. I just took it random.
0x034 ABlock EmissionSpeed All of the following blocks should be floats.
0x048 ABlock SpeedVariation Variation in the flying-speed. (range: 0 to 1)
0x05C ABlock VerticalRange Drifting away vertically. (range: 0 to pi)
0x070 ABlock HorizontalRange They can do it horizontally too! (range: 0 to 2*pi)
0x084 ABlock Gravity Fall down, apple!
0x098 ABlock Lifespan Everyone has to die.
0x0AC uint32 unknownPadding I don't know what these two values should do..
0x0B0 ABlock EmissionRate Stread your particles, emitter.
0x0C4 uint32 unknownPadding2 It could have been an array without them..
0x0C8 ABlock EmissionAreaLength Well, you can do that in this area.
0x0DC ABlock EmissionAreaWidth
0x0F0 ABlock Gravity2 A second gravity? Its strong.
0x104 FBlock ParticleColor This one points to 3 floats defining red, green and blue.
0x114 FBlock ParticleOpacity? Looks like opacity (short) --Igor; Most likely they all have 3 timestamps for {start, middle, end}.
0x124 FBlock ParticleSizes It carries two floats per key. (x and y scale)
0x134 int32 UnknownFields[10] Always 0 as far as I see. Indices into the tiles on the texture?
0x15C float UnknownFloats1[3] They have something to do with the spread.
0x168 float Scale[3] Wheey, its the scale!
0x174 float Slowdown Slowpoke is slow.
0x178 float UnknownFloats2[2] More unknown fields.
0x180 float Rotation As a single value? Most likely only one axis then..
0x184 float UnknownFloats3[2] More unknown fields.
0x18C float Rot1[3] Model Rotation 1
0x198 float Rot2[3] Model Rotation 2
0x1A4 float Trans[3] Model Translation
0x1B0 float UnknownFloats4[6] Unknown, unknown, unknown, unknown, unknown...
0x1C8 ABlock EnabledIn Maybe this has integers again. Has been in the earlier documentations. Enabled Anim Block.

About Slowdown: For a non-zero values, instead of travelling linearly the particles seem to slow down sooner. I can't work out the exact function but for a value of, say, 10, the particles pretty much stay in place. Not the same effect as gravity, though. Speed is multiplied by exp( -slowdown * t ).

About particle rotation: 0 for none, 1 to rotate the particle 360 degrees throughout its lifetime.

Rotation can be a float value greater or less one. Results look better if use it as a "phase shift": particle_rotate = randfloat(-sys->rotation * pi, sys->rotation * pi); --Igor

Particle types

Value Description
0 "normal" particle
1 large quad from the particle's origin to its position (used in Moonwell water effects)
2 seems to be the same as 0 (found some in the Deeprun Tram blinky-lights-sign thing)

ParticleType is always 0 and, maybe, now (Flags & 0x40000) != 0 means "particles from origin to position". --Igor

The Fake-AnimationBlock

  • Its pretty much like the real one but without the "header".
Offset Type Name Description
0x000 uint32 nTimestamps The number of timestamps.
0x004 uint32 ofsTimestamps And the offset to them.
0x008 uint32 nKeys The same number again. This time its the number of Keys / Values.
0x00C uint32 ofsKeys And their offset.

Miscellaneous

Bounding volumes

  • For some models a simplified bounding volume is given. This is probably used for collision detection?

Vertices

  • nBoundingVertices vertices at ofsBoundingVertices.
Offset Type Name Description
0x00 float Coordinate[3] This defines a vertex in x,y and z values.

Triangles

  • nBoundingTriangles triples of uint16s at ofsBoundingTriangles.
Offset Type Name Description
0x00 uint16 Index[3] Specifies three vertices of the list above to build a triangle.

The number nBoundingTriangles once again contains the number of indices used, so divide by 3 to get the number of triangles.

Normals

  • nBoundingNormals normals at ofsBoundingNormals.
Offset Type Name Description
0x00 float Vector[3] This defines the normal for each vertex.

Each vertex also has a corresponding normal vector. Therefore, it should be true that nBoundingVertices = nBoundingNormals = nBoundingTriangles / 3.

Lights

  • nLights records of 0x9A bytes starting at ofsLights, followed by data referenced in these records.

The records have the following structure:

Offset Type Name Description
0x00 uint16 Type Types are listed below.
0x02 int16 Bone If its attached to a bone, this is the bone. Else here is a nice -1.
0x04 float Position[3] Where is this light?
0x10 ABlock AmbientColor The ambient color. Three floats for RGB.
0x24 ABlock AmbientIntensity A float for the intensity.
0x38 ABlock DiffuseColor The diffuse color. Three floats for RGB.
0x4C ABlock DiffuseIntensity A float for the intensity again.
0x60 ABlock AttenuationStart This defines, where the light starts to be.
0x74 ABlock AttenuationEnd And where it stops.
0x88 ABlock Unknown Its an integer and usually 1.

Two light types:

Value Description
0 Directional
1 Point light

Cameras

  • nCameras records of 0x64 bytes starting at ofsCameras, followed by data referenced in these records.
Offset Type Name Description
0x00 uint32 BoneID -1 if attached to none? Its also documented as id elsewhere.
0x04 float FOV No radians, no degrees. Multiply by 35 to get degrees.
0x08 float FarClipping Where it stops to be drawn.
0x0C float NearClipping Far and near. Both of them.
0x10 ABlock TranslationPos How the cameras position moves. Should be 3*floats.
0x24 float Position[3] Where the camera is located.
0x30 ABlock TranslationTar How the target moves. Should be 3*floats.
0x44 float Target[3] Where the camera points to.
0x50 ABlock Scaling The camera can have some roll-effect. Its 0 to 2*Pi.

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.

Camera lookup table

  • nCameraLookup 16-bit integers starting at ofsCameraLookup.
Offset Type Name Description
0x00 uint16 CameraId All cameras. Array indices (0 to n-1).

Attachments

Block 1

  • nAttachments records of the following structure starting at ofsAttachments, followed by data referenced in these records.
Offset Type Name Description
0x00 uint32 Id Just an id. Is referenced in the lookup-block below too.
0x04 uint32 Bone Somewhere it has to be attached.
0x08 float Position[3] Relative to that bone of course.
0x14 ABlock Data Its an integer in the data. It has been 1 on all models I saw. Whatever.

This block specifies a bunch of locations on the body - hands, shoulders, head, back, knees etc. It is used to put items on a character. This seems very likely as this block also contains positions for sheathed weapons, a shield, etc.

Here's the list of position slots (by ID, or index in block P) for character models:

ID Description ID Description ID Description
0 Left wrist / Mountpoint 12 Back 24 -
1 Right palm 13 - 25 -
2 Left palm 14 - 26 Right back sheath
3 Right elbow 15 Bust 27 Left back sheath
4 Left elbow 16 Bust 28 Middle back sheath
5 Right shoulder 17 Face 29 Belly
6 Left shoulder 18 Above character 30 Left back
7 Right knee 19 Ground 31 Right back
8 Left knee 20 Top of head 32 Left hip sheath
9 - 21 Left palm 33 Right hip sheath
10 - 22 Right palm 34 Bust
11 Helmet 23 - 35 Right palm

For weapons, usually 5 of these points are present, which correspond to the 5 columns in ItemVisuals.dbc, which in turn has 5 models from ItemVisualEffects.dbc. This is for the weapon glowy effects and such. The effect ID is the last column in ItemDisplayInfo.dbc. They take the ids 0 to 4. Mounts take the id 0 for their rider.

Attachment Lookup

  • nAttachLookup 16-bit integers starting at ofsAttachLookup.
Offset Type Name Description
0x00 uint16 Attachment From 0 to nAttachments-1

Block 2

  • nAttachments_2 records of 0x14 bytes starting at ofsAttachments_2, followed by "data" referenced in these records.

This might be definitions for weapon attachment slots or something like that... Mostly present on characters, creatures and items.

Offset Type Name Description
0x00 char Identifier[4] Some kind of ID, starts with '$'. Some identifiers below.
0x04 uint32 Id Just an id. Is referenced in the lookup-block below too.
0x08 uint32 Bone Somewhere it has to be attached.
0x0C float Position[3] Relative to that bone of course.
0x08 uint16 InterpolationType This is some fake-AnimationBlock.
0x0A uint16 GlobalSequence Built up like a real one but without values. What the fuck?
0x0C uint32 nTimestamps See the documentation on AnimationBlocks at this topic.
0x10 uint32 ofsTimestamps Will most likely be the same shit again as in the real ones.

Each record specifies a transformation matrix for attaching another model to a certain point. By translating to the attachment position and then applying the transform matrix of the parent bone, the other model at its default origin will snap right into place. This is how weapons are affixed to the hands, helmets and shoulder armor attached, and spell effects are also positioned this way.

Some position identifiers:

ID Description
$TRD Crotch
$CCH Bust
$BTH In front of head
$CHD Head
$SHL, $SHR Left/right shoulder
$CSL, $CSR Left/right hand
$BWP, $BWR Right hand (for weapons maybe?)

The rest are either copies of the crotch position, or down on the floor. I suppose these are used to position spell effects (like a levelup flash or something) and damage effects.