116 lines
3.9 KiB
Bash
Executable File
116 lines
3.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Download a free skinned character (Khronos CesiumMan) for skeletal animation tests.
|
|
# Output: test/assets/skinned/cesium_man/glTF/
|
|
#
|
|
# Usage:
|
|
# scripts/download_skinned_character.sh
|
|
# EVENGINE_SKINNED_DIR=/path scripts/download_skinned_character.sh
|
|
#
|
|
# Idempotent: skips files that already exist with the expected size.
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
OUT_ROOT="${EVENGINE_SKINNED_DIR:-$ROOT/test/assets/skinned}"
|
|
BASE_RAW="https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models"
|
|
API_BASE="https://api.github.com/repos/KhronosGroup/glTF-Sample-Assets/contents/Models"
|
|
|
|
need_cmd() {
|
|
command -v "$1" >/dev/null 2>&1 || {
|
|
echo "error: required command not found: $1" >&2
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
CURL_OPTS=(--retry 5 --retry-delay 2 --retry-all-errors --connect-timeout 30)
|
|
# Prefer system CA bundle (avoids flaky "self-signed certificate" on some CI runners).
|
|
for _ca in /etc/ssl/certs/ca-certificates.crt /etc/pki/tls/certs/ca-bundle.crt; do
|
|
if [ -f "$_ca" ]; then
|
|
CURL_OPTS+=(--cacert "$_ca")
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Vendored in-repo for CI/offline builds; skip network when complete.
|
|
if [ -f "$OUT_ROOT/.downloaded" ] &&
|
|
[ -f "$OUT_ROOT/cesium_man/glTF/CesiumMan.gltf" ] &&
|
|
[ -f "$OUT_ROOT/cesium_man/glTF/CesiumMan_data.bin" ] &&
|
|
[ -f "$OUT_ROOT/cesium_man/glTF/CesiumMan_img0.jpg" ]; then
|
|
echo "Skinned character already present under $OUT_ROOT (skip download)"
|
|
exit 0
|
|
fi
|
|
|
|
need_cmd curl
|
|
need_cmd python3
|
|
|
|
download_model_gltf() {
|
|
local model="$1"
|
|
local dest="$OUT_ROOT/$2/glTF"
|
|
local api_url="$API_BASE/$model/glTF?ref=main"
|
|
local listing_json
|
|
local listing_file
|
|
|
|
mkdir -p "$dest"
|
|
echo "==> Listing $model via GitHub API"
|
|
listing_file="$(mktemp)"
|
|
# GitHub API rejects anonymous requests without User-Agent; CI may 403 without a token.
|
|
curl_args=("${CURL_OPTS[@]}" -fsSL
|
|
-H "User-Agent: evengine-skinned-character"
|
|
-H "Accept: application/vnd.github+json")
|
|
if [ -n "${GITHUB_TOKEN:-}" ]; then
|
|
curl_args+=(-H "Authorization: Bearer ${GITHUB_TOKEN}")
|
|
fi
|
|
curl "${curl_args[@]}" "$api_url" -o "$listing_file"
|
|
listing_json="$listing_file"
|
|
|
|
python3 - "$dest" "$BASE_RAW/$model/glTF" "$listing_json" <<'PY'
|
|
import json, os, sys, urllib.request
|
|
|
|
dest, raw_base, listing_path = sys.argv[1], sys.argv[2], sys.argv[3]
|
|
with open(listing_path, "r", encoding="utf-8") as f:
|
|
items = json.load(f)
|
|
|
|
def fetch(url: str, path: str, expected) -> None:
|
|
os.makedirs(os.path.dirname(path), exist_ok=True)
|
|
if os.path.isfile(path) and expected is not None and os.path.getsize(path) == expected:
|
|
print(f" skip {os.path.basename(path)} ({expected} bytes)")
|
|
return
|
|
if os.path.isfile(path) and expected is None and os.path.getsize(path) > 0:
|
|
print(f" skip {os.path.basename(path)}")
|
|
return
|
|
print(f" get {os.path.basename(path)}")
|
|
req = urllib.request.Request(url, headers={"User-Agent": "evengine-skinned-character"})
|
|
with urllib.request.urlopen(req, timeout=180) as r, open(path, "wb") as out:
|
|
while True:
|
|
chunk = r.read(1024 * 256)
|
|
if not chunk:
|
|
break
|
|
out.write(chunk)
|
|
if expected is not None and os.path.getsize(path) != expected:
|
|
raise SystemExit(
|
|
f"size mismatch for {path}: got {os.path.getsize(path)}, want {expected}"
|
|
)
|
|
|
|
for it in items:
|
|
if it.get("type") != "file":
|
|
continue
|
|
name = it["name"]
|
|
url = f"{raw_base}/{name}"
|
|
fetch(url, os.path.join(dest, name), it.get("size"))
|
|
PY
|
|
rm -f "$listing_json"
|
|
echo "==> $model ready under $dest"
|
|
}
|
|
|
|
mkdir -p "$OUT_ROOT"
|
|
|
|
# CesiumMan (~0.5 MB) — free skinned walking character (CC-BY 4.0 via Khronos samples).
|
|
download_model_gltf "CesiumMan" "cesium_man"
|
|
|
|
cat >"$OUT_ROOT/.downloaded" <<EOF
|
|
cesium_man
|
|
EOF
|
|
|
|
echo "Skinned character installed under $OUT_ROOT"
|
|
du -sh "$OUT_ROOT/cesium_man" 2>/dev/null || true
|