M2: Difference between revisions

From wowdev
Jump to navigation Jump to search
Line 681: Line 681:
Maybe a lookup table for animations? Since the numbers happen to be in fixed positions. The first short seems to increase with the position for models with all animations (like characters), the second seems to be flags or a modifier? Or something.
Maybe a lookup table for animations? Since the numbers happen to be in fixed positions. The first short seems to increase with the position for models with all animations (like characters), the second seems to be flags or a modifier? Or something.


== Texture animation lookup table ==
*'''nTexAnimLookup 16-bit integers starting at ofsTexAnimLookup. (values: -1, 0 to nTexAnims-1)'''


Contain indices into the texture animations list, or -1 meaning a static texture.  
Contain indices into the texture animations list, or -1 meaning a static texture.  

Revision as of 03:50, 21 August 2008

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.
0x02C	uint32	nKeyBoneLookup
0x030	uint32	ofsKeyBoneLookup	Lookup table for key skeletal bones.

--schlumpf_ 03:12, 21 August 2008 (CEST)

  • Xayo and 2.x ones:

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 unknown blocks have (mostly arbitrary) alphabetic names until we figure out what they are.

Offset 	Type 		Description
0x03C 	uint32 		nVertices - number of vertices
0x040 	uint32 		ofsVertices - offset to vertices
0x044 	uint32 		nViews - number of views (LOD versions?) 4 for every model
(0x048 	uint32 		ofsViews - offset to views (After the "New Pattern" it should be there but in my M2 theres just a 00 00 00 00))
0x048 	uint32 		nColors - number of color definitions 
0x04C 	uint32 		ofsColors - offset to color definitions
0x050 	uint32 		nTextures - number of textures
0x054 	uint32 		ofsTextures - offset to texture definitions
0x058 	uint32 		nTransparency - number of transparency definitions
0x05C 	uint32 		ofsTransparency - offset to transparency definitions
0x060 	uint32 		nI - always 0
0x064 	uint32 		ofsI
0x068 	uint32 		nTexReplace
0x06C 	uint32 		ofsTexReplace
0x070 	uint32 		nRenderFlags - number of blending mode definitions
0x074 	uint32 		ofsRenderFlags - offset to blending mode definitions
0x078 	uint32 		nBoneLookupTable - bone lookup table
0x07C 	uint32 		ofsBoneLookupTable
0x080 	uint32 		nTexLookup - number of texture lookup table entries
0x084 	uint32 		ofsTexLookup - offset to texture lookup table
0x088 	uint32 		nTexUnits - texture unit definitions?
0x08C 	uint32 		ofsTexUnits
0x090 	uint32 		nTransLookup - number of transparency lookup table entries
0x094 	uint32 		ofsTransLookup - offset to transparency lookup table
0x098 	uint32 		nTexAnimLookup - number of texture animation lookup table entries
0x09C 	uint32 		ofsTexAnimLookup - offset to texture animation lookup table
0x0A0 	14 * float 	float values ... ? (in range -1000...1000, mostly in -20...30)
0x0D8 	uint32 		nBoundingTriangles
0x0DC 	uint32 		ofsBoundingTriangles
0x0E0 	uint32 		nBoundingVertices
0x0E4 	uint32 		ofsBoundingVertices
0x0E8 	uint32 		nBoundingNormals
0x0EC 	uint32 		ofsBoundingNormals
0x0F0 	uint32 		nAttachments
0x0F4 	uint32 		ofsAttachments
0x0F8 	uint32 		nAttachLookup
0x0FC 	uint32 		ofsAttachLookup
0x100 	uint32 		nAttachments_2
0x104 	uint32 		ofsAttachments_2
0x108 	uint32 		nLights - number of lights
0x10C 	uint32 		ofsLights - offset to lights
0x110 	uint32 		nCameras - number of cameras
0x114 	uint32 		ofsCameras - offset to cameras
0x118 	uint32 		nCameraLookup
0x11C 	uint32 		ofsCameraLookup
0x120 	uint32 		nRibbonEmitters - number of ribbon emitters
0x124 	uint32 		ofsRibbonEmitters - offset to ribbon emitters
0x128 	uint32 		nParticleEmitters - number of particle emitters
0x12C 	uint32 		ofsParticleEmitters - offset to particle emitters

Note: These infos are ALL not aprooved!

Skeleton and animation

