Skip to content

[write_rig.py] Fix bones order & Fix inconsistent order of json values#311

Open
glekDev wants to merge 1 commit intoWolvenKit:mainfrom
glekDev:main
Open

[write_rig.py] Fix bones order & Fix inconsistent order of json values#311
glekDev wants to merge 1 commit intoWolvenKit:mainfrom
glekDev:main

Conversation

@glekDev
Copy link
Copy Markdown

@glekDev glekDev commented Sep 27, 2025

Calculate depth based on names from the original json and fix inconsistent order of json values.

Also jsons from wolvenkit have uppercase exponent indicator "E-", while python outputs them lowercase "e-" (it doesnt affect anything, just makes diffing harder)

Btw im not sure if this script is even supposed to work..
Just exporting .rig from wolvenkit to blender and back to wolvenkit (without any changes) does this:

изображение

Calculate depth based on names from the original json.

Btw im not sure if this script is even supposed to work..
@glekDev glekDev changed the title Fix bones order & Fix inconsistent order of json values [write_rig.py] Fix bones order & Fix inconsistent order of json values Sep 27, 2025
@glekDev
Copy link
Copy Markdown
Author

glekDev commented Sep 27, 2025

There are a lot of confusing things about rigs, can somebody explain / link to an explanation for:

  1. Why do .rig files have three arrays of transforms?
изображение

(My only idea is that it has something to do with LODs)
(What do "aPoseLS" and "aPoseMS" mean?)

  1. Why do .mesh files also have rig data in them?
изображение
  1. What are "boneRigMatrices" and "boneVertexEpsilons"?
    (I just googled the bone rig epsilon and its basically just a small number. ("gimbal lock" something something)
    I guess my question is: why are there bone matrices in .mesh rigs, but not .rig rigs, and why does it need "bonePositions" if there are "boneRigMatrices"? )

Also why do we need a T-pose option in the Rig Import Options?
изображение

@DoctorPresto DoctorPresto self-assigned this Sep 28, 2025
@DoctorPresto
Copy link
Copy Markdown
Contributor

Howdy!

Thanks for the PR

Btw im not sure if this script is even supposed to work..
Just exporting .rig from wolvenkit to blender and back to wolvenkit (without any changes) does this:

It's not really at this point - there are a few reasons why which I'll try to touch on below as well as my thoughts on the easiest ways to fix it - if you have the time and motivation to do some more work on this, it would definitely be appreciated by everyone!

There are a lot of confusing things about rigs, can somebody explain / link to an explanation for:

  1. Why do .rig files have three arrays of transforms?
    (My only idea is that it has something to do with LODs) (What do "aPoseLS" and "aPoseMS" mean?)

LS = Local Space
MS = Model (World) Space

In general, aPoseLS is the array that actually gets used. If both aPoseLS and boneTransforms(which is essentially tPoseLS) are present, aPoseLS will override boneTransforms - aPoseMS gets recalculated at runtime, but in blender is a lot less effort to use than the other options when it's present

Sometimes transforms are being applied in LS on some bones and MS on others, makes for lots of fun :D

  1. Why do .mesh files also have rig data in them?

What the meshes have is not really rig data - this is the skinning data that defines the relationship between the vertex groups in the mesh and the joints of the rig

  1. What are "boneRigMatrices" and "boneVertexEpsilons"?
    (I just googled the bone rig epsilon and its basically just a small number. ("gimbal lock" something something)
    I guess my question is: why are there bone matrices in .mesh rigs, but not .rig rigs, and why does it need "bonePositions" if >there are "boneRigMatrices"? )

Kind of explained above, unless you're about to try to build a dangle rig, I'd recommend focusing on understanding the rest of the info before getting too down that rabbit hole - they're all different pieces of information

Also why do we need a T-pose option in the Rig Import Options?

A couple reasons:

  • if the data is there, why not make it accessible/usable?
  • outside of Cyberpunk, T-Pose is the more commonly used reference pose, including an easy to use and accurate option that gets Cyberpunk rigs and meshes into T-Pose makes it much easier for modders who are porting assets from other games, daz or marvelous designer to actually fit and weight the meshes to get them working in Cyberpunk

Now for my thoughts on fixing rig export:

  • the current implementation of read_rig.py creates custom properties on the armature containing the properly ordered original boneNames array, the boneParentIndexes array, and a few other key bits of info (parts, ragdoll, reference track values etc...)
  • It also includes an option to create "debug empties" - by using these, you don't have to think about the "tail" of the bone, calculate bone roll (neither of which actually exist in Red Engine/Maya) and you also don't have to mess around with space conversions from Red Engine - gLTF - Blender - the values of the empties are direct matches to the red engine values.
  • since these empties are bound to the heads of the bones they're named for, even if bones get moved/scaled etc... these values will still be correct - these are the values we should be exporting from the plugin to the json.
  • rather than calculating depth with the extra steps you've implemented here - for the rigs imported from json, you can just map boneNames[i] to boneParentIndexes[i] and then grab the empty for the correct coordinate space by name and copy the transforms in, assigning the parenting relationship as per the noted parent index. This should also make it much more accessible for us to implement adding/removing bones from inside blender boneNames[0] = boneParentIndexes[0] = boneTransforms[0] = aPoseLS[0] and so on, so if you run into a boneName at index 70 of the custom prop array that doesn't exist in the scene, you know that means that the value in the boneParentIndexes custom prop at index 70 should be skipped - my thought (hope?) is that we can get away with doing additions by just tacking them on at the end of each of these arrays as that makes it much easier to handle

This is a lot of information to throw in a github comment and there is a lot more to share that I won't ramble on about here, but feel free to ping me on discord if you have any questions on the above - more than happy to help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants