feat: cylinder occluders (shape/radiusCm/heightCm) for round props like the test rig post

This commit is contained in:
2026-08-24 10:39:51 +10:00
parent 4753162ea1
commit ef3c13d8c8
+14 -2
View File
@@ -390,9 +390,21 @@ function buildOcclusion(scene) {
occlusionGroup.clear(); occlusionGroup.clear();
const mat = new THREE.MeshBasicMaterial({ colorWrite: false }); // depth-only const mat = new THREE.MeshBasicMaterial({ colorWrite: false }); // depth-only
for (const b of scene.buildings || []) { for (const b of scene.buildings || []) {
const geo = new THREE.BoxGeometry(b.size[0], b.size[1], b.size[2]); /* Two occluder shapes. Boxes cover LEGO buildings; cylinders exist for round
* props (the test rig's 85mm post), where a box silhouette would wrongly
* hide ghosts at the corners. Positions are floor-level, so each mesh is
* lifted by half its height. */
let geo, height;
if (b.shape === 'cylinder') {
const r = b.radiusCm ?? (b.size ? b.size[0] / 2 : 5);
height = b.heightCm ?? (b.size ? b.size[1] : 10);
geo = new THREE.CylinderGeometry(r, r, height, 24);
} else {
height = b.size[1];
geo = new THREE.BoxGeometry(b.size[0], b.size[1], b.size[2]);
}
const mesh = new THREE.Mesh(geo, mat); const mesh = new THREE.Mesh(geo, mat);
mesh.position.set(b.position[0], b.position[1] + b.size[1] / 2, b.position[2]); mesh.position.set(b.position[0], b.position[1] + height / 2, b.position[2]);
mesh.rotation.y = THREE.MathUtils.degToRad(b.yawDeg || 0); mesh.rotation.y = THREE.MathUtils.degToRad(b.yawDeg || 0);
mesh.renderOrder = -1; mesh.renderOrder = -1;
occlusionGroup.add(mesh); occlusionGroup.add(mesh);