Standard animation block

  • Many values that change with time are specified using blocks like the following. The structure changed in WotLK. Information will come soon.
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	nA			Number of the first informations in the block.
0x008	uint32	infA			First informations in the block.
0x00C	uint32	nB			Number of the second informations in the block.
0x010	uint32	infB			Second informations in the block.

--schlumpf_ 02:01, 21 August 2008 (CEST)

  • Old information
Offset 	Type 		Description
0x00 	int16		interpolation type
0x02 	int16		global sequence ID or -1
0x04 	uint32		number of (int, int) interpolation ranges
0x08 	uint32		offset to interpolation ranges
0x0C 	uint32		number of (int) timestamps
0x10 	uint32		offset to timestamps
0x14 	uint32		number of values
0x18 	uint32		offset to values

The values can have various types depending on the kind of data required, like floats, vectors, quaternions etc.

Usually, if animation is used, interpolation ranges will be given for each animation in the global animation list. These ranges refer to keyframes that have given time and data values. The number of timestamps should therefore be equal to the number of data values.

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)

Interpolation types:

Value 			Description
0 			none / static value
1 			linear
2 			(spline?) in addition to values, in/out tangents are given

Maybe the interpolation types here are the same as the WC3 MDL files? (bezier, etc)

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

--schlumpf_ 02:35, 21 August 2008 (CEST)

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. Values are 0x*FFF. 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. Was labeled as PlaySpeed in 2.x and earlier.
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 there is none.
0x3E	uint16	Index		Id in the list of animations.

--schlumpf_ 00:28, 21 August 2008 (CEST)

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.

--schlumpf_ 00:45, 21 August 2008 (CEST)

Bones

  • nBones records of 0x5C bytes starting at ofsBones.
Offset	Type 	Name		Description
0x00	uint32	AnimationSeq	Index into Animation sequences or -1.
0x04	uint32	Flags		Only known flags: 8 - billborded and 512 - transformed
0x08 	uint16 	ParentBone	Parent bone ID or -1 if there is none.
0x0C 	uint16 	GeosetID	A geoset for this bone.
0x10 	DWORD 	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.

--schlumpf_ 02:50, 21 August 2008 (CEST)

Geometry and rendering

Vertices

  • 48 bytes per vertex (at ofsVertices [?])

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

Offset 	Type 		Description
0x00 	float[3] 	Position
0x0C 	uint8[4] 	Bone weights (0 to 255)
0x10 	uint8[4] 	Bone indices (0 to nBones-1)
0x14 	float[3] 	Normal vector
0x20 	float[2] 	Texture coordinates
0x28 	float[2] 	0?

The fields marked with ? probably have to do with skeletal animation.

Considering "standard" GPU skeletal animation (matrix palette, 4 weights/bones per vertex):

  • then "usually 255" should be an array of 4 unsigned chars defning the vertex weight for 4 bones
  • then "vertex group" should be an Array of 4 unsigned chars indexing 4 bones ++++


-Note by Hergonan-

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.

Views (LOD)

Every model has four of these, at 0x2C bytes each. I'm not sure if it is LOD because each one of them has the same amount of vertices for all four data sets. (???) First I thought this might be different vertex orderings from different views, to ease polygon sorting for transparent faces, but that's not it either. Hmm.

Starting at ofsViews, there are four View (LOD?) header records followed by the data for all four.

Offset 	Type 		Description
0x00 	uint32 		number of elements in the index list
0x04 	uint32 		offset to the index list
0x08 	uint32 		number of elements in the triangle list (this is 3* the number of triangles to be drawn)
0x0C 	uint32 		offset to the triangle list
0x10 	uint32 		number of elements in the vertex property list
0x14 	uint32 		offset to the vertex property list
0x18 	uint32 		number of elements in the submesh list
0x1C 	uint32 		offset to the submesh list
0x20 	uint32 		number of elements in the texture list
0x24 	uint32 		offset to the texture list
0x28 	uint32 		LOD distance or something?

Indices

  • A 16-bit unsigned integer per index, specifies vertices from the global vertex list.

Triangles

  • For every triangle, three 16-bit unsigned ints. These refer to the index list given above, not the global vertex list.

Vertex properties

  • 4 bytes per vertex. Usually 0? Purpose unknown.

Submeshes

  • 32 bytes per submesh. 48 bytes per submesh after client 2.0 (Burning Crusade expansion)
