fix(scene): 包围盒沿树累乘变换(修掉入树前的 ERROR 与范围偏位)+ 21 项"真机等价"测试
缺陷:SceneRuntime._compute_aabb() 用 MeshInstance3D.global_transform 计算包围盒, 而它在 _assemble() 里调用 —— 那时运行时节点**还没入树**。两个后果: - Godot 打一行 `ERROR: Condition "!is_inside_tree()" is true. Returning: Transform3D()` (真机每次载入场景都刷一条,与"日志里不应有 ERROR"的排查约定冲突); - 树外的 global_transform 返回单位变换,算出来的只是各网格的**局部** AABB, 于是重力/风 Area3D 的碰撞盒与兜底地面会偏小或偏位 —— 对把网格摆在非原点位置的 场景(导出 GLB 的常见情况)**风力可能作用不到物体上**。 修复:改为从根往下累乘 `Node3D.transform`,不依赖是否入树;挂在单位变换父节点下时 结果与旧语义一致。 新增 21 项无头"真机等价"测试(不需要设备): - tests/test_scene_config.gd:在代码里手写合法 GLB(三角形 + BIN chunk)落盘后 **真实加载**:warnings 为空、按 colliders 三种取值分别核对碰撞体(mesh / auto 命中 *_col / auto 未命中的兜底地面 / none)、重力 Area3D 的 gravity 与方向、 SPACE_OVERRIDE_REPLACE、风力与 WIND_FORCE_SCALE 对齐,以及**带位移网格** (translation [10,0,0])时重力区域与兜底地面都跟着位移(该缺陷的回归测试); - tests/test_pose_server.gd:**时间维度**验证保活 —— 只发应用层 ping、不发关键点帧的 客户端在 17 秒(> 15 秒静默超时)后仍保持连接("画面里没人就掉线、疯狂重连"的根因 对照),而完全不发数据的客户端被 close(1001) 断开。 新增 build/check-version.sh:强制 project.godot 的 application/config/version (「关于」清单与 .pck 的来源)与 project.yaml、发布版本号三者一致;已接入 build/package-release.sh(打包前)与 build/verify.sh(第 0/4 步),并做过反向验证。 此前没有任何机制保证这两个文件同步 —— 界面显示的版本可能和产物名不一致。 版本升至 0.2.1(project.godot / project.yaml / README / 产物名 / tag 全部一致), About 清单与 .pck 内版本号均为 0.2.1(已用 strings 核对)。 验证:build/verify.sh 四步全通过(版本一致性 → 编译 → 751 项断言 → 180 帧启动无错误); 产物 opendance-windows-v0.2.1.zip(LZMA,26,627,191 B) sha256 d49885327047f5a52de6c732431ea080cd1a030ae1c581a8bc0ec0d99bfb792c。
This commit is contained in:
@@ -360,16 +360,33 @@ static func _collect_static_bodies(node: Node) -> Array:
|
||||
return out
|
||||
|
||||
|
||||
static func _compute_aabb(node: Node) -> AABB:
|
||||
## 累加包围盒。
|
||||
##
|
||||
## * 累加包围盒。
|
||||
## *
|
||||
## * ⚠️ 必须**自己沿树累乘变换**,不能用 `global_transform`:本函数在 `_assemble()` 里
|
||||
## * 调用,而那时运行时节点**还没被加入场景树**,`global_transform` 会因为
|
||||
## * "!is_inside_tree()" 直接返回单位变换并**打一行 ERROR 日志**(真机上每次载入
|
||||
## * 场景都会刷一条),算出的包围盒也只是各网格的局部 AABB —— 对于把网格摆在
|
||||
## * 非原点位置的场景,重力/风区域与兜底地面会算得偏小或偏位,**风力可能作用不到**。
|
||||
## *
|
||||
## * 这里改成从根往下累乘 `Node3D.transform`:不依赖是否入树,结果与运行时被挂在
|
||||
## * 单位变换的父节点下时完全一致。
|
||||
static func _compute_aabb(node: Node, parent_transform: Transform3D = Transform3D.IDENTITY) -> AABB:
|
||||
var local := Transform3D.IDENTITY
|
||||
if node is Node3D:
|
||||
local = (node as Node3D).transform
|
||||
var here := parent_transform * local
|
||||
|
||||
var result := AABB()
|
||||
var first := true
|
||||
if node is MeshInstance3D:
|
||||
var mesh_node := node as MeshInstance3D
|
||||
if mesh_node.visible:
|
||||
result = mesh_node.global_transform * mesh_node.get_aabb()
|
||||
result = here * mesh_node.get_aabb()
|
||||
first = false
|
||||
for child in node.get_children():
|
||||
var child_aabb := _compute_aabb(child)
|
||||
var child_aabb := _compute_aabb(child, here)
|
||||
if child_aabb.size == Vector3.ZERO:
|
||||
continue
|
||||
if first:
|
||||
|
||||
Reference in New Issue
Block a user