Files
TeslaRel410/restoration/gallery_build.py
T
CydandClaude Fable 5 326d29b72a Extract all recoverable Division scenes; add Scene Archive gallery
Cracks the DIV-BIZ2 binary format (BGF/BMF) using Division's own
reader source (DPL3/BIZREAD.C) as reference: block stream, 14 vertex
layouts, pmesh/strip connectivity, LOD nesting, embedded materials.
Adds SVT raw-texture decoding, 1995-dialect VGF support (implicit
CONNECTION_LIST, header SCALE), and a whole-drive scene audit.

108 of 241 scenes on the Glaze drive are recoverable; 26 are curated
into restoration/vwe-archive.html, a self-contained WebGL gallery:
Star Trek, Hull Pressure, BattleTech (incl. the polar-map mech
lineup), Red Planet's Mars-canal raceway, and the Canyon demos.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 18:03:12 -05:00

112 lines
5.6 KiB
Python

"""Build the gallery HTML: curated scenes from allscenes.json injected into
gallery_template.html."""
import json, os
CURATED = [
# (scene key, project, display name, blurb)
("STDAVE/TREK.SCN", "Star Trek", "Enterprise-D",
"The Enterprise-D at rest among three parallax layers of drifting stars."),
("STDAVE/KLNGVID.SCN", "Star Trek", "Klingon flyby",
"A Klingon cruiser at rest while two more drift past on spline paths."),
("STDAVE/TREKVID.SCN", "Star Trek", "Enterprise flyby",
"Camera-pass variant of the Enterprise scene, built for video capture."),
("HPDAVE/SDEMO.SCN", "Hull Pressure", "Sea demo",
"The big Hull Pressure demo: seafloor, wrecks, and marine life on spline paths."),
("HPDAVE/FISHSPLS.SCN", "Hull Pressure", "Fish schools",
"Schools of fish and sharks swimming spline circuits over the seabed."),
("HPDAVE/BDDEMO.SCN", "Hull Pressure", "Big demo",
"Full underwater environment demo for the unreleased submarine game."),
("HPDAVE/TMPRIGS.SCN", "Hull Pressure", "Temple rigs",
"Sunken temple environment with rig structures."),
("HPDAVE/DUANE.SCN", "Hull Pressure", "Duane's scene",
"An underwater scene named for one of the team."),
("HPDAVE/SANDTEST.SCN", "Hull Pressure", "Sand test",
"Seafloor sand and lighting test."),
("BTDAVE/MAPS/POLAR4.SCN", "BattleTech", "Polar map",
"The polar arena environment, assembled from 99 models."),
("BTRAVINE/RAVTEST.SCN", "BattleTech", "Ravine map",
"The Ravine arena in development — this environment shipped as RAV/RAV1."),
("BTRAVINE/DESTEST.SCN", "BattleTech", "Desert test",
"Desert environment test with full map furniture."),
("BTDAVE/MAPS/DTEST.SCN", "BattleTech", "Desert map test",
"A smaller desert map assembly test."),
("CONVERT/BTECH/STAD/STAD.SCN", "BattleTech", "Stadium",
"Arena stadium model in the art-conversion workspace."),
("DPL3RLS/SCENES/MISSILE.SCN", "BattleTech", "Missile test",
"Weapon-effects staging scene with arena props."),
("RPDAVE/SCENES/BLADE.SCN", "Red Planet", "Blade arena",
"The Blade racing arena — late Red Planet development work."),
("CONVERT/MILESTON/MILESTON.SCN", "Red Planet", "Milestone",
"The Red Planet milestone demo: Mars mining-canal raceway."),
("CONVERT/MILESTON/WELLENT.SCN", "Red Planet", "Well entrance",
"Raceway well-entrance sequence from the milestone build."),
("CONVERT/RD/CHOICE2.SCN", "Red Planet", "Choice point",
"A raceway fork (“choice”) section of the Mars canals."),
("RD/VTER.SCN", "Red Planet", "Terrain",
"Generated Mars terrain heightfield test."),
("CANYON/CANYON.SCN", "Canyon demo", "Canyon",
"River-canyon flythrough environment — Division demo work."),
("CANYON/CANABOVE.SCN", "Canyon demo", "Canyon from above",
"The canyon seen from altitude."),
("CANYON/TEMPLE.SCN", "Canyon demo", "Maya temple",
"Mayan temple set piece at the canyon rim."),
("ERIC/VANSMAK.SCN", "Misc", "Van's MAK",
"A 31-model scene from developer Eric's directory."),
("HPDAVE/BATEST.SCN", "Hull Pressure", "Bathysphere test",
"Single-model test of the submersible."),
("CONVERT/CALIB/DIVCAL.SCN", "Misc", "Division calibration",
"Display-calibration model used to align the pod projectors."),
]
# camera overrides for scenes whose START sits inside geometry (dev scenes);
# None = use the viewer's auto-framing instead
START_OVERRIDE = {
"BTRAVINE/RAVTEST.SCN": [280, 30, 160, -8, 25, 0],
"CANYON/CANYON.SCN": None,
"CANYON/CANABOVE.SCN": None,
"CANYON/TEMPLE.SCN": None,
"BTDAVE/MAPS/DTEST.SCN": None,
"CONVERT/CALIB/DIVCAL.SCN": None,
}
here = os.path.dirname(os.path.abspath(__file__))
data = json.load(open(os.path.join(here, "allscenes.json")))
out = {"models": {}, "images": {}, "scenes": {}, "catalog": []}
for key, project, name, blurb in CURATED:
sc = data["scenes"].get(key)
if not sc:
print("MISSING SCENE:", key)
continue
if key in START_OVERRIDE:
sc = dict(sc); sc["start"] = START_OVERRIDE[key]
if sc["start"] is None: del sc["start"]
out["scenes"][key] = sc
out["catalog"].append({"key": key, "project": project, "name": name, "blurb": blurb})
for mid in sc["modelmap"].values():
out["models"][mid] = data["models"][mid]
for mat in sc["materials"].values():
if mat and mat.get("img"):
out["images"][mat["img"]] = data["images"][mat["img"]]
# per-model bounding radius for auto-framing
for mid, groups in out["models"].items():
lo = [1e9] * 3; hi = [-1e9] * 3
for g in groups:
for v in g.get("v", g.get("points", [])):
for i in range(3):
lo[i] = min(lo[i], v[i]); hi[i] = max(hi[i], v[i])
if lo[0] > hi[0]: lo = hi = [0, 0, 0]
for g in groups: pass
c = [(lo[i] + hi[i]) / 2 for i in range(3)]
r = max(hi[i] - lo[i] for i in range(3)) / 2 or 1
out.setdefault("bounds", {})[mid] = {"c": [round(x, 2) for x in c], "r": round(r, 2)}
blob = json.dumps(out, separators=(",", ":"))
print("gallery data: %.1f MB, %d scenes, %d models, %d images"
% (len(blob) / 1e6, len(out["scenes"]), len(out["models"]), len(out["images"])))
tpl = open(os.path.join(here, "gallery_template.html"), encoding="utf-8").read()
open(os.path.join(here, "vwe-archive.html"), "w", encoding="utf-8").write(
tpl.replace("%%DATA%%", blob))
print("wrote vwe-archive.html", os.path.getsize(os.path.join(here, "vwe-archive.html")) / 1e6, "MB")