Offset 	Type 		Description
0x00 	uint32 		Mesh part ID
0x04 	uint16 		Starting vertex number
0x06 	uint16 		Number of vertices
0x08 	uint16 		Starting triangle index (that's 3* the number of triangles drawn so far)
0x0A 	uint16 		Number of triangle indices
0x0C 	uint16 		Number of elements in the bone lookup table
0x0E 	uint16 		Starting index in the bone lookup table
0x10 	uint16 		Unknown
0x12 	uint16 		root bone ?
0x14 	float[3]	Vector (3d)
0x20 	float[4]	4 float values? (only in Client 2.0 M2s)

Mesh part ID: for character models, each hairstyle/thick armor/etc is present in the mesh, so to render a character with a specific set of looks, some of the submeshes should be ommitted based on this ID.

Reference to the bone lookup table: the base number seems to increase per LOD, and the numbers in the bone lookup table, in turn, point to bone - indices to Block E. Maybe this could be an indicator of bones used in a submesh, or an animation sequence or something?

About LOD: Creatures\AncientProtector\AncientProtector.m2 is the first model I found where the LOD levels have a significant difference. The 4th LOD level still has the same number of vertices/polygons, but it has more submeshes (more sophisticated animation/lighting or something? I dunno)

Texture units

24 bytes per record. More specifically, textures for each texture unit. Based on the current submesh number, one or two of these are used to determine the texture(s) to bind.

Offset 	Type 		Description
0x00 	uint16 		Flags
0x02 	int16 		Render order (used in skyboxes to ditch the need for depth buffering)
0x04 	uint16 		Submesh index
0x06 	uint16 		Submesh index (repeated?)
0x08 	int16 		Color index or -1
0x0A 	uint16 		Index into render flags table
0x0C 	uint16 		Texture unit number (0 or 1 - index into the texture unit lookup table)
0x0E 	uint16 		always 1?
0x10 	uint16 		Texture to use (index into the texture lookup table)
0x12 	uint16 		Texture unit number (repeated?)
0x14 	uint16 		Transparency (index into transparency lookup table)
0x16 	uint16 		Texture animation (index into the texture animation lookup table)

Flags: usually 16 for static textures, and 0 for animated textures.

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. (values: -1, 0, 1)

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

Colors and transparency

Colors

  • nColors records of 0x38 bytes starting at ofsColors, followed by data referenced in these records.

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 assumed to be constant.

Offset 	Type 					Description
0x00 	AnimationBlock (float,float,float) 	Data for RGB color values
0x1C 	AnimationBlock (short) 			Data for opacity values

Opacity values: 32767 = opaque, 0 = transparent.

Transparency lookup table

  • nTransLookup 16-bit integers starting at ofsTransLookup. (values: 0 to nH-1 ?)

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

Transparency

  • Specifies global transparency values (in addition to the values given in the Color block - I assume these are multiplied together eventually?)

nTransparency records of 0x1C bytes starting at ofsTransparency, followed by data referenced in these records.

Offset 	Type 				Description
0x00 	AnimationBlock (short) 		Data for transparency values

Transparency: 32767 for fully opaque, 0 for fully transparent

Textures

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

Texture lookup table

  • Just a list of 16-bit integers. nTexLookup items starting at ofsTexLookup.

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 		Description
0x00 	uint32 		Texture type (aka replacable id)
0x04 	uint16 		Unknown, usually 0
0x06 	uint16 		Flags
0x08 	uint32 		Filename length
0x0C 	uint32 		Offset to filename

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:

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

'Nothing changed here in WotLK so far!'

Effects

Ribbon emitters

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

These are called ribbon emitters in the strings buried in wow.exe. I guess these are some sort of ribbon-like visual effects similar to particles. In Warcraft 3 (of which the WoW engine is quite loosely based off of) there was also the possibility of ribbon-like effects in trails and flowing clothing. This is also how in WoW the feathers of the gryphons, hippogryphs, and bats flow in the wind as you rise and descend.

Note: the 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 energy trails in the COT (not the actual instance, but the entrance cave in Tanaris Desert). The only other models with ribbon emitters are spells and effects. Gryphons/etc don't have ribbon emitters, the feathers are part of their geometry.

What about the ribbons in the model of the undead ziggurat crystals in Stratholme?

The records have the following structure:

Offset 	Type 		Description
0x00 	int32 		ID? always -1
0x04 	int32 		Bone ID
0x08 	float[3] 	position
0x14 	int32 		Number of texture refs
0x18 	int32 		Offset to texture refs (ints)
0x1C 	int32 		Number of ints #2
0x20 	int32 		Offset to list of ints #2
0x24 	AnimationBlock (float, float, float) 	Color
0x40 	AnimationBlock (short) 	Opacity
0x5C 	AnimationBlock (float) 	Height above
0x78 	AnimationBlock (float) 	Height below
0x94 	float 		Something about length/lifespan?
0x98 	float 		Something about length/lifespan?
0x9C 	float 		Usually 0
0xA0 	short[2] 	(blending modes maybe?) (1,1)
0xA4 	AnimationBlock (int) 	 ? (always 0)
0xC0 	AnimationBlock (int) 	 ? (always 1)

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

Particle emitters

  • nparticleEmitters records of 0x1F8 bytes starting at ofsParticleEmitters, followed by data referenced in these records.

The records have the following structure:

Offset 	Type 		Description
0x000 	int32 		id (always -1?)
0x004 	int32 		flags
0x008 	float[3] 	position
0x014 	int16 		Bone ID
0x016 	int16 		Texture ID
0x018 	uint32 		Number of ints referenced #1
0x01C 	uint32 		Offset to list of ints #1
0x020 	uint32 		Number of ints referenced #2
0x024 	uint32 		Offset to list of ints #2
0x028 	int16 		Blending mode
0x02A 	int16 		Emitter type
0x02C 	int16 		Particle type
0x02E 	int16 		Texture tile rotation (-1,0,1)
0x030 	int16 		Rows on texture
0x032 	int16 		Columns on texture
0x034 	AnimationBlock (float) [10] 	Parameters
0x14C 	float[36] 	unknown float values - more parameters?
0x14C 	float 		Midpoint in lifespan? (0 to 1)
0x150 	uint32[3] 	ARGB colors (start, mid, end)
0x15C 	float[3] 	Particle sizes (start, mid, end)
0x168 	short[10] 	Indices into the tiles on the texture?
0x17C 	float[3] 	Unknown
0x188 	float[3] 	Something about particle scaling? Hm.
0x194 	float 		Slowdown
0x198 	float 		Particle rotation
0x19C 	float[10] 	Unknown (usually all 0)
0x1C4 	float[6] 	Unknown, usually (2.5, 0.7, 7, 0.9, 0, 0)
0x1DC 	AnimationBlock (int) 	unknown

About slowdown: for nonzero 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. Update: thanks to nsz for the formula. Speed is multiplied by exp( -slowdown * t )

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

The ten animatable particle parameters are:

Number 	Description
0 	Emission speed
1 	Speed variation (range: 0 to 1)
2 	Vertical Range (range: 0 to pi)
3 	Horizontal Range (0 to 2*pi)
4 	Gravity
5 	Lifespan
6 	Emission rate
7 	Emission area length
8 	Emission area width
9 	Gravity? (much stronger)

Emitter types:

Value 	Description
1 	Plane (rectangle)
2 	Sphere
3 	(Spline? can't be bothered to find one)

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)

Flags:

Value 	Description
0x1000 	do not billboard (used for some water wake ripple effects)


Miscellaneous

Bounding volumes

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

The nBoundingVertices vertices used by the bounding volume's faces start at ofsBoundingVertices. Each vertex is given by 3 floats.

The faces start at ofsBoundingTriangles. The number nBoundingTriangles once again contains the number of indices used, so divide by 3 to get the number of triangles. Each triangle is given by 3 16-bit integers that index the bounding vertices list.

Each face also has a corresponding normal vector (?), these start at ofsBoundingNormals. Therefore, it should be true that nBoundingNormals * 3 = nBoundingTriangles.

Lights

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

The records have the following structure:

Offset 	Type 		                    Description
0x00 	uint16 		                        Type
0x02 	uint16 		                        Bone ID
0x04 	float[3] 	                        Coordinates
0x10 	AnimationBlock (float, float, float)	Ambient color
0x2C 	AnimationBlock (float) 			Ambient intensity
0x48 	AnimationBlock (float, float, float) 	Diffuse color
0x64 	AnimationBlock (float) 			Diffuse intensity
0x80 	AnimationBlock (float) 			Attenuation start?
0x9C 	AnimationBlock (float) 			Attenuation end?
0xB8 	AnimationBlock (int) 			usually 1

Some light types:

Value 			Description
0 			Directional
1 			Point light

Cameras

  • These blocks seem to be 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.

nCameras records of 0x7C bytes starting at ofsCameras, followed by data referenced in these records.

Offset 	Type 		                          Description
0x00 	int32 		                        ID or maybe a parent bone? usually -1
0x04 	float 		                        FOV
0x08 	float 		                        Far clipping plane
0x0C 	float 		                        Near clipping plane
0x10 	AnimationBlock (float, float, float) 	Translation for position?
0x2C 	float[3] 	                        Position?
0x38 	AnimationBlock (float, float, float) 	Translation for target?
0x54 	float[3] 	                        Target?
0x60 	AnimationBlock (float) 			Rotation or roll? (usually 0 or 2*pi)

For static cameras the animatable data items are all 0. The FOV is not in radians, but some weird scale... Multiplying by about 35 seems to give correct-ish results in degrees.

The reason that non-mainmenu and non-geometry M2s have cameras (atleast in Warcraft 3) was so you could see the unit's portrait. In WoW, these models have cameras so that when you enter the Character menu (press "C") you see your character regardless of what model you currently have. Also, I believe that one of the main menu models has two cameras in it (I believe it's the orc one...).-DG

