Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ still: DIRTY through-hole + loose-vert bead vs CLEAN manifold (same brass).
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/prop-origin-transform/"><img src="examples/prop-origin-transform/preview.webp" alt="Prop origin transform: dual-panel TRAP vs MPI KEEP street pedestals with margins all around — left bare-parent conduit accessory teleports off its dark mount well, right accessory stays seated, origin axes crossing on the floor under each base — proving scale apply, base origin, and matrix_parent_inverse" /></a>
<a href="examples/prop-origin-transform/"><img src="examples/prop-origin-transform/preview.webp" alt="Prop origin transform: two green street utility pedestals, each centred in a floor pivot ring — left, the orange conduit elbow parented with matrix_parent_inverse stays bolted to its mount; right, bare child.parent = parent throws the elbow into the air beyond the slab while a glowing cyan outline marks its empty seat — proving scale apply, base origin, and matrix_parent_inverse" /></a>
</td>
<td valign="middle">

Expand All @@ -1019,7 +1019,7 @@ still: DIRTY through-hole + loose-vert bead vs CLEAN manifold (same brass).
The origin / scale-apply / MPI contract a prop pipeline relies on before
engine ingest: data-API scale bake to exactly `(1,1,1)`, local bbox
`min.z == 0` (origin at base), world AABB unchanged across the bake, and
`matrix_parent_inverse` so a flanged conduit stays on its mount socket.
`matrix_parent_inverse` so a flanged conduit elbow stays on its mount.
Extends [`parent-inverse-orrery`](examples/parent-inverse-orrery/) without
retreading orbits. Dual-panel still: TRAP (bare parent — empty socket +
teleported flange) vs MPI KEEP.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/assets/prop-origin-transform-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/gallery/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -750,11 +750,11 @@ <h2><a href="mesh-hygiene-audit/">mesh-hygiene-audit</a></h2>
</article>
<article class="card" data-tags="transforms parenting game-pipeline">
<a class="card-media" href="prop-origin-transform/" tabindex="-1" aria-hidden="true">
<img src="assets/prop-origin-transform-hero.webp" alt="Two teal pedestals labelled TRAP and MPI KEEP, origin axes crossing on the floor under each base: on the left a conduit fitting has jumped out of its socket, on the right it sits seated." loading="lazy" decoding="async" />
<img src="assets/prop-origin-transform-hero.webp" alt="Two green street utility pedestals in floor pivot rings: the left one keeps its orange conduit elbow bolted on, the right one&#x27;s elbow hangs in the air beside a glowing cyan outline of its seat." loading="lazy" decoding="async" />
</a>
<div class="card-body">
<h2><a href="prop-origin-transform/">prop-origin-transform</a></h2>
<p class="teaches">Street pedestal origin-to-base-center + data-API scale apply + matrix_parent_inverse for a flanged conduit accessory. After bake: scale (1,1,1), local min.z==0, world AABB unchanged. Bare parent jumps the accessory off an empty mount socket; MPI keeps it seated.</p>
<p class="teaches">Street pedestal origin-to-base-center + data-API scale apply + matrix_parent_inverse for a flanged conduit elbow. After bake: scale (1,1,1), local min.z==0, world AABB unchanged. Bare parent throws the elbow off its mount; MPI keeps it seated.</p>
<p class="witnesses"><span class="tag">witnesses</span> Bare child.parent = parent teleports accessories off their mounts; skipping view_layer.update() before matrix_world, or leaving non-uniform scale / centered origin, breaks engine ingest placement.</p>
<a class="card-link" href="prop-origin-transform/">View example<span class="sr-only"> prop-origin-transform</span> <span aria-hidden="true">&rarr;</span></a>
</div>
Expand Down
700 changes: 423 additions & 277 deletions docs/gallery/prop-origin-transform/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions examples/gallery.json
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,8 @@
{
"name": "prop-origin-transform",
"dir": "examples/prop-origin-transform",
"teaches": "Street pedestal origin-to-base-center + data-API scale apply + matrix_parent_inverse for a flanged conduit accessory. After bake: scale (1,1,1), local min.z==0, world AABB unchanged. Bare parent jumps the accessory off an empty mount socket; MPI keeps it seated.",
"alt": "Two teal pedestals labelled TRAP and MPI KEEP, origin axes crossing on the floor under each base: on the left a conduit fitting has jumped out of its socket, on the right it sits seated.",
"teaches": "Street pedestal origin-to-base-center + data-API scale apply + matrix_parent_inverse for a flanged conduit elbow. After bake: scale (1,1,1), local min.z==0, world AABB unchanged. Bare parent throws the elbow off its mount; MPI keeps it seated.",
"alt": "Two green street utility pedestals in floor pivot rings: the left one keeps its orange conduit elbow bolted on, the right one's elbow hangs in the air beside a glowing cyan outline of its seat.",
"witnessesFix": "Bare child.parent = parent teleports accessories off their mounts; skipping view_layer.update() before matrix_world, or leaving non-uniform scale / centered origin, breaks engine ingest placement.",
"hero": "docs/gallery/assets/prop-origin-transform-hero.webp",
"preview": "examples/prop-origin-transform/preview.webp",
Expand Down
46 changes: 30 additions & 16 deletions examples/prop-origin-transform/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Prop Origin Transform

A runnable example that builds a street utility pedestal with a bolted
conduit accessory and proves the **origin / scale-apply / MPI** contract a
A runnable example that builds a street utility pedestal with a flanged
conduit elbow and proves the **origin / scale-apply / MPI** contract a
prop pipeline relies on before engine ingest — following
[`operators`](../../skills/operators/SKILL.md) and the data-API parenting
idiom from [`parent-inverse-orrery`](../parent-inverse-orrery/).
Expand All @@ -27,24 +27,37 @@ engine exporter — it proves the transform properties such an asset must have.
- **Origin at base center.** Local bbox `min.z == 0`, XY centered; world AABB
delta across the bake is **0** (gate `1e-5`).
- **Bare-parent trap.** Parenting the accessory without MPI jumps it
(~0.43 m measured); setting `matrix_parent_inverse` restores world location
(err ~3e-8).
(0.298 m measured); setting `matrix_parent_inverse` restores world
location (err 0).

**What each check catches on failure:** skipping scale apply leaves
non-identity scale; skipping origin bake leaves `min.z ≈ -0.756`; skipping
MPI leaves the accessory teleported.
`(1.15, 0.92, 1.08)` (exit 5); skipping the origin bake leaves
`min.z = -0.58` (exit 6); skipping MPI leaves the accessory 0.298 m off
(exit 8).

**Version witness:** byte-identical numbers on Blender 4.5.11 LTS and 5.1.2.
**Version witness:** identical numbers on Blender 5.2.1 LTS, 5.1.2 and
4.5.11 LTS.

The render is a dual panel: left **TRAP** (bare parent — flanged conduit
teleports off a deep shadowed mount socket) vs right **MPI KEEP** (same metal
fitting seated in the socket), with emissive origin markers at each pedestal's
base. The origin is inside the plinth, so the red X and green Y stubs are
centred on it and run 1.7 m along the floor, exiting the plinth on both
sides: where they cross, under the base, is the origin. The first cut drew
0.28 m stubs from the origin outward, all buried, and 0.11 m labels that
vanished at card size; the labels are 0.21 m now. Accessory and pedestal stay in one material family so displacement — not
color — carries the proof. Check closed forms are unchanged.
**The asset.** The pedestal is one mesh with five materials: a precast concrete footing,
a galvanised base plate with anchor nuts, a green cabinet on a black kick
skirt, a hipped lid, a door with hinges, a T-handle and a hazard plate, louvred
side vents, a conduit boss on the +X face and a sleeve in the pad. It is
authored the way an import often arrives: origin at the geometric centre and
coordinates divided by a non-uniform object scale. The bake lands it on
exactly the designed shape. The accessory is a flanged PVC conduit elbow
with bolt heads, a strap clamp and a coupling that drops into the sleeve.

**The render.** Two baked pedestals stand on a sidewalk slab. On the left the elbow is
parented with MPI and stays bolted to its boss, seated in the sleeve. On the
right, bare `child.parent = parent` applies the pedestal's transform a
second time. The elbow is thrown 0.65 m, past the slab edge and into the
air, and a glowing cyan outline (a Wireframe modifier on a copy)
marks the seat it left. The slab raises both origins 0.20 m, so the doubled
translation lifts the elbow instead of sliding it along the floor. A
pivot ring on the floor is centred on each pedestal's origin, with red
notches on its X axis and green notches on Y. The origin is under the base,
so the ring frames it. There are no text labels: the ghost and the stranded
elbow carry the proof. The check's closed forms are unchanged.

## Run

Expand Down Expand Up @@ -73,6 +86,7 @@ against it. `10` is the shared framing helper.
| 8 | MPI did not restore world location (`--skip-mpi` lands here) |
| 9 | `--output` produced no file |
| 10 | Gallery framing violation |
| 11 | Gallery asset-quality violation (render path only) |

The `blender-smoke` workflow runs the check on Blender 5.2 LTS and 4.5 LTS
(5.1 on the weekly cron, the `needs-5.1` PR label, or manual dispatch).
Expand Down
Binary file modified examples/prop-origin-transform/preview.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading