Files
ChildHood/tools/level-builder/check_pivots.py
T
starmen1265 a3c38aa92a fix(level-builder): 锚点补偿+旋转修复+天空盒+解析器去重
- asset_mapping: 38种BSP资产实测锚点+pivot_offset_xy自动补偿
- scene_builder: Rotator改关键字参数修正旋转轴映射
- scene_builder: spawn前XY锚点补偿(支持Yaw旋转)
- scene_builder: 新增ExponentialHeightFog+大气效果后处理
- build_cmdline: 构建后自动添加雾+GameMode+DirectionalLight大气
- build_guide_parser: 去重+全局地面+旋转列名兼容+边界段范围修正
- BarrierWall实际尺寸修正(60×210非20×100)
- 搭建指南: 全局地面中心坐标+西边界旋转统一+院门改双开门
2026-06-08 19:05:50 +08:00

124 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""BSP 资产锚点检测脚本。
在 UE5 编辑器 Python 环境中运行,检测每个资产的 Bounds Origin,
判断锚点是中心、角落还是底部中心。
用法:
方式1 — 命令行: python main.py check-pivots
方式2 — 编辑器内: exec(open(r"check_pivots.py").read())
"""
import sys
import os
from pathlib import Path
# 将 level-builder 根目录加入 sys.path
_SCRIPT_DIR = Path(__file__).resolve().parent
_LB_DIR = _SCRIPT_DIR
if str(_LB_DIR) not in sys.path:
sys.path.insert(0, str(_LB_DIR))
from config.asset_mapping import MESH_ASSETS
try:
import unreal
HAS_UNREAL = True
except ImportError:
HAS_UNREAL = False
def check_pivots():
"""检测所有 BSP 资产的锚点类型。"""
if not HAS_UNREAL:
print("[错误] 需要在 UE5 编辑器 Python 环境中运行")
return
results = []
for name, info in MESH_ASSETS.items():
path = info["path"]
default_size = info.get("default_size")
mesh = unreal.load_asset(path)
if not mesh:
results.append(f"{name}: ⚠️ 无法加载")
continue
# 获取 Bounding Box (UE5 Box 对象有 min/max,没有 origin/extent)
bb = mesh.get_bounding_box()
bmin = bb.min
bmax = bb.max
mn_x, mn_y, mn_z = bmin.x, bmin.y, bmin.z
mx_x, mx_y, mx_z = bmax.x, bmax.y, bmax.z
size_x = mx_x - mn_x
size_y = mx_y - mn_y
size_z = mx_z - mn_z
# 判断锚点类型:
# CENTER: min ≈ (-half, -half, -half),对称包围盒
# CORNER: min ≈ (0, 0, 0),锚点在角落
# CENTER_BOTTOM: min ≈ (-half, -half, 0),锚点在底部中心
pivot_type = "UNKNOWN"
offset_desc = ""
if default_size:
dw, dh, dd = default_size
half_w, half_h, half_d = dw / 2, dh / 2, dd / 2
tol = 5 # cm 容差
is_corner = (abs(mn_x) < tol and abs(mn_y) < tol and abs(mn_z) < tol)
is_center = (abs(mn_x + half_w) < tol and abs(mn_y + half_h) < tol
and abs(mn_z + half_d) < tol)
is_center_bot = (abs(mn_x + half_w) < tol and abs(mn_y + half_h) < tol
and abs(mn_z) < tol)
if is_corner:
pivot_type = "CORNER"
elif is_center:
pivot_type = "CENTER"
elif is_center_bot:
pivot_type = "CENTER_BOTTOM"
else:
pivot_type = "OTHER"
offset_desc = f" (min=({mn_x:.0f},{mn_y:.0f},{mn_z:.0f}), expected corner=0/center=-{half_w:.0f})"
else:
# 无 default_size,用 min 值推断
tol = 5
if abs(mn_x) < tol and abs(mn_y) < tol and abs(mn_z) < tol:
pivot_type = "CORNER?"
elif mn_z < -tol:
pivot_type = "CENTER?"
else:
pivot_type = "CENTER_BOTTOM?"
offset_desc = f" (no default_size, inferred)"
results.append(
f"{name}:\n"
f" min=({mn_x:.1f}, {mn_y:.1f}, {mn_z:.1f}) "
f"max=({mx_x:.1f}, {mx_y:.1f}, {mx_z:.1f}) "
f"size=({size_x:.0f}, {size_y:.0f}, {size_z:.0f})\n"
f" default_size={default_size} → pivot={pivot_type}{offset_desc}"
)
print("=" * 60)
print("BSP 资产锚点检测结果")
print("=" * 60)
for r in results:
print(r)
print("=" * 60)
# 保存结果
out_path = Path(__file__).parent / "output" / "pivot_check.txt"
out_path.parent.mkdir(exist_ok=True)
with open(out_path, "w", encoding="utf-8") as f:
f.write("BSP 资产锚点检测结果\n")
f.write("=" * 60 + "\n")
for r in results:
f.write(r + "\n")
print(f"\n结果已保存: {out_path}")
# 供命令行调用
if __name__ == "__main__":
check_pivots()