Difference between revisions of "Sims 3:0x015A1849"

From SimsWiki
Jump to: navigation, search
 
(51 intermediate revisions by 7 users not shown)
Line 1: Line 1:
==Header==
+
{{TS3AdvancedModdingHeader}}
 +
{{TS3Resource
 +
|name=Body Geometry - GEOM
 +
|typeid= 0x015A1849
 +
|expansion=The Sims 3
 +
}}
 +
<br clear="all">
 +
__NOTOC__
  
Start with the RCOL Header: [[Sims 3:RCOL]]
+
=Overview=
 +
This is a [[Sims 3:RCOL]] chunk for Body Geometry.
 +
=Format=
 +
DWORD 'GEOM'
 +
DWORD Version // 5
 +
DWORD tgi offset // see [[Sims 3:Key table]]
 +
DWORD tgi size // see [[Sims 3:Key table]]
 +
DWORD EmbeddedID // if no embedded material, will be 0
 +
                                // otherwise, if the "morphskin" or "morphskincloth" shaders are used in the material, it will be the FNV32 hash of "SimSkin",
 +
                                // and if the "morpheye" shader is used, it will be the FNV32 hash of "SimEyes"
 +
--if (EmbeddedID != 0):
 +
DWORD ChunkSize
 +
--insert MTNF chunk // follows the same format of MTNF from [[Sims 3:0x01D0E75D]], starting at the 'MTNF' tag
 +
 +
DWORD mergeGroup
 +
DWORD sortOrder                // often zero
 +
 +
DWORD NumVerts // Number of vertices
 +
DWORD FCount // Number of vertex elements
 +
--repetition FCount:
 +
--insert Vertex Format // [[#Vertex_Format|see below]]
 +
--repetition NumVerts:
 +
--insert Vertex Data // [[#Vertex_Data|see below]]
 +
 +
DWORD ItemCount                // will usually be 1 (hardcoded in pipeline exporter), but sometimes other numbers
 +
--repetition ItemCount:
 +
BYTE BytesPerFacePoint
 +
 +
DWORD NumFacePoints
 +
--repetition NumFacePoints:
 +
BYTE[BytesPerFacePoint] // Given that ItemCount is 1, BytesPerFacePoint is 2, this is a list of WORDs
 +
// Each set of three forms a face.
 +
 +
DWORD index // to a [[Sims_3:0x00AE6C67|Skin Controller(0x00AE6C67)]]
 +
 +
DWORD count1
 +
--repetition count1:
 +
DWORD bonehasharray // 32-bit hash of used bone names.
 +
 +
--insert TGI Block List // see [[Sims 3:Key table]]
 +
==Quirks==
 +
This format is packaged in a [[Sims_3:RCOL|RCOL]] container, however doesn't adhere to the same standards that most do.
  
Then the GEOM chunk:
+
* Declares a null resource key(00000000:00000000:0000000000000000) making it harder for tools to generically infer what type it is.
<pre>
+
* Contains a "Standard" [[Sims_3:Key_table|TGI List]], rather than using the built-in [[Sims_3:RCOL|RCOL]] external references
long    'GEOM'
+
* Due to using the standard list rather than the scoped [[Sims_3:RCOL|RCOL]] list, references made in the [[Sims_3:0x01D0E75D|MTNF]] are interpreted differently
long    Version              // 5
+
* Pets EP introduced animal meshes that tend to have more than 1 uv-channel per mesh(uncommon or non-existent in previous human meshes)
long    TailOffset
+
long    TailSectionSize  // (0x14, 0x44 observed)
+
long    EmbeddedID    //(0, 0x548394B9 observed)
+
if(EmbeddedID!=0) {
+
  long ChunkSize
+
  byte[ChunkSize]      // starts with 'MTNF'
+
  }
+
long  0                      //unknown purpose
+
long  0                      // unknown purpose
+
long  NumVerts
+
long  FCount                            // was named Version, but is number of vertex elements
+
block VertexFormat[FCount]     // long, long, byte; documented below 9 bytes/vertex-element-count
+
struct VertexData[NumVerts]     // follows vertex format block, documented below
+
block  FaceFmt                        // long ItemCount, byte BytesPerFacepoint
+
long  NumFacePoints                // means faces*3
+
word [NumFacePoints][3]         // standard face index (three unsigned words per face) for 2-byte FaceFmt
+
  
----------
+
==Vertex Format==
Tail:
+
  DWORD DataType
long flags
+
  DWORD SubType
long count1
+
  BYTE BytesPerElement
long bonehasharray[count1]  // 32-bit hash of used bone names.
+
long  numtgi
+
block references[numtgi]  // each is a TGI[sub]64[/sub], a 16-byte quantity, so size is 16*numtgi
+
                                    // references are to DDS textures and BONE file
