v0.4.5: tegelvloer met witte rand i.p.v. gras, Lucht geen/dag/nacht, Render met daglicht + lampen

- core/skybox.js: tegelvloer (tiles.jpg) passend om het object, rand 100x25 mm wit
- nacht-panorama; nacht = 15% omgevingslicht + lampen 100%
- Render-knop met camera-icoon: echte lampen in het gekozen licht
- gras verwijderd (bestanden lokaal bewaard, uit git)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Machiel
2026-09-30 12:34:19 +02:00
co-authored by Claude Opus 5.5
parent 9ed9cee2e0
commit 7ae76fe390
12 changed files with 172 additions and 122 deletions
+17 -19
View File
@@ -84,7 +84,7 @@ const HOUSE_OVERVIEW_TEMPLATE = `
<div id="ho-pane-3d" class="ho-pane">
<div class="pane-label">3D</div>
<div class="toolbar-3d" id="ho-toolbar-3d">
<button type="button" id="ho-btn-render" class="btn-3d-toggle" title="Avondscène: elke lamp en spot is een echte lichtbron"><i class="bi bi-moon-stars"></i>Render</button>
<button type="button" id="ho-btn-render" class="btn-3d-toggle" title="Render: elke lamp en spot is een echte lichtbron"><i class="bi bi-camera"></i>Render</button>
</div>
</div>
<div id="ho-specs"></div>
@@ -301,7 +301,7 @@ function mountHouseEditor(container, callbacks) {
let cameraFitted = CameraMemory.restore(overviewCamKey, camera, controls);
let beplatingVisible = true, isolatieVisible = true, lampenVisible = true;
let fullRender = false;
let skyOn = Skybox.isOn();
let skyMode = Skybox.getMode();
const skyEnv = Skybox.createEnvironment(scene);
// Weergave-filter (core/view-filter.js). Beplating = wandplaten, vloer-
@@ -319,30 +319,28 @@ function mountHouseEditor(container, callbacks) {
refresh({ keepProps: true });
});
// Volle render: avondscène, lampen en spots als echte lichtbronnen.
// Omgeving (core/skybox.js: geen/dag/nacht) en Render. Render = lampen en
// spots als echte lichtbronnen, in het licht van de gekozen omgeving;
// Nacht = omgevingslicht op 15% en de lampen altijd aan (100%). De
// tegelvloer ligt op het maaiveld, dus het ingegraven deel van vloer en
// sandwichpanelen verdwijnt eronder.
let lightsGroup = null;
// Lucht en gras (core/skybox.js): alleen in de gewone weergave (de volle
// render is een avondscène). Het gras ligt op het maaiveld, dus het
// ingegraven deel van vloer en sandwichpanelen verdwijnt eronder.
function applyRenderMode() {
const sky = skyOn && !fullRender;
scene.background = new THREE.Color(fullRender ? 0x0b0f18 : 0x1a1a1a);
Skybox.apply(sky, { env: skyEnv, controls, sun: dirLight, shadowRoot: houseGroup });
ambient.intensity = fullRender ? 0.1 : 0.6;
dirLight.intensity = fullRender ? 0.12 : 0.8;
ground.visible = fullRender;
grid.visible = !fullRender && !sky;
const lampsOn = fullRender || skyMode === 'night';
scene.background = new THREE.Color(0x1a1a1a);
Skybox.apply(skyMode, { env: skyEnv, controls, sun: dirLight, ambient, base: { ambient: 0.6, sun: 0.8 }, shadowRoot: houseGroup });
ground.visible = fullRender && skyMode === 'none'; // zonder omgeving: vlak waarop het lamplicht valt
grid.visible = skyMode === 'none' && !fullRender;
if (lightsGroup) { scene.remove(lightsGroup); lightsGroup = null; }
// De nep-lichtbundels (kegels) alleen in de snelle weergave; in de
// volle render schijnt er echt licht.
if (parts && parts.lightingGroup) parts.lightingGroup.traverse(o => { if (o.userData.beam) o.visible = !fullRender; });
if (fullRender && parts && lampenVisible) {
// De nep-lichtbundels (kegels) alleen zonder echte lampen.
if (parts && parts.lightingGroup) parts.lightingGroup.traverse(o => { if (o.userData.beam) o.visible = !lampsOn; });
if (lampsOn && parts && lampenVisible) {
const edge = dakVisible ? parts.roofEdge : null;
lightsGroup = LightingModel.buildLights3D(parts.lighting.lamps, edge ? edge.spots : [], edge ? edge.top - edge.fasciaHeight : 0);
scene.add(lightsGroup);
}
}
Skybox.createToggle(document.getElementById('ho-toolbar-3d'), (on) => { skyOn = on; applyRenderMode(); });
Skybox.createToggle(document.getElementById('ho-toolbar-3d'), (m) => { skyMode = m; applyRenderMode(); });
document.getElementById('ho-btn-render').addEventListener('click', (e) => {
fullRender = !fullRender;
e.currentTarget.classList.toggle('active', fullRender);
@@ -873,7 +871,7 @@ function mountHouseEditor(container, callbacks) {
grid.position.set(cx, 0, cz);
// Maaiveld: settings.groundLevel onder het loopvlak (bovenkant vloer).
const groundY = (Math.max(...parts.units.map(u => u.layout.floorTop)) - state.settings.groundLevel) * toM;
skyEnv.setPlacement(cx, groundY, cz);
skyEnv.fitTo(houseGroup, groundY);
ground.position.set(cx, groundY - 0.002, cz);
applyRenderMode();
if (!cameraFitted) {