Difference between revisions of "AC4F8687"

From SimsWiki
Jump to: navigation, search
(Fixed spelling in infobox)
(Reformatting)
Line 11: Line 11:
 
The file specification for GMDC follows. The format uses the standard RCOL file header, and data chunks conform to the standard RCOL chunk header structure.  
 
The file specification for GMDC follows. The format uses the standard RCOL file header, and data chunks conform to the standard RCOL chunk header structure.  
  
[The File Structure]
+
==The File Structure==
  
 
<pre>
 
<pre>
Line 35: Line 35:
 
</pre>
 
</pre>
  
 
+
==The Elements (P1) Section==
 
+
[The Elements (P1) Section]
+
  
 
The first section of a GMDC file is the Elements chunk. This section stores the actual vertices, normals, UV coordinates, etc.  
 
The first section of a GMDC file is the Elements chunk. This section stores the actual vertices, normals, UV coordinates, etc.  
Line 77: Line 75:
 
</pre>
 
</pre>
  
Table 1: Element Identities
+
===Table 1 : Element Identities===
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
0x1C4AFC56 : Blend Indices
+
0x5C4AFC5C : Blend Weights
+
0x7C4DEE82 : Target Indices
+
0xCB6F3A6A : Normal Morph Deltas
+
0xCB7206A1 : Colour
+
0xEB720693 : Colour Deltas
+
0x3B83078B : Normals List
+
0x5B830781 : Vertices
+
0xBB8307AB : UV coordinates
+
0xDB830795 : UV Coord Deltas
+
0x9BB38AFB : Binormals
+
0x3BD70105 : Bone Weights
+
0xFBD70111 : Bone Assignments
+
0x89D92BA0 : Bump Map Normals
+
0x69D92B93 : Bump Map Normal Deltas
+
0x5CF2CFE1 : Morph Vertex Deltas
+
0xDCF2CFDC : Morph Vertex Map
+
  
Table 2: Block Formats
+
{| border="1"
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
|0x1C4AFC56 || Blend Indices
0x00 1xdword float
+
|-
0x01 2xdword float
+
|0x5C4AFC5C || Blend Weights
0x02 3xdword float
+
|-
0x04 1xdword uint32
+
|0x7C4DEE82 || Target Indices
 +
|-
 +
|0xCB6F3A6A || Normal Morph Deltas
 +
|-
 +
|0xCB7206A1 || Colour
 +
|-
 +
|0xEB720693 || Colour Deltas
 +
|-
 +
|0x3B83078B || Normals List
 +
|-
 +
|0x5B830781 || Vertices
 +
|-
 +
|0xBB8307AB || UV coordinates
 +
|-
 +
|0xDB830795 || UV Coord Deltas
 +
|-
 +
|0x9BB38AFB || Binormals
 +
|-
 +
|0x3BD70105 || Bone Weights
 +
|-
 +
|0xFBD70111 || Bone Assignments
 +
|-
 +
|0x89D92BA0 || Bump Map Normals
 +
|-
 +
|0x69D92B93 || Bump Map Normal Deltas
 +
|-
 +
|0x5CF2CFE1 || Morph Vertex Deltas
 +
|-
 +
|0xDCF2CFDC || Morph Vertex Map
 +
|}
  
Table 3: Set Groups (formats)
+
===Table 2: Block Formats===
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
0x00 Main (Used by the main [first] Vertex group and intermediate blend groups)
+
0x01 Norms (Used by the main normals, and target indices)
+
0x02 UV (Used by UV coords and Deltas)
+
0x03 Secondary (Secondary groups used by the later elements in files, deltas, bones, etc)
+
  
Formula 1: Element value list sets
+
{| border="1"
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
|0x00||1xdword ||float
 +
|-
 +
|0x01||2xdword ||float
 +
|-
 +
|0x02||3xdword ||float
 +
|-
 +
|0x04||1xdword ||uint32
 +
|}
 +
 
 +
===Table 3: Set Groups (formats)===
 +
 
 +
{| border="1"
 +
|0x00 ||Main (Used by the main [first] Vertex group and intermediate blend groups)
 +
|-
 +
|0x01 ||Norms (Used by the main normals, and target indices)
 +
|-
 +
|0x02 ||UV (Used by UV coords and Deltas)
 +
|-
 +
|0x03 ||Secondary (Secondary groups used by the later elements in files, deltas, bones, etc)
 +
|}
 +
 
 +
===Formula 1: Element value list sets===
 
To calculate how many value sets are stored in the element value list,
 
To calculate how many value sets are stored in the element value list,
 
use the following formula:
 