+
</pre>
+
  
==VertexFormat==
+
===DataType===
 +
{| class="wikitable" border="1"
 +
|-
 +
|1||Position||(3 float == 12 bytes)
 +
|-
 +
|2||Normal||(3 float == 12 bytes)
 +
|-
 +
|3||UV||(2 float == 8 bytes)
 +
|-
 +
|4||Bone Assignment||(4 bytes)
 +
|-
 +
|5||Weights||(4 float == 16 bytes)
 +
|-
 +
|6||Tangent Normal||(3 float == 12 bytes)
 +
|-
 +
|7||TagVal||(4 packed bytes) -- colour channel data
 +
|-
 +
|10||VertexID||(dword == 4 bytes)
 +
|-
 +
|}
  
For each vertex count:
+
===SubType===
<pre>
+
{| class="wikitable" border="1"
long  DataType
+
|-
long  SubType
+
|1||floats
byte  BytesPerElement
+
|-
 +
|2||bytes
 +
|-
 +
|3||color
 +
|-
 +
|4||dword
 +
|-
 +
|}
 +
You calculate the offset of each element from the sum of the previous BytesPerElement
  
For DataType:
+
Based on contributions from karybdis and atavera
1  == Position (3 float == 12 bytes)
+
2  == Normal  (3 float == 12 bytes)
+
3  == UV      (2 float == 8 bytes)
+
4  == Bone Assignment (long == 4 bytes)
+
5  == Weights (4 float == 16 bytes)
+
6  == Tangent Normal (3 float == 12 bytes)
+
7  == TagVal (4 packed bytes) -- colour channel data
+
10 == VertexID (long == 4 bytes)
+
  
For SubType
+
==Vertex Data==
1 == floats
+
<!--Data for the known Vertex Formats follows.
2 == bytes
+
===Format 3===
4 == long
+
float PositionDelta[3]
</pre>
+
float NormalDelta[3]
You calculate the offset of each element from the sum of the previous BytesPerElement
+
long VertID
 +
[28 bytes per vertex]
  
==Reading Vertex Data Blocks==
+
===Format 6===
 +
float Position[3] // XYZ, Y is UP
 +
float Normal[3]
 +
float UV[2]
 +
uchar Bone Assignments[4] // a packed byte array, parsed lo order to high order
 +
float Weights[4] // first weight is lowest order byte of assignments, 0.0 (0L) weights are unassigned slots
 +
float Tangent Normal[3]
 +
[64 bytes per vertex]
 +
 
 +
===Format 7===
 +
float Position[3] // XYZ, Y is UP
 +
float Normal[3]
 +
float UV[2]
 +
uchar Bone Assignments[4] // packed byte array
 +
float Weights[4]
 +
long VertID
 +
float Tangent Normal[3]
 +
[68 bytes per vertex]
 +
 
 +
===Format 7===
 +
float Position[3] // XYZ, Y is UP
 +
float Normal[3]
 +
float UV[2]
 +
long Tagval // color channel bytes
 +
uchar Bone Assignments[4] // a packed byte array
 +
float Weights[4]
 +
long VertID
 +
float Tangent Normal[3]
 +
[72 bytes per vertex]-->
 +
 
 +
===Reading Vertex Data Blocks===
  
 
For each vertex, you need to loop through the VertexFormat as defined, and read the information in order.
 
For each vertex, you need to loop through the VertexFormat as defined, and read the information in order.
Line 67: Line 144:
 
Here is some example code in c# to do so:
 
Here is some example code in c# to do so:
 
<pre>
 
<pre>
            for (int i = 0; i < numVerts; i++)
