extends SceneTree ## Dev tool: does the cloth actually JITTER when the character is standing still? ## ## godot --path . --windowed --resolution 900x900 \ ## -s res://debug/idle_jitter_check.gd -- ## ## debug/cloth_settle_check.gd answers this in degrees per frame of LOCAL bone ## rotation, and that number is inflated for a chain: correcting a panel root ## shows up as an equal and opposite delta on its segments, so a hem that has not ## moved at all in world space can report ten degrees. It has misled before. ## ## This renders consecutive frames of a still idle from a fixed camera and saves ## them; comparing neighbouring PNGs gives the only number that matters, which is ## whether anything on screen moved. var _frames := 0 var _out := "." var _model: SkinnedPlayerModel = null var _cam: Camera3D = null var _shots := 0 const SHOTS := 12 func _initialize() -> void: var args := OS.get_cmdline_user_args() _out = args[0] if args.size() > 0 else "." var scene := Node3D.new() root.add_child(scene) current_scene = scene var env := WorldEnvironment.new() var e := Environment.new() e.background_mode = Environment.BG_COLOR e.background_color = Color(0.05, 0.05, 0.08) e.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR e.ambient_light_color = Color(1, 1, 1) e.ambient_light_energy = 1.3 env.environment = e scene.add_child(env) var sun := DirectionalLight3D.new() sun.rotation_degrees = Vector3(-40, 35, 0) scene.add_child(sun) _model = SkinnedPlayerModel.new() _model.model_path = "res://assets/characters/skins/taila.glb" scene.add_child(_model) _cam = Camera3D.new() _cam.fov = 28.0 scene.add_child(_cam) _cam.current = true func _process(_delta: float) -> bool: _frames += 1 if _frames < 10 or not _model.loaded: return false _model.update_state("ground", 0.0, false) _model.set_locomotion(0.0, 0.0, 0.0) var hips := 0.95 if _model.skeleton: var h := _model.skeleton.find_bone("DEF-spine") if h >= 0: hips = _model.skeleton.get_bone_global_pose(h).origin.y # NEGATIVE Z is the FRONT. SkinnedPlayerModel spins the imported scene 180 # degrees (`facing_flip`: glTF forward is +Z, players face -Z), so a camera # on +Z looks at the character's BACK. Every tool in here used to sit on +Z, # and every "front" judgement made from them was of the back of the skirt. _cam.position = Vector3(0.0, hips - 0.08, -0.9) _cam.look_at(Vector3(0, hips - 0.14, 0), Vector3.UP) # Let the chains settle before recording — the first second is the model # dropping into its hanging pose, which is not jitter. if _frames > 130 and _shots < SHOTS: root.get_texture().get_image().save_png("%s/idle_%02d.png" % [_out, _shots]) _shots += 1 if _shots == SHOTS: print("saved %d idle frames" % SHOTS) return true return _frames > 400