M2/.skin: Difference between revisions

From wowdev
Jump to navigation Jump to search
mNo edit summary
mNo edit summary
Line 1: Line 1:
Okay, there is no ofsViews anymore in [[M2/WotLK|M2-files]], but we still got nViews at 4 so there has to be a place where this information is stored. This is when the .skin-files come to the light. They got added in WotLK and are in the same folder as the [[M2/WotLK|M2s]]. They are named like Modelname0x.skin, where Modelname is the same name as the model has and x is a digit from 0 to 3 representing each View / LOD. They are in the same structure as the ofsViews-block has been, just with all offsets now being relative to the .skin-files of course. The vertices are still in the [[M2/WotLK|M2]] itself since they are the same for all views.
Okay, there is no ofsViews anymore in [[M2/WotLK|M2-files]], but we still got nViews at 4 so there has to be a place where this information is stored. This is when the .skin-files come to the light. They got added in WotLK and are in the same folder as the [[M2/WotLK|M2s]]. They are named like Modelname0x.skin, where Modelname is the same name as the model has and x is a digit from 0 to 3 representing each View / LOD. They are in the same structure as the ofsViews-block has been, just with all offsets now being relative to the .skin-files of course. The vertices are still in the [[M2/WotLK|M2]] itself since they are the same for all views.
There is a C .h file here: [[M2/WotLK/.skin/header]]


The files are made up in several blocks. First is a header:
The files are made up in several blocks. First is a header:

Revision as of 15:08, 20 May 2014

Okay, there is no ofsViews anymore in M2-files, but we still got nViews at 4 so there has to be a place where this information is stored. This is when the .skin-files come to the light. They got added in WotLK and are in the same folder as the M2s. They are named like Modelname0x.skin, where Modelname is the same name as the model has and x is a digit from 0 to 3 representing each View / LOD. They are in the same structure as the ofsViews-block has been, just with all offsets now being relative to the .skin-files of course. The vertices are still in the M2 itself since they are the same for all views.

The files are made up in several blocks. First is a header:

Header

Offset	Type 	Name		Description
0x00	uint32	ID		SKIN
0x04	uint32	nIndices		
0x08	uint32	ofsIndices	Indices used in this View.
0x0C	uint32	nTriangles		
0x10	uint32	ofsTriangles	The triangles made with them.
0x14	uint32	nProperties		
0x18	uint32	ofsProperties	Properties of the vertices.
0x1C	uint32	nSubmeshes		
0x20	uint32	ofsSubmeshes	Submeshes (Geosets) of this View.
0x24	uint32	nTextureUnits		
0x28	uint32	ofsTextureUnits	Texture Units.
0x2C	uint32	bones		WoW takes this and divides it by the number of bones in each submesh, then stores the biggest one.

Indices

  • nIndices 16-bit unsigned shorts, specifing vertices from the global vertex list for later use.
Offset	Type 	Name		Description
0x00	uint16	Vertex		The vertex in the global vertex list.

Triangles

  • nTriangles entries of each 3 unsigned shorts. They refer to indices in the list above.
Offset	Type 	Name		Description
0x00	uint16	Indices[3]	Three indices which make up a triangle.

I believe (empirically tested) that nTriangles is actually not the number of triangles in the list, but the number of vertexes in the triangle list. That is, the actual number of triangles in the list is actually nTriangles / 3. I discovered this when a test application I've been writing attempted to read past the end of the file when not first dividing the number of triangles to read by 3.

Vertex properties

  • nProperties entries, they are the Bone Indices for the Vertices
Offset	Type 	Name		Description
0x00	4*uint8	Properties	Bone Indices (Index into BoneLookupTable)

Submeshes

  • nSubmeshes entries of 0x30 bytes defining submeshes.
