M2: Difference between revisions

From wowdev
Jump to navigation Jump to search
m (uint16 - parent bone. -1 if none. what? ..)
No edit summary
Line 396: Line 396:
  ''0x104'' [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] ParticleColor This one points to 3 floats defining red, green and blue.
  ''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]] UnknownFakeBlock1 Most likely they all have 3 timestamps for {start, middle, end}.
  ''0x114'' [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] UnknownFakeBlock1 Most likely they all have 3 timestamps for {start, middle, end}.
  ''0x124'' [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] UnknownFakeBlock2 It carries two floats per key.
  ''0x124'' [[M2/WotLK#The_Fake-AnimationBlock|FBlock]] ParticleSizes It carries two floats per key.
  ''0x134'' int32 UnknownFields[10] Always 0 as far as I see. Indices into the tiles on the texture?
  ''0x134'' int32 UnknownFields[10] Always 0 as far as I see. Indices into the tiles on the texture?
  ''0x15C'' float UnknownFloats1[3] Hell, there are too many values in here.. What the fuck are these for again?
  ''0x15C'' float UnknownFloats1[3] Hell, there are too many values in here.. What the fuck are these for again?
Line 403: Line 403:
  ''0x178'' float UnknownFloats2[2] More unknown fields.
  ''0x178'' float UnknownFloats2[2] More unknown fields.
  ''0x180'' float Rotation As a single value? Most likely only one axis then..
  ''0x180'' float Rotation As a single value? Most likely only one axis then..
  ''0x184'' float UnknownFloats3[17] Unknown, unknown, unknown, unknown, unknown...
  ''0x184'' float UnknownFloats3[2] More unknown fields.
  ''0x1C8'' [[M2/WotLK#Standard_animation_block|ABlock]] UnknownAnimBlock Maybe this has integers again. Has been in the earlier documentations.
''0x18C'' float Rot1[3]                Model Rotation 1
''0x198'' float Rot2[3]                Model Rotation 2
''0x1A4'' float Rot2[3]                Model Translation
''0x1B0'' float UnknownFloats4[6] Unknown, unknown, unknown, unknown, unknown...
  ''0x1C8'' [[M2/WotLK#Standard_animation_block|ABlock]] UnknownAnimBlock 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 ).

Revision as of 17:27, 6 September 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	Type			Type of the model. 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	nUnknown
0x064	uint32	ofsUnknown		This was never in use. Both are 0 all the time.
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.
Offset	Type 	Name			Description
0x000	uint16	InterpolationType	How the values are interpolated. (0=none, 1=linear, 2=hermite)
0x002	uint16	GlobalSequenceID	If its made with a global sequence, its in here. Id is it is, -1 if not.
0x004	uint32	nTimestamps		The number of timestamps. Is the same as the number of keys, most of the time.
0x008	uint32	ofsTimestamps		Offset to the timestamps in the file.
0x00C	uint32	nKeys			Number of the keys.
0x010	uint32	ofsKeys			Values of the block. 

The offsets point to a sub-structure now. Its like this:

Offset	Type 	Name			Description
0x000	uint32	Number			It tells us where the values actually are.
0x004	uint32	Offset			The offset to the data.

The easiest form is if you get a Number == 1 block straight as in single-value AnimationBlocks in some blocks. Particles have only such AnimationBlocks. It just gives you another offset where the data is. Its in this file at the given offset. But if you get a whole list with a lot of stupid values (such as offsets that can't be in the M2 and the .anims), you have a little problem. I don't know why, but Blizzard made some crap here. Most likely to get us confused. Or there is more information I know nothing of.

What helped me so far was this "simple" conversion: Take nTimestamps / nKeys, substract 1, divide by 3. So out of 0x22 (34) you will get 11. This is the offset to the real sub-structure (if you start with the one pointed to at 0). This offset is then into one of the .anim files. I think its just "if the first file is full, we will take the next one". I am not sure about this. I have been sleepless for 2 days now and cba to look even more into these blocks.

The data at the final offset can be of any structure. It can be one float, a short, an integer but too a Vector of three floats or a quaternion which is made in four floats or shorts, depending on the occurence of the main AnimationBlock.


Actually I'd say that we may have gotten this structure:

Offset	Type 	Name			Description
0x000	uint16	InterpolationType	How the values are interpolated. (0=none, 1=linear, 2=hermite)
0x002	uint16	GlobalSequenceID	If its made with a global sequence, its in here. Id is it is, -1 if not.
0x004	uint32	offsetIntoList1		(This - 1) / 3 is the index into the list at offsetToTimestampsOfs.
0x008	uint32	offsetToTimestampsOfs	Offset to the list which holds the offset to the data of the timestamps.
0x00C	uint32	offsetIntoList2		(This - 1) / 3 is the index into the list at offsetToKeysOfs.
0x010	uint32	offsetToKeysOfs		Offset to the list which holds the offset to the data of the keys.

What the fuck, Blizzard?


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).

When I set all info for the vertices to 0 the visual part of the model didn't change but when I tried to select a model ingame by using the mouse and hovering over them I could only do that where the bones were. That means vertices are there for the mouse to react with. --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 	 	?
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	uint16	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.
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		If the Type is "0 - hardcoded" then here is the length.
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.

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.
0x74 	float 	Res 			Something about lifespan?
0x78 	float 	Length 			The length.
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: life span, 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	uint16	BlendingType		A blending type for the particle. Maybe the same as at the renderflags.
0x02A	uint16	EmitterType		1 - Plane (rectangle), 2 - Sphere, 3 - Spline? (can't be bothered to find one)
0x02C	uint16	ParticleType		Found below.
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 	UnknownFakeBlock1	Most likely they all have 3 timestamps for {start, middle, end}.
0x124 	FBlock 	ParticleSizes		It carries two floats per key.
0x134 	int32 	UnknownFields[10]	Always 0 as far as I see. Indices into the tiles on the texture?
0x15C 	float 	UnknownFloats1[3]	Hell, there are too many values in here.. What the fuck are these for again?
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 	Rot2[3]                 Model Translation
0x1B0 	float 	UnknownFloats4[6]	Unknown, unknown, unknown, unknown, unknown...
0x1C8 	ABlock 	UnknownAnimBlock	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.

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)

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.