fix(virtual): cyclorama extent for east/west coves + never frustum-cull the cove
east/west coves run only the cyclorama section (extent from the north wall) instead of the full L-shaped depth; big static swept surface gets frustumCulled=false. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
d0c91faf79
commit
d46025e887
@ -126,7 +126,7 @@ function slopedSide(x, ch, cd, hf, th, m) {
|
||||
// Cyclorama / infinity cove — the floor curves up into the named wall(s) via a fillet of radius R,
|
||||
// with a white floor lead-in, so there's no hard floor↔wall seam (the seamless studio look). Each
|
||||
// wall gets one swept profile: [wall down to R] → [quarter-circle fillet] → [flat floor lead-in].
|
||||
function buildCyclorama(walls, R, lead, W, D, H, mat) {
|
||||
function buildCyclorama(walls, R, lead, W, D, H, mat, extent) {
|
||||
const prof = [];
|
||||
for (let i = 0; i <= 6; i++) prof.push([0, H - (H - R) * i / 6]); // wall: u=0, v H→R
|
||||
for (let i = 1; i <= 12; i++) { const t = Math.PI + (Math.PI / 2) * i / 12; prof.push([R + R * Math.cos(t), R + R * Math.sin(t)]); } // fillet R→0
|
||||
@ -141,14 +141,18 @@ function buildCyclorama(walls, R, lead, W, D, H, mat) {
|
||||
};
|
||||
walls.forEach(wall => {
|
||||
const mp = maps[wall]; if (!mp) return;
|
||||
// east/west coves only run the cyclorama section (extent from the north wall), not the full L-shaped depth
|
||||
let s0 = -mp.len / 2, s1 = mp.len / 2;
|
||||
if ((wall === 'east' || wall === 'west') && extent > 0) { s0 = -D / 2; s1 = -D / 2 + extent; }
|
||||
const pos = [];
|
||||
[-mp.len / 2, mp.len / 2].forEach(s => prof.forEach(([u, v]) => { const p = mp.f(s, u, v); pos.push(p[0], p[1], p[2]); }));
|
||||
[s0, s1].forEach(s => prof.forEach(([u, v]) => { const p = mp.f(s, u, v); pos.push(p[0], p[1], p[2]); }));
|
||||
const idx = [];
|
||||
for (let p = 0; p < P - 1; p++) idx.push(p, P + p, p + 1, p + 1, P + p, P + p + 1);
|
||||
const geo = new THREE.BufferGeometry();
|
||||
geo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(pos), 3));
|
||||
geo.setIndex(idx); geo.computeVertexNormals();
|
||||
grp.add(new THREE.Mesh(geo, mat));
|
||||
geo.setIndex(idx); geo.computeVertexNormals(); geo.computeBoundingSphere();
|
||||
const me = new THREE.Mesh(geo, mat); me.frustumCulled = false; // big static surface — never cull it
|
||||
grp.add(me);
|
||||
});
|
||||
return grp;
|
||||
}
|
||||
@ -255,7 +259,7 @@ function buildScene(data) {
|
||||
const R = num(sp.cyclorama_radius, 0.9);
|
||||
const cmat = material(sp.cyclorama_color || '#ffffff', '#ffffff');
|
||||
cmat.side = THREE.DoubleSide; cmat.roughness = 0.92; cmat.metalness = 0;
|
||||
roomGroup.add(buildCyclorama(cyc, R, Math.max(R + 0.3, 1.2), W, D, H, cmat));
|
||||
roomGroup.add(buildCyclorama(cyc, R, Math.max(R + 0.3, 1.2), W, D, H, cmat, num(sp.cyclorama_extent, 0)));
|
||||
}
|
||||
|
||||
// lights (data-driven + a soft ambient so it's never pitch black)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user