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

From GTAMods Wiki
Jump to navigation Jump to search
m (Fix weight mapping to include all 4 possible vertex weights)
 
(7 intermediate revisions by one other user not shown)
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
+
  1b - BYTE - numBones: Overall number of bones in the skeleton.
  UINT8  padding (unused)
+
  1b - BYTE - usedBones: Number of bones affected by the skin.
UINT8  bonesUsed[numUsedBones]
+
  1b - BYTE - maxVertexWeights: Maximum number of non-zero weights per vertex.
  UINT8  vertexBoneIndices[geometry->numVertices][4]
+
  1b - BYTE - Padding
  FLOAT  vertexBoneWeights[geometry->numVertices][4]
+
 
  #repeat for numMatrices
+
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.
    #if RwVer < 3.7.0.0 && maxWeightsPerVertex == 0
+
 
    INT32  unused 4b value, possibly a leftover from old RW versions (0xDEADDEAD)
+
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.
    #endif
+
 
    FLOAT   skinToBoneMatrix[4][4]
+
  Xb - BYTE[usedBones]       - A list of bone indices, that are affected by the skin.
#endrepeat
+
  Xb - BYTE[numVertices][4]  - A list that maps all vertices to (up to) four bones of the skeleton.
// Split data
+
Xb - FLOAT[numVertices][4] - A list that weights each vertex-bone mapping.
UINT32  boneLimit
+
 
  UINT32  numMeshes
+
Next, a list of transformation matrices for each bone is provided:
UINT32  numRLE
+
 
#if numMeshes > 0
+
  Xb - Bone[numBones]     - Bone transformations
UINT8  meshBoneRemapIndices[numBones]
 
UINT16  meshBoneRLECount[numMeshes]
 
UINT16  meshBoneRLE[numRLE]
 
#endif
 
  
;numBones (numMatrices)
+
Where <code>Bone</code> is defined as follows:
:Number of bones attached to the skin, also the number of inverse matrices (see '''skinToBoneMatrices''').
 
  
;numUsedBones
+
<source lang="c">
: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.
+
struct Bone {
 +
    DWORD unused;           // Only stored if version < 0x37000 && maxVertexWeights == 0
 +
    FLOAT transform[4][4];  // Skin-to-Bone transform.
 +
};
 +
</source>
  
;maxWeightsPerVertex
+
=== Bone Group Remapping ===
:Overall number of maximum non-zero weights per vertex. If zero, RW will find this value automatically.
 
  
;bonesUsed
+
As indicated above by the <code>usedBones</code> counter, a mesh (stored within the parent [[Geometry (RW Section)|geometry]]) may not affected by all bones in the skeleton. Some platforms only support a certain number of bones at once. Thus RenderWare can split up a skeleton into groups, where group-indices must be mapped to the actual bone indices. Those groups are stored in a [https://en.wikipedia.org/wiki/Run-length_encoding run-length encoded] fashion.  
:Indices list of the significant bones connected to the skin (see '''numUsedBones''').
 
  
;vertexBoneIndices
+
For all RenderWare-based GTA games, this feature is typically unused. Thus the following values are usually set to zero.
:Vertex bone indices are represented with 4 bone indices per each vertex.
 
  
;vertexBoneWeights
+
4b - DWORD  - boneLimit: the maximum number of bones per group. (?)
: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.
+
4b - DWORD  - numGroups: the number of bone groups.
 +
4b - DWORD  - numRemaps: the number of bone remappings.
  
;skinToBoneMatrices
+
If there are any groups (<code>numGroups > 0</code>), the counters are followed by three arrays:
:These are inverse matrices represented with ''RwMatrix'' structure.
 
  
;boneLimit
+
Xb - BYTE[numBones]          - boneRemapIndices: an array of all bone indices where each element identifies a bone of the skeleton
 +
Xb - BoneGroup[numGroups]    - boneGroups (see below)
 +
Xb - BoneRemap[numRemaps]    - boneRemaps (see below)
  
;numMeshes
+
Where <code>BoneGroup</code> and <code>BoneRemap</code> is defined as follows:
  
;numRLE
+
<source lang="c">
 +
struct BoneGroup {
 +
    BYTE firstBone;            // Index of first bone in boneRemaps array.
 +
    BYTE numBones;            // Number of bones in boneRemaps that define the mesh (starting from firstBone).
 +
};
  
;meshBoneRemapIndices
+
struct BoneRemap {
 +
    BYTE boneIndex;           // Index of the bone in boneRemapIndices.
 +
    BYTE indices;              // The number of elements of the boneRemapIndices that are included by the group in boneRemapIndices.
 +
};
 +
</source>
  
;meshBoneRLECount
+
== See also ==
  
;meshBoneRLE
+
* [[IFP|IFP Animation Package]]
  
 
{{N|SA|VC|3}}
 
{{N|SA|VC|3}}
 +
 +
[[Category:Pedestrian_Formats]]

Latest revision as of 15:51, 25 October 2024

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][4] - A list that weights each vertex-bone mapping.

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

Xb - Bone[numBones]      - Bone transformations

Where Bone is defined as follows:

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

Bone Group Remapping

As indicated above by the usedBones counter, a mesh (stored within the parent geometry) may not affected by all bones in the skeleton. Some platforms only support a certain number of bones at once. Thus RenderWare can split up a skeleton into groups, where group-indices must be mapped to the actual bone indices. Those groups are stored in a run-length encoded fashion.

For all RenderWare-based GTA games, this feature is typically unused. Thus the following values are usually set to zero.

4b - DWORD  - boneLimit: the maximum number of bones per group. (?)
4b - DWORD  - numGroups: the number of bone groups.
4b - DWORD  - numRemaps: the number of bone remappings.

If there are any groups (numGroups > 0), the counters are followed by three arrays:

Xb - BYTE[numBones]           - boneRemapIndices: an array of all bone indices where each element identifies a bone of the skeleton
Xb - BoneGroup[numGroups]     - boneGroups (see below)
Xb - BoneRemap[numRemaps]     - boneRemaps (see below)

Where BoneGroup and BoneRemap is defined as follows:

struct BoneGroup {
    BYTE firstBone;            // Index of first bone in boneRemaps array.
    BYTE numBones;             // Number of bones in boneRemaps that define the mesh (starting from firstBone).
};

struct BoneRemap {
    BYTE boneIndex;            // Index of the bone in boneRemapIndices.
    BYTE indices;              // The number of elements of the boneRemapIndices that are included by the group in boneRemapIndices.
};

See also