Files
mtgodot-poc/oracle/run-diff-suite.sh
T
2026-09-28 19:39:13 -07:00

117 lines
5.5 KiB
Bash
Executable File
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.
#!/usr/bin/env bash
# M2 门禁·主:对测试资产集跑 oracle dump + oracle_diff,汇总 test/m2-numeric.json。
# 前置:oracle/build-wine.sh 已产出 oracle.exe;WINEPREFIX 已 init(见 RUNBOOK.md);
# oracle_diff 已构建(cmake -B build-tools -DMT_BUILD_TOOLS=ON)。
set -uo pipefail
cd "$(dirname "$0")/.."
REPO="$(pwd)"
ASSETS="$(cd "${MT_ASSETS:-$REPO/assets}" && pwd)"
DUMPS="$REPO/test/oracle_dumps"
DIFF=""
for c in "$REPO/build-tools/tools/oracle_diff" "$REPO/build/tools/oracle_diff"; do
[ -x "$c" ] && DIFF="$c" && break
done
[ -n "$DIFF" ] || { echo "oracle_diff not built — run: cmake -B build-tools -DMT_BUILD_TOOLS=ON && cmake --build build-tools"; exit 2; }
mkdir -p "$DUMPS"
WINE="${WINE:-/tmp/wine/Wine Stable.app/Contents/Resources/wine/bin/wine}"
export WINEPREFIX="${WINEPREFIX:-$HOME/.wine-oracle}" WINEDEBUG="${WINEDEBUG:--all}"
# Z: 盘映射到 /
winpath() { printf 'Z:%s' "$(printf '%s' "$1" | sed 's#/#\\#g')"; }
# 用例:<model 相对 assets> | <anim 相对 assets,或 -> | <t> | <mesh idx>
CASES=$(cat <<'EOF'
PC/ymir work/pc/warrior/warrior_cheongrin.gr2|-|0|4
PC/ymir work/pc/warrior/warrior_cheongrin_lod_01.gr2|-|0|4
PC/ymir work/pc/warrior/warrior_cheongrin_lod_02.gr2|-|0|4
PC/ymir work/pc/warrior/warrior_cheongrin_lod_03.gr2|-|0|4
PC/ymir work/pc/warrior/warrior_lord.gr2|-|0|1
PC/ymir work/pc/warrior/warrior_lord_lod_01.gr2|-|0|1
PC/ymir work/pc/warrior/warrior_lord_lod_02.gr2|-|0|1
PC/ymir work/pc/warrior/warrior_lord_lod_03.gr2|-|0|1
PC/ymir work/pc/assassin/assassin.gr2|-|0|16
PC/ymir work/pc/shaman/shaman_lord.gr2|-|0|0
metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_soldier2/redthief2_soldier2_lod_01.gr2|-|0|4
monster2/ymir work/monster2/snakeman_bow/snakeman_bow_lod_01.gr2|-|0|0
monster2/ymir work/monster2/snakeman_bow/snakeman_bow_lod_01.gr2|-|0|1
metin2_patch_easter1/ymir work/pc/warrior/warrior_rabbit1_backup.gr2|-|0|0
Zone/ymir work/zone/oxevent/ox_01.gr2|-|0|0
PC/ymir work/pc/warrior/warrior_cheongrin.gr2|PC/ymir work/pc/warrior/action/dance_1.gr2|0|4
PC/ymir work/pc/warrior/warrior_cheongrin.gr2|PC/ymir work/pc/warrior/action/dance_1.gr2|4.7|4
PC/ymir work/pc/warrior/warrior_cheongrin.gr2|PC/ymir work/pc/warrior/action/dance_1.gr2|11.333|4
PC/ymir work/pc/warrior/warrior_cheongrin.gr2|PC/ymir work/pc/warrior/action/dance_1.gr2|20|4
PC/ymir work/pc/warrior/warrior_cheongrin.gr2|PC/ymir work/pc/warrior/general/attack.gr2|0.3|4
PC/ymir work/pc/warrior/warrior_cheongrin.gr2|PC/ymir work/pc/warrior/general/run.gr2|0.5|4
PC/ymir work/pc/warrior/warrior_lord.gr2|PC/ymir work/pc/warrior/action/dance_1.gr2|10|1
PC/ymir work/pc/warrior/warrior_lord.gr2|PC/ymir work/pc/warrior/general/wait.gr2|1.0|1
EOF
)
key_for() { echo "$1|$2|$3|$4" | md5 -q | cut -c1-12; }
# ── 1. dump(并行,4 个一批)──────────────────────────────────────────
run_dump() {
local model="$1" anim="$2" t="$3" mesh="$4" out="$5"
local wm; wm="$(winpath "$ASSETS/$model")"
local wa="-"; [ "$anim" != "-" ] && wa="$(winpath "$ASSETS/$anim")"
local wo; wo="$(winpath "$out")"
"$WINE" "$REPO/oracle/oracle.exe" dump "$wm" "$wa" "$t" -o "$wo" --mesh "$mesh" >/dev/null 2>&1
}
echo "== oracle dump =="
i=0
while IFS='|' read -r model anim t mesh; do
[ -z "$model" ] && continue
k=$(key_for "$model" "$anim" "$t" "$mesh")
out="$DUMPS/suite_$k.bin"
run_dump "$model" "$anim" "$t" "$mesh" "$out" &
i=$((i+1)); [ $((i % 4)) -eq 0 ] && wait
done <<< "$CASES"
wait
# ── 2. diff + 汇总 ─────────────────────────────────────────────────────
echo "== oracle_diff =="
JSON="$REPO/test/m2-numeric.json"
{
echo '{'
echo ' "granny": "2.9.12.0",'
echo ' "threshold": {"mat": 1e-3, "vtx": 1e-3},'
echo ' "cases": ['
} > "$JSON"
total=0; passed=0; first=1
worst_mat=0; worst_vtx=0
while IFS='|' read -r model anim t mesh; do
[ -z "$model" ] && continue
k=$(key_for "$model" "$anim" "$t" "$mesh")
bin="$DUMPS/suite_$k.bin"
total=$((total+1))
if [ ! -s "$bin" ]; then
line=" {\"model\":\"$(basename "$model")\",\"anim\":\"$(basename "$anim")\",\"t\":$t,\"mesh\":$mesh,\"status\":\"NO_DUMP\"}"
else
amodel="$ASSETS/$model"; aanim="-"; [ "$anim" != "-" ] && aanim="$ASSETS/$anim"
v=$("$DIFF" "$amodel" "$aanim" "$bin" --mesh "$mesh" 2>/dev/null | tail -1)
m=$(echo "$v" | sed -n 's/.*mat \([0-9.e+-]*\) <.*/\1/p')
vt=$(echo "$v" | sed -n 's/.*vtx \([0-9.e+-]*\) <.*/\1/p')
st="FAIL"; echo "$v" | grep -q PASS && { st="PASS"; passed=$((passed+1)); }
awk -v m="$m" -v w="$worst_mat" 'BEGIN{exit !(m+0>w+0)}' && worst_mat=$m
awk -v m="$vt" -v w="$worst_vtx" 'BEGIN{exit !(m+0>w+0)}' && worst_vtx=$vt
printf ' [%-4s] %-40s %-14s mat=%-10s vtx=%s\n' "$st" "$(basename "$model")" "$(basename "$anim") @${t}" "$m" "$vt"
line=" {\"model\":\"$(basename "$model")\",\"anim\":\"$(basename "$anim")\",\"t\":$t,\"mesh\":$mesh,\"mat\":$m,\"vtx\":$vt,\"status\":\"$st\"}"
fi
[ $first -eq 1 ] && first=0 || echo ',' >> "$JSON"
printf '%s' "$line" >> "$JSON"
done <<< "$CASES"
{
echo ''
echo ' ],'
echo " \"summary\": {\"total\": $total, \"passed\": $passed, \"worst_mat\": $worst_mat, \"worst_vtx\": $worst_vtx}"
echo '}'
} >> "$JSON"
echo
echo "== $passed/$total PASS worst mat=$worst_mat vtx=$worst_vtx → $JSON =="
[ "$passed" -eq "$total" ]