use the following formula:
Line 124: Line 149:
 
[List Length] = [Block Size] / [Set Size] / 4
 
[List Length] = [Block Size] / [Set Size] / 4
  
Formula 2: Reading the element value list
+
===Formula 2: Reading the element value list===
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
 
To read the element value list, use the following code:
 
To read the element value list, use the following code:
  
Line 170: Line 194:
  
 
The "Target Indices" sections seem to only appear in the Elements section, and flag the inclusion of Morph Delta(s), Morph Normal(s) and a Morph map. For multiple morph models, there would be 'n' Morph Delta sections, then 'n' Morph normals sections, then a single morph map, which is mapped into sets of 4 bytes. Each byte value, if zero, means the corresponding vertice is left at its explicit location. For the first morph, you read the value of the least-significant byte in the morph map. Zeroes mean that vertice has no morph. Placing a number value (1, 2 or 3) into a byte flags the corresponding vertice and normal to be modified by adding the delta value from morph delta and morph normal (if present) (n-1). For a second morph, the second byte (reading big-endian) is used, again, a 1 would mean take the delta values from the first morph data section, or a 2 from the second one. That leaves room for 4 morphs in the morph map. Esentially, the map is designed to read by 'column' and use the value-1 as an index for which data block, at that offset, to look for the proper delta value.
 
The "Target Indices" sections seem to only appear in the Elements section, and flag the inclusion of Morph Delta(s), Morph Normal(s) and a Morph map. For multiple morph models, there would be 'n' Morph Delta sections, then 'n' Morph normals sections, then a single morph map, which is mapped into sets of 4 bytes. Each byte value, if zero, means the corresponding vertice is left at its explicit location. For the first morph, you read the value of the least-significant byte in the morph map. Zeroes mean that vertice has no morph. Placing a number value (1, 2 or 3) into a byte flags the corresponding vertice and normal to be modified by adding the delta value from morph delta and morph normal (if present) (n-1). For a second morph, the second byte (reading big-endian) is used, again, a 1 would mean take the delta values from the first morph data section, or a 2 from the second one. That leaves room for 4 morphs in the morph map. Esentially, the map is designed to read by 'column' and use the value-1 as an index for which data block, at that offset, to look for the proper delta value.
 +
 
As of this editing, leaving all the data blocks empty in a Target Index block still results in a loadable file that will morph from thin to fat in the game. However, the data are definitely vectors, and indexes, but I haven't figured out whether the indexes are to vertices or to triangles. After reproducing a complete model, even using the original tangent normals
 
As of this editing, leaving all the data blocks empty in a Target Index block still results in a loadable file that will morph from thin to fat in the game. However, the data are definitely vectors, and indexes, but I haven't figured out whether the indexes are to vertices or to triangles. After reproducing a complete model, even using the original tangent normals
 
(0x89D92BA0 : Bump Map Normals) from the original mesh, bumpmapping won't work without this data. Until this mystery is unraveled, complete game meshes can be produced with all the features except alpha layer bumpmapping.
 
(0x89D92BA0 : Bump Map Normals) from the original mesh, bumpmapping won't work without this data. Until this mystery is unraveled, complete game meshes can be produced with all the features except alpha layer bumpmapping.
  
[The Linkages (P2) Section]
+
==The Linkages (P2) Section==
  
 
The second section in a GMDC contains data to link elements from section one, to groupings of those elements, defined in section 3 (P3). In some cases, three additional blocks other than the main index may be populated. These blocks contain extra indices of vertices, normals, and UV's for a subset mesh, defined later on in section 5 (P5).
 
The second section in a GMDC contains data to link elements from section one, to groupings of those elements, defined in section 3 (P3). In some cases, three additional blocks other than the main index may be populated. These blocks contain extra indices of vertices, normals, and UV's for a subset mesh, defined later on in section 5 (P5).
Line 218: Line 243:
  
  
[The Groups (P3) Section]
+
==The Groups (P3) Section==
  
 
The third section in GMDC is the groups section. Groups collect elements from section one, through linkages in section 2, to form components like faces of a mesh.  
 
The third section in GMDC is the groups section. Groups collect elements from section one, through linkages in section 2, to form components like faces of a mesh.  
Line 253: Line 278:
 
The last subset version maps the value used in the 0xFBD70111 (Bone Assignments) section to the standard values used by other parts of the game. For example, a bone value of 4(from P1) would be used as an index to retrieve a value from the fifth element of this array that represents the real bone number, as used in other parts of the game. In creating a new GMDC, making an array that uses a series of 0, 1, 2, 3, ... makes a legitimate map, so long as you use the "real" bone values in the Bone Assignments section.
 
