extends SceneTree ## Dev probe: dump how Godot imported fps_arms.glb (node tree, skeleton scale, bone ## names) so ViewModel.gd can be authored against the real numbers instead of guesses. ## ## Godot --headless --path game --script dev/probe_arms.gd func _initialize() -> void: _probe("res://assets/viewmodel/fps_arms.glb") for w in ["bat", "sledge", "crowbar", "cutter", "extinguisher"]: _probe("res://assets/viewmodel/%s.glb" % w, false) quit() func _probe(path: String, deep := true) -> void: print("\n=========== ", path) if not ResourceLoader.exists(path): print(" MISSING") return var ps := load(path) as PackedScene if ps == null: print(" not a PackedScene") return var root := ps.instantiate() _dump(root, 0, deep) var skel := _find_skel(root) if skel != null: print(" -- skeleton: ", skel.name, " bones=", skel.get_bone_count()) print(" -- skeleton global xform: ", skel.transform) # Godot sanitises glTF bone names on import, so print what actually landed # rather than assuming the mixamorig: spelling survived. for i in skel.get_bone_count(): var nm := skel.get_bone_name(i) if nm.to_lower().contains("right") or nm.to_lower().contains("spine"): print(" %-34s idx=%-3d parent=%-3d rest.origin=%s" % [ nm, i, skel.get_bone_parent(i), skel.get_bone_rest(i).origin]) # overall size var aabb := _aabb(root) print(" -- combined AABB pos=", aabb.position, " size=", aabb.size) root.free() func _dump(n: Node, d: int, deep: bool) -> void: var pad := "" for i in d: pad += " " var extra := "" if n is MeshInstance3D: var mi := n as MeshInstance3D extra = " surfaces=%d skin=%s" % [ mi.mesh.get_surface_count() if mi.mesh else 0, str(mi.skin != null)] if mi.mesh: for s in mi.mesh.get_surface_count(): var m := mi.mesh.surface_get_material(s) extra += " [mat%d=%s]" % [s, m.resource_name if m else "null"] print(pad, n.name, " <", n.get_class(), ">", extra) if not deep and d >= 1: return for c in n.get_children(): _dump(c, d + 1, deep) func _find_skel(n: Node) -> Skeleton3D: if n is Skeleton3D: return n for c in n.get_children(): var r := _find_skel(c) if r != null: return r return null func _aabb(n: Node) -> AABB: var acc := AABB() var started := false for mi in _meshes(n): var a: AABB = (mi as MeshInstance3D).get_aabb() a = (mi as Node3D).transform * a if not started: acc = a started = true else: acc = acc.merge(a) return acc func _meshes(n: Node, acc: Array = []) -> Array: if n is MeshInstance3D: acc.append(n) for c in n.get_children(): _meshes(c, acc) return acc