3fb45f0ef2
checkpoint / checkpoint (push) Successful in 1m47s
Now that cloudbison can render (Radeon GPU via Xvfb, or llvmpipe software), added scripts/tools/screenshot_rig.gd + scenes/dev/ so a scene can be booted, run a few frames, and its rendered frame saved to PNG -- caught three things the headless smoke never could: - limbs floated detached from the torso: widened the torso and overlapped the arm/leg boxes into it, and pulled limb depth in behind the torso front so they stop z-fighting. - proportions were scrawny: reworked to Roblox R6 ratios (2-stud torso, 2-stud arms/legs, 1-stud head) with the head clearly pegged on top. - the walk swing was a 40-deg lunge: STRIDE 0.7->0.42 rad, separate 0.32 arm swing, KNEE 1.0->0.5. Reads as a walk now, not a crouch. test_level lighting was near-black on the shaded side (ambient was disabled) -- colour ambient at 0.8 + a stronger key light, so the avatar reads in-world. avatar_preview.tscn (AGP_PREVIEW_WALK=1) renders the assembled avatar walking in place for quick visual checks. Verified: avatar smoke 14/14 source + exported pack; fresh-clone boot PASS; eyeballed in rendered screenshots (game scene + walk sequence). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015jtxAiu5dAW4WxCNdGkrkJ
70 lines
2.3 KiB
GDScript
70 lines
2.3 KiB
GDScript
extends Node3D
|
|
## Dev-only. Builds the current avatar via AvatarSystem, stands it on a small
|
|
## stage with even lighting, and (optionally) drives the procedural walk cycle
|
|
## so screenshots can verify both the silhouette and that the limbs move.
|
|
##
|
|
## Env:
|
|
## AGP_PREVIEW_WALK "1" -> feed the limb animator a walking speed
|
|
## AGP_PREVIEW_SPIN degrees/sec turntable (default 0)
|
|
## Used together with screenshot_rig.gd (AGP_SHOT_SCENE=res://scenes/dev/avatar_preview.tscn,
|
|
## AGP_SHOT_SEQ="6:10" to catch the cycle at several phases).
|
|
|
|
const LimbAnimator := preload("res://scripts/avatar/limb_animator.gd")
|
|
|
|
var _avatar: Node3D = null
|
|
var _anim: Node = null
|
|
var _spin_deg := 0.0
|
|
|
|
|
|
func _ready() -> void:
|
|
_spin_deg = float(OS.get_environment("AGP_PREVIEW_SPIN"))
|
|
|
|
var env := WorldEnvironment.new()
|
|
var e := Environment.new()
|
|
e.background_mode = Environment.BG_COLOR
|
|
e.background_color = Color(0.16, 0.18, 0.22)
|
|
e.ambient_light_source = Environment.AMBIENT_SOURCE_COLOR
|
|
e.ambient_light_color = Color(0.6, 0.64, 0.7)
|
|
e.ambient_light_energy = 0.6
|
|
env.environment = e
|
|
add_child(env)
|
|
|
|
var key := DirectionalLight3D.new()
|
|
key.rotation = Vector3(-0.9, -0.6, 0.0)
|
|
key.light_energy = 1.1
|
|
add_child(key)
|
|
|
|
var ground := MeshInstance3D.new()
|
|
var pm := PlaneMesh.new()
|
|
pm.size = Vector2(6, 6)
|
|
ground.mesh = pm
|
|
var gmat := StandardMaterial3D.new()
|
|
gmat.albedo_color = Color(0.3, 0.32, 0.36)
|
|
ground.material_override = gmat
|
|
add_child(ground)
|
|
|
|
var cam := Camera3D.new()
|
|
cam.position = Vector3(2.1, 1.15, 2.6)
|
|
cam.look_at_from_position(cam.position, Vector3(0.0, 1.0, 0.0), Vector3.UP)
|
|
cam.current = true
|
|
add_child(cam)
|
|
|
|
var avatars := get_node_or_null("/root/AvatarSystem")
|
|
if avatars != null and avatars.has_method("build_current_avatar"):
|
|
_avatar = avatars.build_current_avatar()
|
|
if _avatar != null:
|
|
add_child(_avatar)
|
|
var skel := _avatar.find_child("Skeleton3D", true, false)
|
|
if skel is Skeleton3D and OS.get_environment("AGP_PREVIEW_WALK") == "1":
|
|
_anim = LimbAnimator.new()
|
|
add_child(_anim)
|
|
_anim.call("setup", skel)
|
|
_anim.set("speed", 4.2)
|
|
else:
|
|
push_warning("avatar_preview: AvatarSystem.build_current_avatar() returned null")
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
if _avatar != null and _spin_deg != 0.0:
|
|
_avatar.rotate_y(deg_to_rad(_spin_deg) * delta)
|