CSkSkeleton¶
Stores the bone hierarchy (skeleton) used for animating skinned meshes. It defines the names, parent-child relationships, and bind-pose transformations for all bones. 🦴
Overview¶
- Purpose: Defines the articulated structure (bones) that drives the deformation of animated characters and objects.
- Where it appears: Included in animated model types:
AnimatedUnit,AnimatedObjectNoCollision,AnimatedObjectCollision. It's absent in static models. Appears afterCSkSkinInfoin theWriteOrder. - Engine impact: Forms the basis for skeletal animation playback. The number of bones and hierarchy depth can affect animation performance.
Structure¶
| Field | Type | Description |
|---|---|---|
magic |
int32 |
Internal block identifier, should be 1558308612. |
version |
int32 |
Format version, typically 3. |
bone_matrix_count |
int32 |
Number of entries in bone_matrices. Should match bone_count. |
bone_matrices |
List[BoneMatrix] |
Bind pose transformation data for each bone, ordered sequentially by bone identifier (0, 1, 2...). See BoneMatrix. |
bone_count |
int32 |
Total number of bones in the skeleton. |
bones |
List[Bone] |
The list defining each bone's properties and hierarchy. Note: This list is ordered by Bone.version, not necessarily by bone identifier. See Bone. |
super_parent |
Matrix4x4 |
Root transformation matrix, usually identity. See Matrix4x4. |
BoneMatrix¶
Contains bind pose data derived from four BoneVertex entries, effectively storing the bone's local transform relative to its parent (or world space for root bones).
| Field | Type | Description |
|---|---|---|
bone_vertices |
List[BoneVertex] |
Four vertices defining the bone's orientation, position, and hierarchical links. Always 4 entries. See BoneVertex. |
BoneVertex¶
A helper structure within BoneMatrix. The parent field is key for linking within the skeleton's structure, particularly for the first two vertices.
| Field | Type | Description |
|---|---|---|
position |
Vector3 |
A 3D coordinate related to the bone's bind pose. See Vector3. |
parent |
int32 |
Index linking to bone identifiers, with specific meaning based on its index within bone_vertices: |
Specific parent field usage within BoneMatrix.bone_vertices:
bone_vertices[0].parent: Stores theidentifierof this bone's parent bone in the hierarchy. For the root bone (identifier 0), this value is-1. This directly links a bone back to its parent.bone_vertices[1].parent: Stores theidentifierof the bone itself. This acts as a self-reference.bone_vertices[2].parent: Hardcoded to0during export (create_skeleton). Its specific use in-game is unclear.bone_vertices[3].parent: Hardcoded to0during export (create_skeleton). Its specific use in-game is unclear.
Bone¶
Defines a single bone in the skeleton hierarchy. Remember this list is ordered by version, not identifier.
| Field | Type | Description |
|---|---|---|
version |
uint32 |
Bone version/identifier, often derived from a hash or predefined list (bone_versions.json). Used for sorting this list. |
identifier |
int32 |
Unique ID for this bone within the skeleton (0 for root, 1, 2...). Used by CSkSkinInfo and CDspJointMap. Used for indexing bone_matrices. |
name_length |
int32 |
Length of the bone name string. |
name |
string |
Name of the bone (e.g., "Bip01_Head"). Limited to 63 characters by importer/exporter (hashes longer names). |
child_count |
int32 |
Number of direct children this bone has. |
children |
List[int32] |
List of identifier values for the children bones. |
Authoring & In-Game Behavior¶
- Blender Workflow:
- Creation: Created automatically during export (
create_skeletonindrs_utility.py) from a Blender Armature object within the model's collection. - Hierarchy: The parent-child relationships in the Blender Armature directly define the
Bone.childrenand theBoneVertex[0].parentlinks in the exportedCSkSkeleton. The root bone in Blender (usually the one with no parent) becomes boneidentifier0. - Bone Map: The exporter generates a
bone_map(create_bone_map) which assigns a unique sequentialidentifier(0, 1, 2...) to each bone based on traversing the hierarchy. This map is crucial for linking skin weights (CSkSkinInfo) and joint maps (CDspJointMap), and determines the order of thebone_matricesarray. - Bone Ordering: The
boneslist itself is sorted based on theBone.versionfield (potentially frombone_versions.jsonor a hash) before writing. Thebone_matriceslist remains ordered by the hierarchicalidentifier. - Naming: Bone names are taken directly from the Blender Armature. The importer/exporter enforces a 63-character limit; longer names might be hashed (
Bone.readlogic). Standard naming conventions (like "Bip01_...") are recommended. - Bind Pose: The
bone_matricesare calculated from the bone's Rest Pose transforms in Blender (armature_bone.matrix_local).
- Creation: Created automatically during export (
- Import: When importing (
import_csk_skeleton,init_bones), theCSkSkeletondata is used to reconstruct the Armature object in Blender, including bone names, hierarchy (create_bone_treeuses parent links), and setting the Rest Pose (record_bind_pose).
Validation Rules¶
| Rule | Why |
|---|---|
magic == 1558308612 |
Confirms block type. |
version == 3 |
Ensures expected format. |
bone_matrix_count == bone_count |
Each bone needs matrix data. |
bone_count == len(bones) |
Bone array must match its count. |
Bone identifier values are unique and sequential (0 to bone_count-1) |
Required for consistent indexing by other systems. |
Child indices in Bone.children are valid bone identifier values |
Prevents broken hierarchy links. |
BoneVertex[0].parent index is valid (-1 or 0 to bone_count-1) |
Ensures correct parent linking. |
BoneVertex[1].parent == Bone.identifier |
Consistency check for self-reference. |
| Bone names are unique and <= 63 chars | Ensures correct mapping and avoids engine/tool limitations. |
Cross-References¶
- Header / Nodes: Referenced via
NodeInformationin the DRS header. See Header. - Skinning Weights: Provides the bone
identifiervalues referenced byCSkSkinInfo. See CSkSkinInfo. - Joint Map: Provides the bone
identifiervalues referenced byCDspJointMap. See CDspJointMap. - Common Structures: Uses
Matrix4x4andVector3. See Common Structures.
Nice to know¶
- Magic Value:
CSkSkeleton = -2110567991(0x823299C9). See Glossary → MagicValues. - Node Name: The node is typically named
csk_skeletonin the hierarchy during export. - Ordering Difference: Be aware that the
boneslist is sorted byversion, whilebone_matricesare indexed by the sequentialidentifier. This meansbones[i].identifierdoes not necessarily equali.