The last subset version maps the value used in the 0xFBD70111 (Bone Assignments) section to the standard values used by other parts of the game. For example, a bone value of 4(from P1) would be used as an index to retrieve a value from the fifth element of this array that represents the real bone number, as used in other parts of the game. In creating a new GMDC, making an array that uses a series of 0, 1, 2, 3, ... makes a legitimate map, so long as you use the "real" bone values in the Bone Assignments section.
  
[The Model (P4) Section]
+
==The Model (P4) Section==
  
 
There is only one model per GMDC, so the next section does not have an outer loop. The model contains information to rotate and transform the mesh, as well as a bounding mesh for the whole model. The mesh stored in the model section is composed of vertecies and faces composed of those vertices. In the face list, each sequential set of 3 values represents a face. The face is defined by using the vertices at the positions in the vertex list specified in the 3 face values.  
 
There is only one model per GMDC, so the next section does not have an outer loop. The model contains information to rotate and transform the mesh, as well as a bounding mesh for the whole model. The mesh stored in the model section is composed of vertecies and faces composed of those vertices. In the face list, each sequential set of 3 values represents a face. The face is defined by using the vertices at the positions in the vertex list specified in the 3 face values.  
Line 298: Line 323:
 
The "Name Pairs" are used by the game to identify links to the morphs for animation purposes. Inclusion of full morph data without duplicating the name pairs referenced by the animations will not render.
 
The "Name Pairs" are used by the game to identify links to the morphs for animation purposes. Inclusion of full morph data without duplicating the name pairs referenced by the animations will not render.
  
[The Subset (P5) Section]
+
==The Subset (P5) Section==
  
 
Subsets are parts of the full mesh, and are associated with bones (joints) and other components of the model.
 
Subsets are parts of the full mesh, and are associated with bones (joints) and other components of the model.

Revision as of 09:07, 10 September 2006

AC4F8687
Short name: GMDC
Long name: Geometric data container
This article is imported from the old MTS2 wiki. You can help Sims2Wiki by cleaning it up. It's original page with comments can be found at http://old_wiki.modthesims2.com/AC4F8687
This article is imported from the old MTS2 wiki. You can help Sims2Wiki by cleaning it up. It's original page with comments can be found at http://old_wiki.modthesims2.com/GMDC

The Geometry Data Container format (GMCD for short, Maxis name cGeometryDataContainer), is the 3D mesh of The Sims 2 files. GMDC is part of the "SceneGraph Resource Collection" set of files, more commonly known as RCOL. This complex file format stores information such as vertecies, normal vectors, U/V texture mapping coordinates, IK animation bones and bone joints, and a few other things. It is a very important file to modding efforts, as its central to creating new objects in the game.

The file specification for GMDC follows. The format uses the standard RCOL file header, and data chunks conform to the standard RCOL chunk header structure.

Contents

The File Structure

REF		reference: RCOL file header and index

; Depending on the RCOL index, other RCOL chunks 
; may appear before the GMDC chunk

7BITSTR		block name (cGeometryDataContainer)
DWORD		block ID
DWORD		block version

REF		reference: read a cSGResource chunk here

REF		reference: Elements section (P1)
REF		reference: Linkages section (P2)
REF		reference: Groups section   (P3)
REF		reference: Model section    (P4)
REF		reference: Subsets section  (P5)

; Depending on the RCOL index, other RCOL chunks
; may appear after the GMDC chunk

The Elements (P1) Section

The first section of a GMDC file is the Elements chunk. This section stores the actual vertices, normals, UV coordinates, etc.

DWORD		element count		; 32bit count

; Elements
LOOP					; repeat previous value times
  DWORD		References Array Size	; Size of element array that can be referenced in Referenced Array List
  DWORD		Element Identity	; See table 1 below
  DWORD		Identity repetition	; logs how many times this identity has been used

  DWORD		Block Format		; Determines the format of the element values list
  DWORD		Set Format		; Determines the format of values in the element list

; Element Value List block
  DWORD		Block size		; The size of the following data block in bytes

  LOOP		element value list	; repeat by formula 1 below
	LOOP	value set		; repeat by formula 2 below
	  IF (GMDC version = 4)
	    WORD				; Single value from a value set
	  ELSE IF (GMDC version < 4)
	    DWORD				; Single value from a value set
	ENDLOOP
  ENDLOOP