Offset	Type 	Name			Description
0x00 	uint32	ID			Mesh part ID, see below.
0x04 	uint16	StartVertex		Starting vertex number.
0x06 	uint16	nVertices		Number of vertices.
0x08 	uint16	StartTriangle		Starting triangle index (that's 3* the number of triangles drawn so far).
0x0A 	uint16	nTriangles		Number of triangle indices.
0x0C 	uint16	nBones			Number of elements in the bone lookup table.
0x0E 	uint16	StartBones		Starting index in the bone lookup table.
0x10 	uint16	Unknown			
0x12 	uint16	RootBone		Not sure.
0x14 	Vec3F	CenterMass		Average position of all the vertices in the submesh.
0x20 	Vec3F	CenterBoundingBox	The center of the box when an axis aligned box is built around the vertices in the submesh.
0x2C 	float	Radius			Distance of the vertex farthest from CenterBoundingBox.

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 at ofsBones.

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.

The submeshes are sorted into groups. As Blizzard uses multiple integers (3 ?) for masking them, there are 8*i groups possible. Groups are like this for character models. They can be different for other models.

00**: Hairstyles
01**: Facial1
02**: Facial2
03**: Facial3
04**: Braces
05**: Boots
06**: Unknown
07**: Ears
08**: Wristbands
09**: Kneepads?
10**:
11**: Related to pants
12**: Tabard
13**: Trousers / kilts
14**:
15**: Cape
16**:
17**: Eyeglows (including the deathknight ones)
18**: Belt / bellypack

You can use this together with CreatureDisplayInfo.dbc.creatureGeosetData for nice effects.

Texture units

  • nTextureUnits blocks of 0x18 bytes per record. (Actually named batches)

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 	Name		Description
0x00 	uint16	Flags		Usually 16 for static textures, and 0 for animated textures.	
0x02 	uint16	Shading		If set to 0x8000: shaders. Used in skyboxes to ditch the need for depth buffering. See below.
0x04 	uint16	SubmeshIndex	A duplicate entry of a submesh from the list above.
0x06 	uint16	SubmeshIndex2	
0x08 	int16	ColorIndex	A Color out of the Colors-Block or -1 if none.
0x0A 	uint16	RenderFlags	The renderflags used on this texture-unit.
0x0C 	uint16	TexUnitNumber	Index into the texture unit lookup table.
0x0E 	uint16	Mode		See below.
0x10 	uint16	Texture		Index into Texture lookup table
0x12 	uint16	TexUnitNumber2	Duplicate of TexUnitNumber.
0x14 	uint16	Transparency	Index into transparency lookup table.
0x16 	uint16	TextureAnim	Index into uvanimation lookup table. 

Shader thingey

Its actually two uint8s defining the shader used. Everything below this is in binary. X represents a variable digit.

Depending on "Mode", its either "Diffuse_%s_%s" and "Combiners_%s_%s" (Mode=0) or "Diffuse_%s" and "Combiners_%s" (Mode>0).

Diffuse

Mode   Shading     String
0      0XXX 0XXX   Diffuse_T1_T2
0      0XXX 1XXX   Diffuse_T1_Env
0      1XXX 0XXX   Diffuse_Env_T2
0      1XXX 1XXX   Diffuse_Env_Env

1      0XXX XXXX   Diffuse_T1
1      1XXX XXXX   Diffuse_Env

Combiners

Mode   Shading     String
0      X000 XXXX   Combiners_Opaque_%s
0      X001 XXXX   Combiners_Mod_%s
0      X011 XXXX   Combiners_Add_%s
0      X100 XXXX   Combiners_Mod2x_%s

0      XXXX X000   Combiners_%s_Opaque
0      XXXX X001   Combiners_%s_Mod
0      XXXX X011   Combiners_%s_Add
0      XXXX X100   Combiners_%s_Mod2x
0      XXXX X110   Combiners_%s_Mod2xNA
0      XXXX X111   Combiners_%s_AddNA

1      X000 XXXX   Combiners_Opaque
1      X001 XXXX   Combiners_Mod
1      X010 XXXX   Combiners_Decal
1      X011 XXXX   Combiners_Add
1      X100 XXXX   Combiners_Mod2x
1      X101 XXXX   Combiners_Fade