Phase 6.5 checkpoint again

This commit is contained in:
2026-10-26 12:58:02 +03:00
parent ec3f98f8a0
commit 88fd97fedd
11 changed files with 4116 additions and 12 deletions
@@ -148,8 +148,9 @@ current definition sets are loadable. At runtime `FurnitureLibrary`
discovers `furniture-*.json`, validates schema/identity/bounds and exposes
stable ids and aliases.
To add the phase 6.5 layer fixtures to the existing source (idempotent),
then export and render the preview gallery:
To add the phase 6.5 fixtures (layer fixes + the 6.5.I store/garage
set) to the existing source (idempotent), then export and render the
preview gallery:
```bash
../../blender-bin/bin/blender -b assets/blender/buildings/parts/furniture.blend \
@@ -165,6 +166,30 @@ and an atlas UV rectangle. `render_furniture_gallery.py` and
`generate_furniture_gallery_index.py` are the generators. The gallery
target is opt-in so routine builds do not render every asset.
### The fixture script (`add_furniture_fixtures.py`)
`add_furniture_fixtures.py` extends `furniture.blend` in place and is
safe to re-run (every root is created only when missing, duplicate
markers are never added again):
- Layer fixtures: `carpet1` (`thin-floor`), `switch1` and `picture1`
(`thin-wall`), `ceiling-light1` (`ceiling`) and `shop-shelf1`
(`normal`, with a simplified `collision-shelf-proxy`).
- Store/garage fixtures (6.5.I): `counter1` (shop/counter/essential,
`work` attachment marker for the demo's working-counter action),
`workbench1` (garage/working) and `bay1` (vehicle-sized repair bay,
`bay` marker plus visual stripes).
- `ensure_attachment(root)` gives every fixture root one root-local
`position-attach` marker (the guard matches the whole
`position-attach` prefix — Blender renames colliding objects with
numeric suffixes, so an exact-name check would re-create a second
marker whenever a renamed marker survives; the demo's
`demo_scene_furniture.json` POI test depends on one marker per root).
The phase 6.5.I demo scene and its headless check live in
`src/features/editScene/demos/demo-taxi/` (`demo_scene_furniture.json`,
`./demoTaxi --headless --test-furniture`).
## Choosing the authoring layer
| Need | Preferred home |
@@ -62,8 +62,15 @@ def box(root, name, location, dimensions, mat, collision=False):
def ensure_attachment(root):
"""A root-local marker used by the runtime layer-transform checks."""
if any(child.name == "position-attach" for child in root.children):
"""A root-local marker used by the runtime layer-transform checks.
The guard matches the whole 'position-attach' prefix: Blender
renames colliding objects with numeric suffixes, so an exact-name
check would re-create a second marker whenever a deduped or
renamed marker survives in the blend.
"""
if any(child.name.startswith("position-attach")
for child in root.children):
return
marker = bpy.data.objects.new("position-attach", None)
marker.empty_display_size = 0.05
@@ -128,5 +135,50 @@ if created:
(1.5, 0.4, 1.5), None, collision=True)
root["collision_mesh"] = collision.name
root, created = make_root("furniture-counter1", "shop, counter, essential",
"normal", True, False)
if created:
box(root, "CounterTop", (0, 0, 0.95), (1.8, 0.6, 0.05), wood)
for z in (-0.3, 0.3):
box(root, "CounterLeg", (z, 0, 0.47), (0.06, 0.65, 0.95), wood)
collision = box(root, "collision-counter", (0, 0, 0.5),
(1.8, 0.6, 1.0), None, collision=True)
root["collision_mesh"] = collision.name
ensure_attachment(root)
work_mark = bpy.data.objects.new("position-work", None)
work_mark.empty_display_size = 0.05
bpy.context.scene.collection.objects.link(work_mark)
work_mark.parent = root
work_mark.location = (0, -0.4, 1.0)
work_mark["name"] = "work"
work_mark["type"] = "attachment"
root, created = make_root("furniture-workbench1",
"garage, working, optional",
"normal", True, False)
if created:
box(root, "BenchTop", (0, 0, 0.9), (4.2, 0.8, 0.06), wood)
for x in (-1.9, 0.0, 1.9):
box(root, "BenchLeg", (x, 0, 0.44), (0.08, 0.7, 0.9), wood)
box(root, "BenchVise", (1.4, 0, 0.78), (0.25, 0.3, 0.25), trim)
collision = box(root, "collision-workbench", (0, 0, 0.5),
(4.2, 0.8, 1.0), None, collision=True)
root["collision_mesh"] = collision.name
root, created = make_root("furniture-bay1",
"garage, bay, optional",
"thin-floor", True, False)
if created:
box(root, "BayPad", (0, 0, 0.01), (5.2, 2.2, 0.02), accent)
box(root, "BayStripe", (0, 0, 0.011), (4.7, 1.6, 0.004), picture)
ensure_attachment(root)
bay_mark = bpy.data.objects.new("position-bay", None)
bay_mark.empty_display_size = 0.05
bpy.context.scene.collection.objects.link(bay_mark)
bay_mark.parent = root
bay_mark.location = (0, 0, 0.02)
bay_mark["name"] = "bay"
bay_mark["type"] = "attachment"
bpy.ops.wm.save_as_mainfile(filepath=bpy.data.filepath)
print("Phase 6.5 furniture fixtures present.")
Binary file not shown.