; Reference Array  (links to entries by references# in another element - generally automatic associations)

  DWORD count
  LOOP      ; repeat previous count value times
	IF (GMDC version = 4)
	  WORD				; Single Reference Array Entry
	ELSE IF (GMDC Version < 4)
	  DWORD				; Single Reference Array Entry
  ENDLOOP
ENDLOOP

Table 1 : Element Identities

0x1C4AFC56 Blend Indices
0x5C4AFC5C Blend Weights
0x7C4DEE82 Target Indices
0xCB6F3A6A Normal Morph Deltas
0xCB7206A1 Colour
0xEB720693 Colour Deltas
0x3B83078B Normals List
0x5B830781 Vertices
0xBB8307AB UV coordinates
0xDB830795 UV Coord Deltas
0x9BB38AFB Binormals
0x3BD70105 Bone Weights
0xFBD70111 Bone Assignments
0x89D92BA0 Bump Map Normals
0x69D92B93 Bump Map Normal Deltas
0x5CF2CFE1 Morph Vertex Deltas
0xDCF2CFDC Morph Vertex Map

Table 2: Block Formats

0x00 1xdword float
0x01 2xdword float
0x02 3xdword float
0x04 1xdword uint32

Table 3: Set Groups (formats)

0x00 Main (Used by the main [first] Vertex group and intermediate blend groups)
0x01 Norms (Used by the main normals, and target indices)
0x02 UV (Used by UV coords and Deltas)
0x03 Secondary (Secondary groups used by the later elements in files, deltas, bones, etc)

Formula 1: Element value list sets

To calculate how many value sets are stored in the element value list, use the following formula:

1) Use details from Table 2 to determine the structure of a single set in the list. For example, a Block Format of 2 means there are three float values per set. [Set Size]

2) Calculate number of entries in the list using:

[List Length] = [Block Size] / [Set Size] / 4

Formula 2: Reading the element value list

To read the element value list, use the following code:

'' Read blockFormat
'' ...

'' Determine set length
int setLength = 1;
switch (blockFormat)
{
  case 0x00: 
  case 0x04:
	setLength = 1:
	break;
  case 0x01:
	setLength = 2;
	break;
  case 0x02:
	setLength = 3;
	break;
}

'' Determine list length
int listLength = blockSize / setLength / 4;

'' Read list
for (int i=0; i<listLength; i++)
{
  '' Read single set
  for (int j=0; j<setLength; j++)
  {
	if (blockFormat == 0x04)
	{
	 	'' Read a 32bit integer
	}
	else
	{
	'' Read a float
	}
  }
}

The "Target Indices" sections seem to only appear in the Elements section, and flag the inclusion of Morph Delta(s), Morph Normal(s) and a Morph map. For multiple morph models, there would be 'n' Morph Delta sections, then 'n' Morph normals sections, then a single morph map, which is mapped into sets of 4 bytes. Each byte value, if zero, means the corresponding vertice is left at its explicit location. For the first morph, you read the value of the least-significant byte in the morph map. Zeroes mean that vertice has no morph. Placing a number value (1, 2 or 3) into a byte flags the corresponding vertice and normal to be modified by adding the delta value from morph delta and morph normal (if present) (n-1). For a second morph, the second byte (reading big-endian) is used, again, a 1 would mean take the delta values from the first morph data section, or a 2 from the second one. That leaves room for 4 morphs in the morph map. Esentially, the map is designed to read by 'column' and use the value-1 as an index for which data block, at that offset, to look for the proper delta value.

As of this editing, leaving all the data blocks empty in a Target Index block still results in a loadable file that will morph from thin to fat in the game. However, the data are definitely vectors, and indexes, but I haven't figured out whether the indexes are to vertices or to triangles. After reproducing a complete model, even using the original tangent normals (0x89D92BA0 : Bump Map Normals) from the original mesh, bumpmapping won't work without this data. Until this mystery is unraveled, complete game meshes can be produced with all the features except alpha layer bumpmapping.

The Linkages (P2) Section

The second section in a GMDC contains data to link elements from section one, to groupings of those elements, defined in section 3 (P3). In some cases, three additional blocks other than the main index may be populated. These blocks contain extra indices of vertices, normals, and UV's for a subset mesh, defined later on in section 5 (P5).

