feat: implement automated 3D character pipeline with retargeting and rig management tools

This commit is contained in:
Nicholas Butzke
2026-07-24 20:52:35 -04:00
parent afc954e129
commit 374d9f9822
19 changed files with 3220 additions and 221 deletions
+17 -10
View File
@@ -34,10 +34,15 @@ class_name SkinJointHelper
## SkinnedPlayerModel.ShooterPoseModifier). A helper that is not updated in step
## with its child deforms the limb instead of saving it.
## [parent, child] per joint, both sides.
const JOINTS := [
["DEF-thigh.L", "DEF-shin.L"], ["DEF-thigh.R", "DEF-shin.R"],
]
## The CHILD bone of each joint to subdivide. The parent is whatever the
## skeleton says it is, not a second hardcoded name.
##
## It used to be a [parent, child] pair of ["DEF-thigh.L", "DEF-shin.L"], which
## silently did nothing on a rig with limb twist bones: Taila's shin hangs off
## DEF-thigh.L.001, so the knee vertices are weighted across THAT and the shin,
## and the pass found no vertex holding both named bones. The knee measured 0.76
## with this "installed" and doing nothing at all.
const JOINT_CHILDREN := ["DEF-shin.L", "DEF-shin.R", "shin.L", "shin.R"]
## Angular steps through each joint. 4 leaves at most a quarter of the bend for
## any one vertex to blend across, which is a ~3% collapse at a hard tuck.
const SEGMENTS := 4
@@ -55,16 +60,18 @@ static func install(root: Node, skeleton: Skeleton3D) -> Array:
var driven: Array = []
# child bone -> [parent bone, [helper bones, inner first]]
var joint_helpers := {}
for joint in JOINTS:
var parent := skeleton.find_bone(joint[0])
var child := skeleton.find_bone(joint[1])
if parent < 0 or child < 0:
for child_name in JOINT_CHILDREN:
var child := skeleton.find_bone(child_name)
if child < 0:
continue
if skeleton.find_bone("HELPER1-" + joint[1]) >= 0:
var parent := skeleton.get_bone_parent(child)
if parent < 0:
continue
if skeleton.find_bone("HELPER1-" + child_name) >= 0:
continue # already installed
var helpers: Array = []
for step in range(1, SEGMENTS):
var hname: String = "HELPER%d-%s" % [step, joint[1]]
var hname: String = "HELPER%d-%s" % [step, child_name]
skeleton.add_bone(hname)
var h := skeleton.find_bone(hname)
skeleton.set_bone_parent(h, parent)