tests & can charge up thrust
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
/extends SceneTree
|
||||
## Ragdoll throw visual test — triggers ragdoll on the matador and captures a
|
||||
## frame strip so you can inspect the throw arc and settling.
|
||||
##
|
||||
## Run (needs a display for real screenshots):
|
||||
## godot --script tests/ragdoll_throw_test.gd
|
||||
##
|
||||
## Outputs: tests/output/ragdoll_throw/frame_00..09.png
|
||||
## Each frame is 0.2 s apart → strip covers 2 s of flight and tumble.
|
||||
|
||||
const OUTPUT_DIR := "res://tests/output/ragdoll_throw"
|
||||
const BULL_SPEED := 22.0 # simulate a solid charge
|
||||
|
||||
const TRACKED_BONES: Array[StringName] = [&"chest", &"head", &"COG"]
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
_run.call_deferred()
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
DirAccess.make_dir_recursive_absolute(OUTPUT_DIR)
|
||||
|
||||
var scene_res := load("res://scene.tscn")
|
||||
if not scene_res:
|
||||
push_error("ragdoll_throw_test: failed to load scene.tscn")
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var scene: Node = scene_res.instantiate()
|
||||
root.add_child(scene)
|
||||
|
||||
# Let physics and AI settle
|
||||
await create_timer(0.8).timeout
|
||||
|
||||
var matadors := get_nodes_in_group(&"matador")
|
||||
if matadors.is_empty():
|
||||
push_error("ragdoll_throw_test: no matadors in scene")
|
||||
quit(1)
|
||||
return
|
||||
|
||||
var mat := matadors[0] as Node3D
|
||||
var spawn := mat.global_position
|
||||
print("matador spawn: %s" % spawn)
|
||||
|
||||
# Throw toward +Z with a realistic charge speed
|
||||
mat.call(&"_enter_ragdoll", Vector3(0.0, 0.0, 1.0), BULL_SPEED)
|
||||
print("ragdoll triggered bull_speed=%.1f" % BULL_SPEED)
|
||||
|
||||
# Strip: 10 frames every 0.2 s
|
||||
for i: int in range(10):
|
||||
await create_timer(0.2).timeout
|
||||
var t := (i + 1) * 0.2
|
||||
|
||||
var img: Image = root.get_viewport().get_texture().get_image()
|
||||
if img:
|
||||
img.save_png(OUTPUT_DIR + "/frame_%02d.png" % i)
|
||||
|
||||
var sim: Node = _find_class_recursive(mat, "PhysicalBoneSimulator3D")
|
||||
var bone_info := ""
|
||||
if sim:
|
||||
for bone_name: StringName in TRACKED_BONES:
|
||||
for child: Node in sim.get_children():
|
||||
if child is PhysicalBone3D and \
|
||||
(child as PhysicalBone3D).bone_name == bone_name:
|
||||
var bp: Vector3 = (child as PhysicalBone3D).global_position
|
||||
var dist: float = bp.distance_to(spawn)
|
||||
bone_info += " %s y=%.2f dist=%.2f" % [bone_name, bp.y, dist]
|
||||
|
||||
print("t=%.1fs frame %02d%s" % [t, i, bone_info])
|
||||
|
||||
print("\nStrip saved → %s" % OUTPUT_DIR)
|
||||
quit(0)
|
||||
|
||||
|
||||
func _find_class_recursive(node: Node, class_name_str: String) -> Node:
|
||||
if node.get_class() == class_name_str:
|
||||
return node
|
||||
for child: Node in node.get_children():
|
||||
var r := _find_class_recursive(child, class_name_str)
|
||||
if r:
|
||||
return r
|
||||
return null
|
||||
Reference in New Issue
Block a user