Difference between revisions of "Sims 3:0x015A1849"

From SimsWiki
Jump to: navigation, search
(DataType)
(DataType)
Line 46: Line 46:
 
===DataType===
 
===DataType===
 
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
|+
+
|-
 
|1||Position||(3 float == 12 bytes)
 
|1||Position||(3 float == 12 bytes)
|+
+
|-
 
|2||Normal||(3 float == 12 bytes)
 
|2||Normal||(3 float == 12 bytes)
|+
+
|-
 
|3||UV||(2 float == 8 bytes)
 
|3||UV||(2 float == 8 bytes)
|+
+
|-
 
|4||Bone Assignment||(4 packed integers == 4 bytes)
 
|4||Bone Assignment||(4 packed integers == 4 bytes)
|+
+
|-
 
|5||Weights||(4 float == 16 bytes)
 
|5||Weights||(4 float == 16 bytes)
|+
+
|-
 
|6||Tangent Normal||(3 float == 12 bytes)
 
|6||Tangent Normal||(3 float == 12 bytes)
|+
+
|-
 
|7||TagVal||(4 packed bytes) -- colour channel data
 
|7||TagVal||(4 packed bytes) -- colour channel data
|+
+
|-
 
|10||VertexID||(long == 4 bytes)
 
|10||VertexID||(long == 4 bytes)
|+
+
|-
 
|}
 
|}
  

Revision as of 20:50, 4 May 2010

Tutorials by Category

CAS | Patterns | Objects | Building | Worlds | Modding | Modding Reference 

Contents

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		// 0, 0x548394B9 (FNV32 of "SimSkin") observed
--if (EmbeddedID != 0):
	DWORD ChunkSize
	--insert MTNF chunk	// follows the same format of MTNF from Sims 3:0x01D0E75D, starting at the 'MTNF' tag

DWORD
DWORD

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
--repetition ItemCount:
	BYTE BytesPerFacePoint

DWORD NumFacePoints		// means faces*3
--repetition NumFacePoints:
	WORD[3]			// standard face index (three unsigned words per face) for 2-byte FaceFmt

DWORD flags

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

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

Vertex Format

DWORD DataType
DWORD SubType
BYTE BytesPerElement

DataType

1 Position (3 float == 12 bytes)
2 Normal (3 float == 12 bytes)
3 UV (2 float == 8 bytes)
4 Bone Assignment (4 packed integers == 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)

SubType

1 floats
2 bytes
4 long

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

Based on contributions from karybdis and atavera

Vertex Data

Data for the known Vertex Formats follows.

Format 3

float	PositionDelta[3]
float	NormalDelta[3]
long	VertID

[28 bytes per vertex]

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.

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.

Tutorials by Category

CAS | Patterns | Objects | Building | Worlds | Modding | Modding Reference 

Personal tools
Namespaces

Variants
Actions
Navigation
game select
Toolbox