Difference between revisions of "Sims 3:0x015A1849"

From SimsWiki
Jump to: navigation, search
Line 1: Line 1:
 +
==Header==
 +
 +
Start with the RCOL Header: [[Sims 3:RCOL]]
 +
 +
Then the GEOM chunk:
 
<pre>
 
<pre>
{rcol header}
 
 
long    'GEOM'
 
long    'GEOM'
 
long    Version              // 5
 
long    Version              // 5
Line 19: Line 23:
 
long  NumFacePoints                // means faces*3
 
long  NumFacePoints                // means faces*3
 
word [NumFacePoints][3]        // standard face index (three unsigned words per face) for 2-byte FaceFmt
 
word [NumFacePoints][3]        // standard face index (three unsigned words per face) for 2-byte FaceFmt
 +
 
----------
 
----------
 
Tail:
 
Tail:
Line 27: Line 32:
 
block references[numtgi]  // each is a TGI[sub]64[/sub], a 16-byte quantity, so size is 16*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
 
                                     // references are to DDS textures and BONE file
 +
</pre>
  
==========================
+
==VertexFormat==
VertexFormat:
+
 
(for each vertex count)
+
For each vertex count:
 +
<pre>
 
long  DataType
 
long  DataType
 
long  SubType
 
long  SubType
Line 42: Line 49:
 
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)
+
7  == TagVal (4 packed bytes) -- colour channel data
 
10 == VertexID (long == 4 bytes)
 
10 == VertexID (long == 4 bytes)
  
Line 49: Line 56:
 
2 == bytes
 
2 == bytes
 
4 == long
 
4 == long
 
+
</pre>
 
You calculate the offset of each element from the sum of the previous BytesPerElement
 
You calculate the offset of each element from the sum of the previous BytesPerElement
==========================
 
Known Vertex Format Examples:
 
  
Format 3 VertexData is:
+
==Reading Vertex Data Blocks==
float PositionDelta[3]
+
float NormalDelta[3]
+
long VertID
+
[28 bytes per vertex]
+
  
Format 6 VertexData is:
+
For each vertex, you need to loop through the VertexFormat as defined, and read the information in order.
float    Position[3]      // XYZ, Y is UP
+
float    Normal[3]
+
float    UV[2]
+
long    Bone Assignments  // 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 VertexData is:
+
The order can be completely arbitary, and varied in size.
float    Position[3]      // XYZ, Y is UP
+
float    Normal[3]
+
float    UV[2]
+
long    Bone Assignments  // packed byte array
+
float    Weights[4]
+
long    VertID
+
float    Tangent Normal[3]
+
[68 bytes per vertex]
+
  
Format 8 VertexData is:
+
Here is some example code in c# to do so:
float   Position[3]     // XYZ, Y is UP
+
<pre>
float    Normal[3]
+
            for (int i = 0; i < numVerts; i++)
float   UV[2]
+
            {
long    Tagval          // color channel bytes
+
 
long    Bone Assignments // a packed byte array
+
                for (int j = 0; j < vertexFormats.Count; j++)
float   Weights[4]
+
                {
long    VertID
+
                    float x = 0;
float   Tangent Normal[3]
+
                    float y = 0;
[72 bytes per vertex]
+
                    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;
 +
 
 +
                    }
 +
 
 +
                }
 +
            }
 
</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.

Revision as of 15:01, 25 June 2009

Header

Start with the RCOL Header: Sims 3:RCOL

Then the GEOM chunk:

long     'GEOM'
long     Version              // 5
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

----------
Tail:
long  flags
long  count1
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

VertexFormat

For each vertex count:

long   DataType
long   SubType
byte   BytesPerElement

For DataType:
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
1 == floats
2 == bytes
4 == long

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

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.

Personal tools
Namespaces

Variants
Actions
Navigation
game select
Toolbox