DWORD		count
LOOP					; repeat "previous count" times
  DWORD		index count
  LOOP					; index, Block A
	IF (GMDC Version = 4)
	  WORD	index value
	ELSE IF (GMDC version < 4)
	  DWORD	index value
  ENDLOOP

  DWORD		referenced array size (max element reference array size)
  DWORD		active elements for this link (active element #'s)

  DWORD		Submodel vertex count	
  LOOP					; Block B
	IF (GMDC Version = 4)
	  WORD	subset index value
	ELSE IF (GMDC version < 4)
	  DWORD	subset index value
  ENDLOOP

  DWORD		Submodel normals count	
  LOOP					; Block C
	IF (GMDC Version = 4)
	  WORD	normals index value
	ELSE IF (GMDC version < 4)
	  DWORD	normals index value
  ENDLOOP

  DWORD		Submodel UV count		
  LOOP					; Block D
	IF (GMDC Version = 4)
	  WORD	UV index value
	ELSE IF (GMDC version < 4)
	  DWORD	UV index value
  ENDLOOP
ENDLOOP


The Groups (P3) Section

The third section in GMDC is the groups section. Groups collect elements from section one, through linkages in section 2, to form components like faces of a mesh.

DWORD		count
LOOP					; repeat "previous count" times
  DWORD		primitive type
  DWORD		link index

  7BITSTR	name of object

  DWORD		face count
  LOOP					; repeat "face count" times
	IF (GMDC version = 4)
	  WORD	vertex reference
	ELSE IF (GMDC version < 4)
	  DWORD	vertex reference
  ENDLOOP 

  DWORD		opacity amount		; 0xFFFFFFFF = full opacity, 0x0 = full transparency, < 16 for shadows

  IF (GMDC version != 1)
	DWORD	subset count
	LOOP				; repeat "subset count" times
	  IF (GMDC version = 4)
	    WORD	model subset reference
	  ELSE IF (GMDC version < 4)
	    DWORD	model subset reference
	ENDLOOP
ENDLOOP

The last subset version maps the value used in the 0xFBD70111 (Bone Assignments) section to the standard values used by other parts of the game. For example, a bone value of 4(from P1) would be used as an index to retrieve a value from the fifth element of this array that represents the real bone number, as used in other parts of the game. In creating a new GMDC, making an array that uses a series of 0, 1, 2, 3, ... makes a legitimate map, so long as you use the "real" bone values in the Bone Assignments section.

The Model (P4) Section

There is only one model per GMDC, so the next section does not have an outer loop. The model contains information to rotate and transform the mesh, as well as a bounding mesh for the whole model. The mesh stored in the model section is composed of vertecies and faces composed of those vertices. In the face list, each sequential set of 3 values represents a face. The face is defined by using the vertices at the positions in the vertex list specified in the 3 face values.

DWORD		transform block count
LOOP					; repeat "transform block count" times
  DWORD		quaternion x		; Rotation quaternion: x plane amount
  DWORD		quaternion y		; Rotation quaternion: y plane amount
  DWORD		quaternion z		; Rotation quaternion: z plane amount
  DWORD		quaternion w		; Rotation quaternion: focal point

  DWORD		transform x		; Transform: x amount
  DWORD		transform y		; Transform: y amount
  DWORD		transform x		; Transform: z amount
ENDLOOP

DWORD		name pairs count
LOOP					; repeat "name pairs count" times (this is equal to the number of targets located in P1 (the first target is usually a pair of NULL names).
  7BITSTR	blend group name
  7BITSTR	assigned element name
ENDLOOP

DWORD		vertex count		; if zero, no mesh, continue to next section (used when model has no bones or joints)
IF (vertex count > 0)
  DWORD		face count

  LOOP					; repeat "vertex count" times
	DWORD	vertex x
	DWORD	vertex y
	DWORD	vertex z
  ENDLOOP

  LOOP					; repeat "face count" times
	IF (GMDC version = 4)
	  WORD
	ELSE IF (GMDC version < 4)
	  DWORD
  END LOOP

You can reduce the resultant size if this part by consolidating duplicate vertices (since normals and UVs are not elements), as long as you adjust the correct index value in the face reference list.

The "Name Pairs" are used by the game to identify links to the morphs for animation purposes. Inclusion of full morph data without duplicating the name pairs referenced by the animations will not render.

The Subset (P5) Section

Subsets are parts of the full mesh, and are associated with bones (joints) and other components of the model.

DWORD           subset count  ; a standard Sims2 skeleton has 65 joints, although many are unused. Other values indicate animated meshes with joint or target areas, but are processed in the same manner.
LOOP            ; repeat 'subset count' times
  DWORD		vertex count		; if zero, blank section
  IF (vertex count > 0)
	DWORD		face count
	
	LOOP					; repeat "vertex count" times
  	DWORD	vertex x
	DWORD	vertex y
	DWORD	vertex z
	ENDLOOP

	LOOP					; repeat "face count" times
  	IF (GMDC version = 4)
	  WORD
	ELSE IF (GMDC version < 4)
	  DWORD
	END LOOP
END LOOP
Personal tools
Namespaces

Variants
Actions
Navigation
game select
Toolbox