5620347ffe
Keep authored JSON separate from generated output. Export rotated model bounds for SDK-free navigation and check grazing voxel corners. Include unretouched in-game before/after captures and explicit art/performance limits; pilots are an intermediate pass, not completion of the full asset set. Co-Authored-By: Codex <noreply@openai.com>
43 lines
2.0 KiB
Python
43 lines
2.0 KiB
Python
"""Export conservative model bounds for SDK-free chassis navigation."""
|
|
import itertools
|
|
import json
|
|
import math
|
|
from pathlib import Path
|
|
|
|
|
|
def model_bounds(model):
|
|
points = []
|
|
for element in model.get("elements", []):
|
|
rotation = element.get("rotation")
|
|
for point in itertools.product(*zip(element["from"], element["to"])):
|
|
point = list(point)
|
|
if rotation:
|
|
axis = "xyz".index(rotation["axis"])
|
|
a, b = (axis + 1) % 3, (axis + 2) % 3
|
|
origin = rotation["origin"]
|
|
x, y = point[a] - origin[a], point[b] - origin[b]
|
|
angle = math.radians(rotation["angle"])
|
|
# Rescaled rotations expand in the plane perpendicular to the rotation axis.
|
|
scale = 1 / math.cos(angle) if rotation.get("rescale") else 1
|
|
point[a] = origin[a] + (x * math.cos(angle) - y * math.sin(angle)) * scale
|
|
point[b] = origin[b] + (x * math.sin(angle) + y * math.cos(angle)) * scale
|
|
points.append(point)
|
|
if not points:
|
|
return None
|
|
return tuple([min(p[a] for p in points) for a in range(3)]), tuple([max(p[a] for p in points) for a in range(3)])
|
|
|
|
|
|
def write_rust_bounds(stage):
|
|
stage = Path(stage)
|
|
rows = ["// Generated by tools/gen_models.py from the final staged models; do not edit.\n",
|
|
"pub fn bounds(id: &str) -> Option<([f64; 3], [f64; 3])> {\n Some(match id {\n"]
|
|
for path in sorted((stage / "assets/airdef/models/block").glob("*.json")):
|
|
bounds = model_bounds(json.loads(path.read_text(encoding="utf-8")))
|
|
if bounds:
|
|
lo, hi = ([round(float(x), 6) for x in corner] for corner in bounds)
|
|
rows.append(f' "airdef:{path.stem}" => ({lo}, {hi}),\n')
|
|
rows.append(" _ => return None,\n })\n}\n")
|
|
target = stage / "src/sim/generated_bounds.rs"
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
target.write_text("".join(rows), encoding="utf-8")
|