Difference between revisions of "Skin PLG (RW Section)"

From GTAMods Wiki
Jump to navigation Jump to search
Line 1: Line 1:
{{Stub}}
 
 
 
{{cleanup-rewrite}}
 
{{cleanup-rewrite}}
  
Line 16: Line 14:
 
==Structure==
 
==Structure==
  
UINT8  numBones (numMatrices)
+
The structure starts with a 4-byte value, where each individual byte contains a counter and the last byte being used for padding.
UINT8  numUsedBones
 
UINT8  maxWeightsPerVertex
 
UINT8  padding (unused)
 
UINT8  bonesUsed[numUsedBones]
 
UINT8  vertexBoneIndices[geometry->numVertices][4]
 
FLOAT  vertexBoneWeights[geometry->numVertices][4]
 
#repeat for numMatrices
 
    #if RwVer < 3.7.0.0 && maxWeightsPerVertex == 0
 
    INT32  unused 4b value, possibly a leftover from old RW versions (0xDEADDEAD)
 
    #endif
 
    FLOAT  skinToBoneMatrix[4][4]
 
#endrepeat
 
// Split data
 
UINT32  boneLimit
 
UINT32  numMeshes
 
UINT32  numRLE
 
#if numMeshes > 0
 
UINT8  meshBoneRemapIndices[numBones]
 
UINT16  meshBoneRLECount[numMeshes]
 
UINT16  meshBoneRLE[numRLE]
 
#endif
 
  
;numBones (numMatrices)
+
1b - BYTE - numBones: Overall number of bones in the skeleton.
:Number of bones attached to the skin, also the number of inverse matrices (see '''skinToBoneMatrices''').
+
1b - BYTE - usedBones: Number of bones affected by the skin.
 +
1b - BYTE - maxVertexWeights: Maximum number of non-zero weights per vertex.
 +
1b - BYTE - Padding
  
;numUsedBones
+
The third counter can be any value from 0 to 4. If it equals zero, the engine attempts to figure out this number by looking into each weight array (see below) and counting the non-zero weights. It then takes the largest number from the results.  
:Number of bones which influence vertices, that is those bones which have at least a non-zero weight. If this value is zero, RW will try to find "used" bones automatically.
 
  
;maxWeightsPerVertex
+
The counters are followed by multiple arrays that contain information about how vertices of a mesh relate to bones. The number of vertices is obtained from the parent geometry section.
:Overall number of maximum non-zero weights per vertex. If zero, RW will find this value automatically.
 
  
;bonesUsed
+
Xb - BYTE[usedBones]      - A list of bone indices, that are affected by the skin.
:Indices list of the significant bones connected to the skin (see '''numUsedBones''').
+
Xb - BYTE[numVertices][4]  - A list that maps all vertices to (up to) four bones of the skeleton.
 +
Xb - FLOAT[numVertices]    - A list that weights each vertex-bone mapping.
  
;vertexBoneIndices
+
Next, a list of transformation matrices for each bone is provided:
:Vertex bone indices are represented with 4 bone indices per each vertex.
 
  
;vertexBoneWeights
+
Xb - RpBone[numBones]      - Bone transformations
:Vertex bone weights are represented with ''RwMatrixWeights'' structure per each vertex. RW docs says it's necessary to keep the order within 4 weight values (from higher to lower), but even some example models have different ordering.
 
  
;skinToBoneMatrices
+
Where RpBone is defined as follows:
:These are inverse matrices represented with ''RwMatrix'' structure.
 
  
;boneLimit
+
<source lang="c">
 +
struct RpBone {
 +
    DWORD unused;           // Only stored if version < 0x37000 && maxVertexWeights == 0
 +
    FLOAT transform[4][4];  // Skin-to-Bone transform.
 +
};
 +
</source>
  
;numMeshes
+
=== Run-Length Encoding (RLE) ===
  
;numRLE
+
The skin skin may be followed by a [https://en.wikipedia.org/wiki/Run-length_encoding|Run-length encoded] list of index mappings:
  
;meshBoneRemapIndices
+
// Split data
 +
UINT32  boneLimit
 +
UINT32  numMeshes
 +
UINT32  numRLE
  
;meshBoneRLECount
+
#if numMeshes > 0
 +
UINT8  meshBoneRemapIndices[numBones]
 +
UINT16  meshBoneRLECount[numMeshes]
 +
UINT16  meshBoneRLE[numRLE]
 +
#endif
  
;meshBoneRLE
 
  
 
{{N|SA|VC|3}}
 
{{N|SA|VC|3}}

Revision as of 18:51, 11 September 2020

40px-Ambox rewrite orange.svg.png This article may need to be rewritten.
Please help improve this article. The discussion page may contain suggestions.
Skin PLG
RenderWare Stream Section
Vendor Criterion Games
Module Toolkit
Module ID 0x000001
Identifier 0x16
Chunk ID 0x00000116
Versions All
Hierarchy
Parents:
Geometry (Extension)
Children:
None
Extensions:
None
File Format

Skin is an additional RenderWare plugin for geometry section. It is used to hold information about skinned model.

Structure

The structure starts with a 4-byte value, where each individual byte contains a counter and the last byte being used for padding.

1b - BYTE - numBones: Overall number of bones in the skeleton.
1b - BYTE - usedBones: Number of bones affected by the skin.
1b - BYTE - maxVertexWeights: Maximum number of non-zero weights per vertex.
1b - BYTE - Padding

The third counter can be any value from 0 to 4. If it equals zero, the engine attempts to figure out this number by looking into each weight array (see below) and counting the non-zero weights. It then takes the largest number from the results.

The counters are followed by multiple arrays that contain information about how vertices of a mesh relate to bones. The number of vertices is obtained from the parent geometry section.

Xb - BYTE[usedBones]       - A list of bone indices, that are affected by the skin.
Xb - BYTE[numVertices][4]  - A list that maps all vertices to (up to) four bones of the skeleton.
Xb - FLOAT[numVertices]    - A list that weights each vertex-bone mapping.

Next, a list of transformation matrices for each bone is provided:

Xb - RpBone[numBones]      - Bone transformations

Where RpBone is defined as follows:

struct RpBone {
    DWORD unused;            // Only stored if version < 0x37000 && maxVertexWeights == 0
    FLOAT transform[4][4];   // Skin-to-Bone transform.
};

Run-Length Encoding (RLE)

The skin skin may be followed by a encoded list of index mappings:

// Split data
UINT32  boneLimit
UINT32  numMeshes
UINT32  numRLE 
#if numMeshes > 0
UINT8   meshBoneRemapIndices[numBones]
UINT16  meshBoneRLECount[numMeshes]
UINT16  meshBoneRLE[numRLE]
#endif