+
for (int i = 0; i < numVerts; i++)
            {
+
{
 
+
for (int j = 0; j < vertexFormats.Count; j++)
                for (int j = 0; j < vertexFormats.Count; j++)
+
{
                {
+
float x = 0;
                    float x = 0;
+
float y = 0;
                    float y = 0;
+
float z = 0;
                    float z = 0;
+
vertexFormat vf = (vertexFormat)vertexFormats[j];
 
+
switch (vf.dataType)
                    vertexFormat vf = (vertexFormat)vertexFormats[j];
+
{
                    switch (vf.dataType)
+
case 1:
                    {
+
x = reader.ReadSingle();
                        case 1:
+
z = reader.ReadSingle();
                            x = reader.ReadSingle();
+
y = reader.ReadSingle();
                            z = reader.ReadSingle();
+
sb.AppendLine("  XYZ: " + x.ToString() + " " + y.ToString() + " " + z.ToString() );
                            y = reader.ReadSingle();
+
break;
                            sb.AppendLine("  XYZ: " + x.ToString() + " " + y.ToString() + " " + z.ToString() );
+
case 2:
                            break;
+
x = reader.ReadSingle();
                        case 2:
+
z = reader.ReadSingle();
                            x = reader.ReadSingle();
+
y = reader.ReadSingle();
                            z = reader.ReadSingle();
+
sb.AppendLine("  Normal: " + x.ToString() + " " + y.ToString() + " " + z.ToString() );
                            y = reader.ReadSingle();
+
break;
                            sb.AppendLine("  Normal: " + x.ToString() + " " + y.ToString() + " " + z.ToString() );
+
case 3:
                            break;
+
float u = reader.ReadSingle();
                        case 3:
+
float v = reader.ReadSingle();
                            float u = reader.ReadSingle();
+
sb.AppendLine("  UV: " + u.ToString() + " " + v.ToString() );
                            float v = reader.ReadSingle();
+
break;
                            sb.AppendLine("  UV: " + u.ToString() + " " + v.ToString() );
+
case 4:
                            break;
+
sb.AppendLine("  Bone: " + reader.ReadUInt32().ToString() );
                        case 4:
+
break;
                            sb.AppendLine("  Bone: " + reader.ReadUInt32().ToString() );
+
case 5:
                            break;
+
float w1 = reader.ReadSingle();
                        case 5:
+
float w2 = reader.ReadSingle();
                            float w1 = reader.ReadSingle();
+
float w3 = reader.ReadSingle();
                            float w2 = reader.ReadSingle();
+
float w4 = reader.ReadSingle();
                            float w3 = reader.ReadSingle();
+
sb.AppendLine("  Weights: " + w1.ToString() + " " + w2.ToString() + " "
                            float w4 = reader.ReadSingle();
+
+ w3.ToString() + " " + w4.ToString() );
                            sb.AppendLine("  Weights: " + w1.ToString() + " " + w2.ToString() + " " + w3.ToString() + " " + w4.ToString() );
+
break;
                            break;
+
case 6:
                        case 6:
+
x = reader.ReadSingle();
                            x = reader.ReadSingle();
+
z = reader.ReadSingle();
                            z = reader.ReadSingle();
+
y = reader.ReadSingle();
                            y = reader.ReadSingle();
+
sb.AppendLine("  Tangent Normal: " + x.ToString() + " " + y.ToString() + " " + z.ToString() );
                            sb.AppendLine("  Tangent Normal: " + x.ToString() + " " + y.ToString() + " " + z.ToString() );
+
break;
                            break;
+
case 7:
                        case 7:
+
// Note, not splitting this up yet just reading an int
                            // Note, not splitting this up yet just reading an int
+
sb.AppendLine("  TagVal: " + reader.ReadUInt32().ToString() );
                            sb.AppendLine("  TagVal: " + reader.ReadUInt32().ToString() );
+
break;
                            break;
+
case 10:
                        case 10:
+
sb.AppendLine("  VertexID: " + reader.ReadUInt32().ToString() );
                            sb.AppendLine("  VertexID: " + reader.ReadUInt32().ToString() );
+
break;
                            break;
+
}
 
+
}
                    }
+
}
 
+
                }
+
            }
+
 
</pre>
 
</pre>
  
 
Note that basically we just look through the VertexFormat, and read the data in order.  There is no fixed "vertex format" version, it's all controlled via the vertexformat data.
 
Note that basically we just look through the VertexFormat, and read the data in order.  There is no fixed "vertex format" version, it's all controlled via the vertexformat data.
 +
 +
{{TS3AdvancedModdingHeader}}

Latest revision as of 04:04, 26 January 2012

Modding Reference by Category

Sims 3 :DBPF | File Types | RCOL(Scene) | Catalog Resource | String Table | Key Table | TS3 Programmer's Reference 

Body Geometry - GEOM
TypeID:0x015A1849
Game Version:The Sims 3




[edit] Overview

This is a Sims 3:RCOL chunk for Body Geometry.

[edit] Format

DWORD 'GEOM'
DWORD Version			// 5
DWORD tgi offset		// see Sims 3:Key table
DWORD tgi size			// see Sims 3:Key table
DWORD EmbeddedID		// if no embedded material, will be 0
                                // otherwise, if the "morphskin" or "morphskincloth" shaders are used in the material, it will be the FNV32 hash of "SimSkin",
                                // and if the "morpheye" shader is used, it will be the FNV32 hash of "SimEyes"
--if (EmbeddedID != 0):
	DWORD ChunkSize
	--insert MTNF chunk	// follows the same format of MTNF from Sims 3:0x01D0E75D, starting at the 'MTNF' tag

