Implement playable Mac client and rendering validation

This commit is contained in:
shen
2026-09-11 14:58:22 +08:00
parent 1ab68bd06e
commit 374d4165d8
233 changed files with 6546 additions and 284 deletions
+61
View File
@@ -0,0 +1,61 @@
extends SceneTree
const Anchor = preload("res://fx/motion_effect_anchor.gd")
const PlayerView = preload("res://ui/player_view.gd")
var failures := 0
func check(ok: bool, label: String) -> void:
if not ok:
failures += 1
printerr("FAIL: " + label)
func _init() -> void:
call_deferred("run")
func run() -> void:
var view := PlayerView.new()
check(view.build(AssetRoot.path(), 0), "real warrior builds")
root.add_child(view)
view.position = Vector3(7, 2, -4)
view.rotation.y = 0.7
view.anim.set_process(false)
view.anim.set_time(0.2)
var effect := Node3D.new()
root.add_child(effect)
var anchor := Anchor.new()
effect.add_child(anchor)
var event := {"attaching": true, "following": true, "independent": false,
"bone": "equip_right_hand", "pos": Vector3(10, 20, 30)}
check(anchor.configure(view, event), "real equip_right_hand resolves")
check(anchor.is_processing(), "following bone updates")
var pose: Dictionary = view.anim.get_effect_bone_pose(event.bone)
if not pose.is_empty():
var expected: Vector3 = view.model.global_transform * (pose.transform.origin + event.pos)
check(effect.global_position.distance_to(expected) < 0.00001, "bone + actor-local cm offset, then actor rotation")
var before := effect.global_transform
view.anim.set_time(1.0)
anchor.update_anchor()
check(not effect.global_transform.is_equal_approx(before), "anchor uses sampled animation pose")
event.following = false
check(anchor.configure(view, event) and not anchor.is_processing(), "snapshot bone does not follow")
before = effect.global_transform
view.position.x += 3.0
await process_frame
check(effect.global_transform.is_equal_approx(before), "snapshot remains in world after actor moves")
event.independent = true
event.bone = "missing"
check(anchor.configure(view, event), "independent ignores bone")
check(effect.global_position.distance_to(view.model.global_transform * event.pos) < 0.00001,
"independent offset converts source Z to world up")
event.independent = false
check(not anchor.configure(view, event), "missing bone rejected")
event.attaching = false
check(anchor.configure(view, event) and anchor.is_processing(), "root attachment follows regardless of FollowingEnable")
# Metadata from the real file must survive the file-reader parser and native API.
view.anim.set_anim_path(AssetRoot.path().path_join("PC/ymir work/pc/warrior/skill/gigongcham.msa"))
var events: Array = view.anim.get_events()
check(not events.is_empty(), "real skill events loaded")
if not events.is_empty():
check(events[0].attaching and events[0].bone == "Bip01 Spine1", "file parser retains bone metadata")
check(String(events[0].effect).contains("/"), "full effect path retained")
effect.free()
view.free()
await process_frame
print("motion_effect_anchor_test: failures=%d" % failures)
quit(1 if failures else 0)