Skin PLG (RW Section)

From GTAMods Wiki
Revision as of 15:51, 25 October 2024 by Nebula (talk | contribs) (Fix weight mapping to include all 4 possible vertex weights)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
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