refs: survey the sibling project and recalibrate the hero facade
Tools/sibling_asset_audit.py reads the sibling security-game project's prop library straight from the GLB headers: 20 street props, 11.8k triangles, every one with a Blender source. The 50 .blend sources are copied to Art/props/blender_src/ with a manifest; nothing is imported into Unreal yet. Its building meshes are deliberately not taken - they are Godot GLBs built around a 29.6 m facade that this project measured at 25.75 m. The facade proportions were wrong against the photograph: 5.7 m of blank wall above the capitals. Entablature is now 3.4 m, parapet 2.2 m, with architrave and cornice bands and square pedestals, so the elevation reads as layered stone.
This commit is contained in:
1 parent
52a736bc9f
commit
5e5e5ae9b4
67 files changed
+591
-27
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,288 @@
|
||||
{
|
||||
"source_project": "/run/media/system/DATA/Documents/06-games/security-game",
|
||||
"scanned": "assets/models/blender/props + assets/models/blender_src",
|
||||
"licence": "project-owned (same author); confirm before shipping",
|
||||
"note": "audit only \u2014 nothing has been copied",
|
||||
"props": [
|
||||
{
|
||||
"prop": "a_frame_sign",
|
||||
"glb": "a_frame_sign.glb",
|
||||
"bytes": 19120,
|
||||
"blend_source": "a_frame_sign.blend",
|
||||
"blend_bytes": 96742,
|
||||
"triangles": 212,
|
||||
"size_gltf": [
|
||||
0.62,
|
||||
0.965,
|
||||
0.527
|
||||
],
|
||||
"materials": 4
|
||||
},
|
||||
{
|
||||
"prop": "bench",
|
||||
"glb": "bench.glb",
|
||||
"bytes": 36268,
|
||||
"blend_source": "bench.blend",
|
||||
"blend_bytes": 102020,
|
||||
"triangles": 560,
|
||||
"size_gltf": [
|
||||
1.8,
|
||||
0.844,
|
||||
0.522
|
||||
],
|
||||
"materials": 2
|
||||
},
|
||||
{
|
||||
"prop": "bollard",
|
||||
"glb": "bollard.glb",
|
||||
"bytes": 10020,
|
||||
"blend_source": "bollard.blend",
|
||||
"blend_bytes": 92615,
|
||||
"triangles": 138,
|
||||
"size_gltf": [
|
||||
0.25,
|
||||
0.975,
|
||||
0.25
|
||||
],
|
||||
"materials": 2
|
||||
},
|
||||
{
|
||||
"prop": "crowd_barrier",
|
||||
"glb": "crowd_barrier.glb",
|
||||
"bytes": 24808,
|
||||
"blend_source": "crowd_barrier.blend",
|
||||
"blend_bytes": 96463,
|
||||
"triangles": 388,
|
||||
"size_gltf": [
|
||||
2.248,
|
||||
1.084,
|
||||
0.613
|
||||
],
|
||||
"materials": 1
|
||||
},
|
||||
{
|
||||
"prop": "double_door",
|
||||
"glb": "double_door.glb",
|
||||
"bytes": 33336,
|
||||
"blend_source": "double_door.blend",
|
||||
"blend_bytes": 101710,
|
||||
"triangles": 380,
|
||||
"size_gltf": [
|
||||
2.165,
|
||||
2.72,
|
||||
0.2
|
||||
],
|
||||
"materials": 6
|
||||
},
|
||||
{
|
||||
"prop": "fire_hydrant",
|
||||
"glb": "fire_hydrant.glb",
|
||||
"bytes": 34684,
|
||||
"blend_source": "fire_hydrant.blend",
|
||||
"blend_bytes": 102818,
|
||||
"triangles": 610,
|
||||
"size_gltf": [
|
||||
0.53,
|
||||
0.815,
|
||||
0.47
|
||||
],
|
||||
"materials": 2
|
||||
},
|
||||
{
|
||||
"prop": "handrail",
|
||||
"glb": "handrail.glb",
|
||||
"bytes": 15656,
|
||||
"blend_source": "handrail.blend",
|
||||
"blend_bytes": 93785,
|
||||
"triangles": 268,
|
||||
"size_gltf": [
|
||||
2.209,
|
||||
1.784,
|
||||
0.1
|
||||
],
|
||||
"materials": 1
|
||||
},
|
||||
{
|
||||
"prop": "marquee",
|
||||
"glb": "marquee.glb",
|
||||
"bytes": 126272,
|
||||
"blend_source": "marquee.blend",
|
||||
"blend_bytes": 144786,
|
||||
"triangles": 2804,
|
||||
"size_gltf": [
|
||||
6,
|
||||
2.044,
|
||||
1.67
|
||||
],
|
||||
"materials": 3
|
||||
},
|
||||
{
|
||||
"prop": "newspaper_box",
|
||||
"glb": "newspaper_box.glb",
|
||||
"bytes": 27304,
|
||||
"blend_source": "newspaper_box.blend",
|
||||
"blend_bytes": 99783,
|
||||
"triangles": 300,
|
||||
"size_gltf": [
|
||||
0.44,
|
||||
0.916,
|
||||
0.386
|
||||
],
|
||||
"materials": 5
|
||||
},
|
||||
{
|
||||
"prop": "palm_tree",
|
||||
"glb": "palm_tree.glb",
|
||||
"bytes": 20912,
|
||||
"blend_source": "palm_tree.blend",
|
||||
"blend_bytes": 100466,
|
||||
"triangles": 400,
|
||||
"size_gltf": [
|
||||
4.0,
|
||||
6.99,
|
||||
3.9
|
||||
],
|
||||
"materials": 3
|
||||
},
|
||||
{
|
||||
"prop": "planter_box",
|
||||
"glb": "planter_box.glb",
|
||||
"bytes": 63276,
|
||||
"blend_source": "planter_box.blend",
|
||||
"blend_bytes": 114862,
|
||||
"triangles": 818,
|
||||
"size_gltf": [
|
||||
1.0,
|
||||
1.118,
|
||||
1.0
|
||||
],
|
||||
"materials": 4
|
||||
},
|
||||
{
|
||||
"prop": "round_planter",
|
||||
"glb": "round_planter.glb",
|
||||
"bytes": 56664,
|
||||
"blend_source": "round_planter.blend",
|
||||
"blend_bytes": 113201,
|
||||
"triangles": 808,
|
||||
"size_gltf": [
|
||||
0.759,
|
||||
1.175,
|
||||
0.736
|
||||
],
|
||||
"materials": 3
|
||||
},
|
||||
{
|
||||
"prop": "security_podium",
|
||||
"glb": "security_podium.glb",
|
||||
"bytes": 18968,
|
||||
"blend_source": "security_podium.blend",
|
||||
"blend_bytes": 97217,
|
||||
"triangles": 184,
|
||||
"size_gltf": [
|
||||
0.64,
|
||||
1.167,
|
||||
0.487
|
||||
],
|
||||
"materials": 5
|
||||
},
|
||||
{
|
||||
"prop": "sedan",
|
||||
"glb": "sedan.glb",
|
||||
"bytes": 50348,
|
||||
"blend_source": "sedan.blend",
|
||||
"blend_bytes": 111241,
|
||||
"triangles": 928,
|
||||
"size_gltf": [
|
||||
1.85,
|
||||
1.32,
|
||||
4.625
|
||||
],
|
||||
"materials": 6
|
||||
},
|
||||
{
|
||||
"prop": "stanchion",
|
||||
"glb": "stanchion.glb",
|
||||
"bytes": 19048,
|
||||
"blend_source": "stanchion.blend",
|
||||
"blend_bytes": 99736,
|
||||
"triangles": 434,
|
||||
"size_gltf": [
|
||||
1.095,
|
||||
1.01,
|
||||
0.34
|
||||
],
|
||||
"materials": 3
|
||||
},
|
||||
{
|
||||
"prop": "street_lamp",
|
||||
"glb": "street_lamp.glb",
|
||||
"bytes": 22740,
|
||||
"blend_source": "street_lamp.blend",
|
||||
"blend_bytes": 99309,
|
||||
"triangles": 428,
|
||||
"size_gltf": [
|
||||
1.3,
|
||||
4.985,
|
||||
0.5
|
||||
],
|
||||
"materials": 2
|
||||
},
|
||||
{
|
||||
"prop": "street_tree",
|
||||
"glb": "street_tree.glb",
|
||||
"bytes": 119588,
|
||||
"blend_source": "street_tree.blend",
|
||||
"blend_bytes": 134001,
|
||||
"triangles": 1506,
|
||||
"size_gltf": [
|
||||
2.191,
|
||||
3.634,
|
||||
2.133
|
||||
],
|
||||
"materials": 4
|
||||
},
|
||||
{
|
||||
"prop": "traffic_cone",
|
||||
"glb": "traffic_cone.glb",
|
||||
"bytes": 13328,
|
||||
"blend_source": "traffic_cone.blend",
|
||||
"blend_bytes": 95292,
|
||||
"triangles": 210,
|
||||
"size_gltf": [
|
||||
0.38,
|
||||
0.69,
|
||||
0.38
|
||||
],
|
||||
"materials": 3
|
||||
},
|
||||
{
|
||||
"prop": "trash_bin",
|
||||
"glb": "trash_bin.glb",
|
||||
"bytes": 18584,
|
||||
"blend_source": "trash_bin.blend",
|
||||
"blend_bytes": 95841,
|
||||
"triangles": 228,
|
||||
"size_gltf": [
|
||||
0.527,
|
||||
0.92,
|
||||
0.536
|
||||
],
|
||||
"materials": 3
|
||||
},
|
||||
{
|
||||
"prop": "wall_lantern",
|
||||
"glb": "wall_lantern.glb",
|
||||
"bytes": 13752,
|
||||
"blend_source": "wall_lantern.blend",
|
||||
"blend_bytes": 93826,
|
||||
"triangles": 180,
|
||||
"size_gltf": [
|
||||
0.22,
|
||||
0.33,
|
||||
0.365
|
||||
],
|
||||
"materials": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -105,3 +105,11 @@ Scope: facts and traps that cost time to establish. Planned work lives in [ROADM
|
||||
- **`StaticMaterial` is a struct**: `material.get_editor_property("material_interface")`, no `get_name()` on the wrapper.
|
||||
- **Review screenshots are committed on the owner's instruction (2026-11-07).** They are large PNGs, so a review run adds weight to the repo; keep the shot list short and delete retired shots rather than accumulating.
|
||||
|
||||
## 2026-11-07 — Sibling project reuse survey
|
||||
|
||||
- **`security-game` holds 20 reusable street props** with Blender sources (`assets/models/blender_src/*.blend`) and Godot GLBs: bollard, bench, trash bin, stanchion, crowd barrier, street lamp, traffic cone, fire hydrant, newspaper box, palm/street trees, sedan, marquee, doors, lanterns. About 727 KB and 11.8k triangles for the set. Audit: `Tools/sibling_asset_audit.py`, manifest at `Art/props/reuse-manifest.json`; the 50 `.blend` sources are copied to `Art/props/blender_src/`.
|
||||
- **Their building meshes are not reusable** — they are Godot GLBs built to a different key set (hero facade scaled to 29.6 m, a figure this project measured at 25.75 m). Do not import their venue geometry.
|
||||
- **`tools/generate_textures.py` in that project is the OpenRouter image endpoint pattern** (`POST /api/v1/images`, `b64_json`, optional `reference_path` for image-to-image on the chat endpoint) and it already has procedural `brick_facade` / `seamless_concrete` / `asphalt` generators. Worth porting for our facade materials.
|
||||
- **Its AI concept frames are restaged photograph references** (`.refgen.json` sidecars point at photos with a "keep geometry fixed" suffix). Useful as art direction, not as texture sources.
|
||||
- **Blosm exposes `setupScript`** (`scene.blosm.setupScript` → `loadSetupScript`) for custom building materials, and ships `setup/neoclassical.py` as an example — the hook for giving OSM buildings a per-building facade style instead of flat colours.
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ Follow-on work on the player avatar, after the review scene passes. None of it i
|
||||
- [x] Establish a consistent scale test, named export presets, and repeatable import settings. Scale test = the three-cube calibration scene (`Art/blender/scaletest/`, regenerable via `Tools/scale_test_export.py`); named export preset `ue_metric_v1` (FBX settings in that script); named import preset `ue_metric_v1` (`FbxImportUI` settings in `Tools/ue_scale_test_import.py`). Both scripts are the templates for production asset export/import.
|
||||
- [-] Collect reference photography for manual façade work. Local only, never committed: `Art/reference/` is gitignored. **72 images in eleven folders**: hero façades to 4k, the El Capitan Theatre exterior series, premiere-night staging, Ovation Hollywood, the north side, and the Lee Drug neighbour. Gaps largely closed by the Flickr/web-search pass: the hero entrance is now documented (three portals with individual short flights — the inherited "eight steps, 12 m wide" is overturned), and the 6806–6822 retail run appears in an oblique 2013 frame. Still missing: a clean isolated frame of the door recess and a night frame of 6840 itself.
|
||||
- [x] Download reference photography for the two north-side buildings inside the 50 m buffer — TCL Chinese Theatre (OSM way 424105908, 6925 Hollywood Blvd) and Madame Tussaud's (way 424105889, 6933 Hollywood Blvd). Done 2026-11-06 with `Tools/commons_fetch.py` against the Wikimedia Commons API: eleven frames in the local `Art/reference/north-chinese/` and `Art/reference/north-tussauds/`, provenance in each `sidecar.json`, nothing committed.
|
||||
- [-] Model hero façade for the El Capitan Entertainment Centre site. **First pass built 2026-11-07** (`Tools/hero_facade_build.py` → `Art/blender/hero/hero-facade-2026-11-07.blend` + JSON part report with evidence per part → `Tools/ue_hero_facade_import.py` → `/Game/Hollywood/ElCapitan/SM_HeroFacade`, 1892 tris, 4 materials, placed on the measured building line). Six columns at 4.96 m over the 25.75 m frontage, plinth, three portal flights (5 risers, not the old 8), entablature 2.2 m, parapet 1.6 m with motto band and medallions. **Screenshot review pending** (`Screenshots/review-04`, `review-05`). Next pass: portal recesses read from the street, banner and window placement, then materials.
|
||||
- [x] Model hero façade for the El Capitan Entertainment Centre site. **Second pass built 2026-11-07** (proportions recalibrated from the 2009 photograph: entablature 3.4 m, parapet 2.2 m, architrave and cornice bands, square pedestals — the first pass had 5.7 m of blank wall above the capitals and read as a warehouse). **First pass built 2026-11-07** (`Tools/hero_facade_build.py` → `Art/blender/hero/hero-facade-2026-11-07.blend` + JSON part report with evidence per part → `Tools/ue_hero_facade_import.py` → `/Game/Hollywood/ElCapitan/SM_HeroFacade`, 1892 tris, 4 materials, placed on the measured building line). Six columns at 4.96 m over the 25.75 m frontage, plinth, three portal flights (5 risers, not the old 8), entablature 2.2 m, parapet 1.6 m with motto band and medallions. **Screenshot review pending** (`Screenshots/review-04`, `review-05`). Next pass: portal recesses read from the street, banner and window placement, then materials.
|
||||
- [ ] Model surrounding block frontage.
|
||||
- [ ] Model simplified background buildings directly across Hollywood Boulevard.
|
||||
- [-] Build sidewalks, roads, and collision meshes. Terrain, road, sidewalks and kerbs exist (`Art/blender/terrain/`, `street/`) and are assembled in `site/site-2026-11-06.blend`; collision and details (crossing markings, kerb radii, aprons) are not built. Ground must follow the DEM: 3.94 m fall along the block, ~2 % crown between the gutters at ±10–11 m from the centreline, north sidewalk higher than south. Kerb height is an unresolved assumption — the DEM does not resolve it (`Geo/verification/2026-11-06-cross-sections.md`).
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -43,11 +43,15 @@ COLUMN_BAY = 4.96
|
||||
FRONTAGE_Y = 0.0 # front plane sits at the building line of the block frame
|
||||
|
||||
# --- assumptions -------------------------------------------------------------
|
||||
# Calibrated against the 2009 façade photograph: the entablature starts a little
|
||||
# over half the total height, and the parapet carries the motto at about three
|
||||
# quarters. The first pass had the enframed wall carrying 5.7 m of blank stone
|
||||
# above the capitals, which read as a warehouse rather than a temple.
|
||||
PEDESTAL_H = 1.45 # column pedestal top; entrance platform sits on it
|
||||
COLUMN_D = 0.95 # Ionic shaft diameter at the base
|
||||
CAPITAL_H = 0.95
|
||||
ENTABLATURE_H = 2.20
|
||||
PARAPET_H = 1.60
|
||||
ENTABLATURE_H = 3.40 # band between the capitals and the motto panel
|
||||
PARAPET_H = 2.20 # motto panel and cornice above the entablature
|
||||
PORTAL_W = 3.10 # each of the three door openings
|
||||
PORTAL_H = 3.40
|
||||
STEP_TREAD = 0.34
|
||||
@@ -127,8 +131,8 @@ def build():
|
||||
for i in range(COLUMN_COUNT):
|
||||
x = -span / 2.0 + i * COLUMN_BAY
|
||||
col_xs.append(x)
|
||||
cylinder(f"Hero_Pedestal_{i + 1}", x, -0.55, PEDESTAL_H, PEDESTAL_H + 0.55,
|
||||
0.62, stone, vertices=16)
|
||||
cube(f"Hero_Pedestal_{i + 1}", x, -0.62, PEDESTAL_H + 0.27,
|
||||
1.24, 1.24, 0.54, stone)
|
||||
cylinder(f"Hero_Column_{i + 1}", x, -0.55, PEDESTAL_H + 0.55,
|
||||
PEDESTAL_H + 0.55 + (HEIGHT - ENTABLATURE_H - PARAPET_H - PEDESTAL_H - 0.55 - CAPITAL_H),
|
||||
COLUMN_D / 2.0, stone)
|
||||
@@ -140,6 +144,13 @@ def build():
|
||||
|
||||
# --- entablature and parapet ------------------------------------------
|
||||
ent_z0 = HEIGHT - ENTABLATURE_H - PARAPET_H
|
||||
# Lower entablature band (architrave) standing proud of the wall, so the
|
||||
# elevation reads as layered stone rather than one flat plane.
|
||||
cube("Hero_Architrave", 0.0, -1.55, ent_z0 + 0.42, FRONTAGE_W, 1.65, 0.84, stone)
|
||||
note("Hero_Architrave", (FRONTAGE_W, 1.65, 0.84), "assumption: stacked entablature bands")
|
||||
# Cornice under the parapet.
|
||||
cube("Hero_Cornice", 0.0, -1.6, HEIGHT - PARAPET_H - 0.18, FRONTAGE_W, 1.75, 0.36, stone)
|
||||
note("Hero_Cornice", (FRONTAGE_W, 1.75, 0.36), "assumption: projecting cornice line")
|
||||
cube("Hero_Entablature", 0.0, -0.75, ent_z0 + ENTABLATURE_H / 2.0,
|
||||
FRONTAGE_W, 1.5, ENTABLATURE_H, stone)
|
||||
note("Hero_Entablature", (FRONTAGE_W, 1.5, ENTABLATURE_H), "assumption: entablature depth")
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
# Audit the sibling Gig Line project for assets this project can reuse.
|
||||
#
|
||||
# python3 Tools/sibling_asset_audit.py # summary
|
||||
# python3 Tools/sibling_asset_audit.py --manifest # write Art/props/reuse-manifest.json
|
||||
#
|
||||
# The sibling project (…/06-games/security-game) is a Godot 4 security game by
|
||||
# the same author that researched this block first. Its street props are small,
|
||||
# generic and far cheaper to reuse than to remodel; its building meshes are not
|
||||
# reusable because they are Godot GLBs built to a different contract.
|
||||
#
|
||||
# What this tool does NOT do: copy anything, decide licence, or assume a prop
|
||||
# matches this project's proportions. It reports name, size, format and whether
|
||||
# a Blender source exists, so the copy list can be chosen deliberately.
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
SIBLING = "/run/media/system/DATA/Documents/06-games/security-game"
|
||||
PROPS_GLB = os.path.join(SIBLING, "assets/models/blender/props")
|
||||
SRC_BLEND = os.path.join(SIBLING, "assets/models/blender_src")
|
||||
OUT = "Art/props/reuse-manifest.json"
|
||||
|
||||
|
||||
def glb_stats(path):
|
||||
"""Triangle count and bounds from a GLB, without any dependency."""
|
||||
with open(path, "rb") as f:
|
||||
data = f.read()
|
||||
if data[:4] != b"glTF":
|
||||
return None
|
||||
json_len = struct.unpack("<I", data[12:16])[0]
|
||||
doc = json.loads(data[20 : 20 + json_len].decode("utf-8"))
|
||||
tris = 0
|
||||
for mesh in doc.get("meshes", []):
|
||||
for prim in mesh.get("primitives", []):
|
||||
idx = prim.get("indices")
|
||||
if idx is not None:
|
||||
tris += doc["accessors"][idx]["count"] // 3
|
||||
# bounds across all positions
|
||||
mins = [1e9] * 3
|
||||
maxs = [-1e9] * 3
|
||||
for mesh in doc.get("meshes", []):
|
||||
for prim in mesh.get("primitives", []):
|
||||
acc = prim.get("attributes", {}).get("POSITION")
|
||||
if acc is None:
|
||||
continue
|
||||
a = doc["accessors"][acc]
|
||||
if "min" in a and "max" in a:
|
||||
mins = [min(m, v) for m, v in zip(mins, a["min"])]
|
||||
maxs = [max(m, v) for m, v in zip(maxs, a["max"])]
|
||||
size = [round(maxs[i] - mins[i], 3) for i in range(3)] if mins[0] < 1e8 else None
|
||||
return {"triangles": tris, "size_gltf": size, "materials": len(doc.get("materials", []))}
|
||||
|
||||
|
||||
def main():
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--manifest", action="store_true")
|
||||
args = ap.parse_args()
|
||||
if not os.path.isdir(PROPS_GLB):
|
||||
sys.exit(f"missing {PROPS_GLB}")
|
||||
|
||||
rows = []
|
||||
for name in sorted(os.listdir(PROPS_GLB)):
|
||||
if not name.endswith(".glb"):
|
||||
continue
|
||||
stem = name[:-4]
|
||||
path = os.path.join(PROPS_GLB, name)
|
||||
stats = glb_stats(path) or {}
|
||||
source = os.path.join(SRC_BLEND, stem + ".blend")
|
||||
rows.append({
|
||||
"prop": stem,
|
||||
"glb": name,
|
||||
"bytes": os.path.getsize(path),
|
||||
"blend_source": os.path.basename(source) if os.path.exists(source) else None,
|
||||
"blend_bytes": os.path.getsize(source) if os.path.exists(source) else None,
|
||||
**stats,
|
||||
})
|
||||
|
||||
for r in rows:
|
||||
src = "blend" if r["blend_source"] else "glb-only"
|
||||
size = r.get("size_gltf")
|
||||
dims = "x".join(f"{v:.2f}" for v in size) if size else "?"
|
||||
print(f"{r['prop']:18} {r['triangles']:5} tris {dims:>18} glTF m "
|
||||
f"mats {r.get('materials', 0)} {src}")
|
||||
|
||||
print(f"\n{len(rows)} props, {sum(r['bytes'] for r in rows)//1024} KB of GLB, "
|
||||
f"{sum(r['triangles'] for r in rows)} triangles total")
|
||||
print("glTF is Y-up and Blender is Z-up: the exporter swaps Y/Z, so `size_gltf` "
|
||||
"lists X, height, depth — not X, Y, Z as authored.")
|
||||
|
||||
if args.manifest:
|
||||
os.makedirs(os.path.dirname(OUT), exist_ok=True)
|
||||
with open(OUT, "w") as f:
|
||||
json.dump({
|
||||
"source_project": SIBLING,
|
||||
"scanned": "assets/models/blender/props + assets/models/blender_src",
|
||||
"licence": "project-owned (same author); confirm before shipping",
|
||||
"note": "audit only — nothing has been copied",
|
||||
"props": rows,
|
||||
}, f, indent=2)
|
||||
print(f"wrote {OUT}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user