8fa53c8e78
- male/: raw + z-facing + quat-named bodies, Meshy rigged GLB/FBX, stock walk/run clips, male-ual-clips.glb (16 UAL1 clips baked via ariki-game mixamo_retarget.py --map ual) - anim_male.tscn: Meshy stock clips; anim_male_ual.tscn: UAL clips (scales position keys x100 — Meshy skeleton is cm, clips are m) - view_tripo.tscn: env-var GLB turntable/anim shots + interactive orbit - rotate_glb.gd: headless face-+Z/height fixup (Meshy pose estimation rejects Tripo's +X-facing normalized output) - Meshy spine chain is reverse-named: Spine02 = lowest vertebra Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
51 lines
1.9 KiB
GDScript
51 lines
1.9 KiB
GDScript
# Headless probe: compare the male body's pelvis rest height with the pelvis
|
|
# position keys in the baked UAL clips GLB.
|
|
extends SceneTree
|
|
|
|
const DIR := "C:/Users/CAN/tinqs-ltd/tattoo-test/male/"
|
|
|
|
func _init() -> void:
|
|
var body := _load(DIR + "male-lena-v15-quatnamed.glb")
|
|
var skel: Skeleton3D = _find(body, "Skeleton3D")
|
|
print("body bones=", skel.get_bone_count())
|
|
for i in [0, 1]:
|
|
print("bone ", i, " '", skel.get_bone_name(i), "' rest=", skel.get_bone_rest(i).origin,
|
|
" parent=", skel.get_bone_parent(i))
|
|
var pelvis := skel.find_bone("pelvis")
|
|
print("pelvis idx=", pelvis, " global_rest=", skel.get_bone_global_rest(pelvis).origin)
|
|
|
|
var clips := _load(DIR + "male-ual-clips.glb")
|
|
var ap: AnimationPlayer = _find(clips, "AnimationPlayer")
|
|
var anim := ap.get_animation("Idle_Loop")
|
|
for t in anim.get_track_count():
|
|
var path := String(anim.track_get_path(t))
|
|
if path.ends_with(":pelvis"):
|
|
var kind := anim.track_get_type(t)
|
|
if kind == Animation.TYPE_POSITION_3D:
|
|
print("POS track ", path, " key0=", anim.track_get_key_value(t, 0),
|
|
" keyN=", anim.track_get_key_value(t, anim.track_get_key_count(t) - 1))
|
|
elif kind == Animation.TYPE_ROTATION_3D:
|
|
print("ROT track ", path, " key0=", anim.track_get_key_value(t, 0))
|
|
# also inspect the clips GLB's own skeleton rest (exported armature)
|
|
var cskel: Skeleton3D = _find(clips, "Skeleton3D")
|
|
if cskel:
|
|
var cp := cskel.find_bone("pelvis")
|
|
print("clipsGLB pelvis rest=", cskel.get_bone_rest(cp).origin, " bones=", cskel.get_bone_count())
|
|
quit(0)
|
|
|
|
func _load(path: String) -> Node3D:
|
|
var doc := GLTFDocument.new()
|
|
var state := GLTFState.new()
|
|
doc.append_from_file(path, state)
|
|
return doc.generate_scene(state)
|
|
|
|
func _find(root: Node, klass: String) -> Node:
|
|
var stack: Array = [root]
|
|
while not stack.is_empty():
|
|
var n: Node = stack.pop_back()
|
|
if n.get_class() == klass:
|
|
return n
|
|
for c in n.get_children():
|
|
stack.push_back(c)
|
|
return null
|