Files
jeremy 31ba2911df init: animation pipeline hub — Mac↔PC bridge for converting and implementing animations
Skills (.claude/skills/): animation-creation, iclone-video-mocap,
pose-estimation (MediaPipe models via LFS), retarget-animations (deprecated).
Tools: cc/mixamo/kevin/mocap retargeters + composite baker.
Plans: animation-gen-pipeline + skills-adoption.
exchange/: incoming-fbx, converted-glb, reference-video (LFS for fbx/glb/mp4).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:29:48 -07:00

5.4 KiB

Skill: Animation Retargeting (Kevin → BoZo) — DEPRECATED

DEPRECATED May 19, 2026. BoZo and Kevin characters retired. Quaternius character system replaces them — no retargeting needed. This skill is kept for engine reference (Godot fork rest fixer fix).

# 1. Clean import (creates default .import files)
rm -f assets/animations/kevin/*.import assets/models/characters/Body/Body_BasicBody.fbx.import
rm -f .godot/imported/Archer*.scn .godot/imported/Body_BasicBody*.scn .godot/imported/Villager*.scn .godot/imported/Throwing*.scn
godot --headless --path . --import

# 2. Patch .import files with BoneMap + retarget config
godot --headless --path . -s setup_retarget.gd

# 3. Delete cache + reimport with retarget config
rm -f .godot/imported/Archer*.scn .godot/imported/Body_BasicBody*.scn .godot/imported/Villager*.scn .godot/imported/Throwing*.scn
godot --headless --path . --import

IMPORTANT: Must delete .godot/imported/*.scn cache between steps 2→3, otherwise Godot skips reimport.

What the pipeline does

  1. Bone renamer: Renames Kevin bones (B-hipsHips) and BoZo bones (pelvisHips) to Humanoid standard
  2. Overwrite Axis (method 1): Changes skeleton rest poses to match SkeletonProfileHumanoid reference
  3. Animation conversion: Transforms keyframe values from old rest coordinate system to new rest coordinate system using formula from post_import_plugin_skeleton_rest_fixer.cpp:777:
    new_q = new_pg_q.inv * old_pg_q * qt * old_rest_q.inv * old_pg_q.inv * new_pg_q * new_rest_q
    

Known Bug (patched in tinqs/godot fork)

Commit: 4e16c3f5bd on main

The %GeneralSkeleton unique node resolution via get_node() fails in headless import mode. Original code at line 733:

Node *node = (ap->get_node(ap->get_root_node()))->get_node(NodePath(track_path));
ERR_CONTINUE(!node);  // Silently skips ALL animation tracks!

Fix: Falls back to find_child() when unique name resolution fails. Without this fix, rest poses change but animation keyframe values stay in the old coordinate system.

Current Status (2026-05-18)

Working:

  • Bone renaming (Kevin → Humanoid, BoZo → Humanoid) ✓
  • Rest pose overwrite to Humanoid reference ✓
  • Skeleton node resolution fix (find_child fallback) ✓
  • Animation conversion runs for spine/chest bones ✓

NOT working:

  • Animation conversion appears to be a NO-OP for limb bones (arms, legs)
  • Spine keys → near identity (correct). Arm/leg keys → near rest (unconverted)
  • Root cause: unknown. Possibly old_rest captured AFTER partial overwrite, or formula output matches input for bones with specific rest orientations

Visual symptoms:

  • Arms cross behind back during animation
  • Legs may be double-rotated (rest * rest)
  • Spine animates correctly

Bone Mapping

Kevin → Humanoid

Humanoid Kevin
Hips B-hips
Spine B-spine
Chest B-chest
UpperChest B-upperChest
Neck B-neck
Head B-head
LeftShoulder B-shoulder.L
LeftUpperArm B-upper_arm.L
LeftLowerArm B-forearm.L
LeftHand B-hand.L
Right* B-*.R (mirror)
LeftUpperLeg B-thigh.L
LeftLowerLeg B-shin.L
LeftFoot B-foot.L
LeftToes B-toe.L
Right* B-*.R (mirror)

BoZo → Humanoid

Humanoid BoZo
Hips pelvis
Spine spine_01
Chest spine_03
UpperChest spine_05
Neck neck_01
Head head
LeftShoulder clavicle_l
LeftUpperArm upperarm_l
LeftLowerArm lowerarm_l
LeftHand hand_l
Right* *_r (mirror)
LeftUpperLeg thigh_l
LeftLowerLeg calf_l
LeftFoot foot_l
LeftToes ball_l
Right* *_r (mirror)

BoZo intermediate bones (spine_02, spine_04, neck_02) have no Kevin equivalent and keep global rest.

Key Files

File Purpose
setup_retarget.gd Headless script: patches .import files with BoneMap + retarget config
run_retarget.gd EditorScript: same but runs inside Godot editor GUI
addons/retarget_setup/plugin.gd EditorPlugin: auto-runs on editor start
assets/retarget/kevin_bonemap.tres Kevin → Humanoid BoneMap resource
assets/retarget/bozo_bonemap.tres BoZo → Humanoid BoneMap resource
inspect_fbx.gd Debug: prints bone names, rest poses, animation values
src/Viewer/PlayerController.cs Character: loads animation, remaps %GeneralSkeleton paths

Godot Engine Source (for debugging)

File What
editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp Overwrite Axis + animation conversion
editor/import/3d/post_import_plugin_skeleton_renamer.cpp Bone renaming
scene/3d/retarget_modifier_3d.cpp Runtime retargeting (RetargetModifier3D)
scene/resources/bone_map.cpp BoneMap resource
scene/resources/skeleton_profile.cpp SkeletonProfile + Humanoid preset

What NOT to do

  1. Manual quaternion retargeting in C# — tried 5 different formulas, all failed. The formula requires parent GLOBAL rest transforms for the entire bone chain. Only Godot's engine code handles this correctly.
  2. Rename BoZo bones at runtime — breaks outfit/clothing FBX loading (bone name mismatch).
  3. BoneAttachment3D for head without inverse rest compensation — double-transforms the head.
  4. Headless import without deleting .scn cache — Godot skips reimport if source FBX unchanged.