Oh, that's right. Neat. I added menu backdrops using these cameras. Obviously it's still missing particle emitters, but that can be fixed eventually... - Z.

Camera lookup table

  • Lookup table for cameras? It seems to be persent only if a camera is present too.

nCameraLookup 16-bit integers starting at ofsCameraLookup. (values: 0..nCameras-1)

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.

Attachments

Block 1

  • nAttachments records of 0x50 bytes starting at ofsAttachments, followed by data referenced in these records.
Offset 	Type 			Description
0x00 	uint32 			id (position of the record in block P)
0x04 	uint32 			bone
0x08 	float[3] 		position
0x14 	AnimationBlock (int) 	Data
0x40 	float[3] 		Unknown Floats (rot maybe?)
0x4C 	AnimationBlock (int) 	Data

--Xayo 02:33, 21 August 2008 (CEST)

Much like Block 2 this one also specifies a bunch of locations on the body - hands, shoulders, head, back, knees etc. Maybe this one is actually 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

ID 0 is left wrist / shield for mobs and "mountpoint" for mounts.

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.

Attachment Lookup

  • nAttachLookup 16-bit integers starting at ofsAttachLookup. (values: -1, 0 to nO-1)

Lookup table for whatever is in block 1, I guess :)

Block 2

  • nAttachments_2 records of 0x24 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 		Description