DWORD mergeGroup
DWORD sortOrder                 // often zero

DWORD NumVerts			// Number of vertices
DWORD FCount			// Number of vertex elements
--repetition FCount:
	--insert Vertex Format	// see below
--repetition NumVerts:
	--insert Vertex Data	// see below

DWORD ItemCount                 // will usually be 1 (hardcoded in pipeline exporter), but sometimes other numbers
--repetition ItemCount:
	BYTE BytesPerFacePoint

DWORD NumFacePoints
--repetition NumFacePoints:
	BYTE[BytesPerFacePoint]	// Given that ItemCount is 1, BytesPerFacePoint is 2, this is a list of WORDs
				// Each set of three forms a face.

DWORD index 			// to a Skin Controller(0x00AE6C67)

DWORD count1
--repetition count1:
	DWORD bonehasharray	// 32-bit hash of used bone names.

--insert TGI Block List	// see Sims 3:Key table

[edit] Quirks

This format is packaged in a RCOL container, however doesn't adhere to the same standards that most do.

  • Declares a null resource key(00000000:00000000:0000000000000000) making it harder for tools to generically infer what type it is.
  • Contains a "Standard" TGI List, rather than using the built-in RCOL external references
  • Due to using the standard list rather than the scoped RCOL list, references made in the MTNF are interpreted differently
  • Pets EP introduced animal meshes that tend to have more than 1 uv-channel per mesh(uncommon or non-existent in previous human meshes)

[edit] Vertex Format

DWORD DataType
DWORD SubType
BYTE BytesPerElement

[edit] DataType

1 Position (3 float == 12 bytes)
2 Normal (3 float == 12 bytes)
3 UV (2 float == 8 bytes)
4 Bone Assignment (4 bytes)
5 Weights (4 float == 16 bytes)
6 Tangent Normal (3 float == 12 bytes)
7 TagVal (4 packed bytes) -- colour channel data
10 VertexID (dword == 4 bytes)

[edit] SubType

1 floats
2 bytes
3 color
4 dword

You calculate the offset of each element from the sum of the previous BytesPerElement

Based on contributions from karybdis and atavera

[edit] Vertex Data

[edit] Reading Vertex Data Blocks

For each vertex, you need to loop through the VertexFormat as defined, and read the information in order.

The order can be completely arbitary, and varied in size.

Here is some example code in c# to do so:

for (int i = 0; i < numVerts; i++)
{
	for (int j = 0; j < vertexFormats.Count; j++)
	{
		float x = 0;
		float y = 0;
		float z = 0;
		vertexFormat vf = (vertexFormat)vertexFormats[j];
		switch (vf.dataType)
		{
			case 1:
				x = reader.ReadSingle();
				z = reader.ReadSingle();
				y = reader.ReadSingle();
				sb.AppendLine("  XYZ: " + x.ToString() + " " + y.ToString() + " " + z.ToString() );
				break;
			case 2:
				x = reader.ReadSingle();
				z = reader.ReadSingle();
				y = reader.ReadSingle();
				sb.AppendLine("  Normal: " + x.ToString() + " " + y.ToString() + " " + z.ToString() );
				break;
			case 3:
				float u = reader.ReadSingle();
				float v = reader.ReadSingle();
				sb.AppendLine("  UV: " + u.ToString() + " " + v.ToString() );
				break;
			case 4:
				sb.AppendLine("  Bone: " + reader.ReadUInt32().ToString() );
				break;
			case 5:
				float w1 = reader.ReadSingle();
				float w2 = reader.ReadSingle();
				float w3 = reader.ReadSingle();
				float w4 = reader.ReadSingle();
				sb.AppendLine("  Weights: " + w1.ToString() + " " + w2.ToString() + " "
					+ w3.ToString() + " " + w4.ToString() );
				break;
			case 6:
				x = reader.ReadSingle();
				z = reader.ReadSingle();
				y = reader.ReadSingle();
				sb.AppendLine("  Tangent Normal: " + x.ToString() + " " + y.ToString() + " " + z.ToString() );
				break;
			case 7:
				// Note, not splitting this up yet just reading an int
				sb.AppendLine("  TagVal: " + reader.ReadUInt32().ToString() );
				break;
			case 10:
				sb.AppendLine("  VertexID: " + reader.ReadUInt32().ToString() );
				break;
		}
	}
}

Note that basically we just look through the VertexFormat, and read the data in order. There is no fixed "vertex format" version, it's all controlled via the vertexformat data.

Modding Reference by Category

Sims 3 :DBPF | File Types | RCOL(Scene) | Catalog Resource | String Table | Key Table | TS3 Programmer's Reference 

Personal tools
Namespaces

Variants
Actions
Navigation
game select
Toolbox