0x00 	char[4] 	some kind of ID, starts with '$'
0x04 	uint32 		database ID?
0x08 	uint32 		bone ID
0x0C 	float[3] 	floats (coordinates?)
0x18 	AnimBlock(int) 	AnimationBlock for Something unknown

--Xayo 02:56, 21 August 2008 (CEST)

The records seem to contain a truncated animation block. The int values look like timestamps, and there are no data values. The ranges reference more integers than are given in the list (there's always 1 less item). Weird.

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

Some unknows identifiers:

ID 		Found at
$CST		Frostwurm & Dragon
$CAH		Frostwurm & Dragon
$CPP		Frostwurm & Dragon
$CSS		Frostwurm & Dragon
$HIT		Frostwurm & Dragon
$DTH		Frostwurm & Dragon
$FSD		Frostwurm & Dragon
$WNG		Frostwurm & Dragon
$FL0, $FL1	Frostwurm & Dragon
$FR0, $FR1	Frostwurm & Dragon
$RL0, $RL1	Frostwurm & Dragon
$RR0, $RR1	Frostwurm & Dragon

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.

Unknown blocks

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. 

--schlumpf_ 03:10, 21 August 2008 (CEST)

Replacable texture lookup

  • nK 16-bit integers starting at ofsK. (values: -1 or 0 to nTex-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.

Deleted Blocks

Block D

  • nD records of (int16, int16) starting at ofsD

Maybe a lookup table for animations? Since the numbers happen to be in fixed positions. The first short seems to increase with the position for models with all animations (like characters), the second seems to be flags or a modifier? Or something.


Contain indices into the texture animations list, or -1 meaning 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.