diff --git a/.gitignore b/.gitignore
index 4bebd89..5cb53ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,5 +5,3 @@ examples/
# Lokale exports
*.pdf
.DS_Store
-# Oude grastextuur (niet meer gebruikt), lokaal bewaard
-assets/grass*.jpg
diff --git a/README.md b/README.md
index b08c2cf..a33215c 100644
--- a/README.md
+++ b/README.md
@@ -157,16 +157,22 @@ assets/ logo (preloader) + bestemmingsmap voor toekomstige
Koppeling, Dak). Labels: zelfstandig naamwoord, geen dubbele punt, uitleg
in een hint (i-icoon) i.p.v. tussen haakjes. Sneltoets T wisselt in drie
stappen: standaard -> 3D groot -> alleen de render -> standaard.
-- **Omgeving en render (v0.4.5).** Knop "Lucht" in elke 3D-werkbalk wisselt
- geen -> dag -> nacht (core/skybox.js, keuze onthouden). Het panorama
- (assets/skybox.webp / skybox-night.webp) wordt op de grond geprojecteerd
- (port van three.js GroundedSkybox); onder het object ligt een ronde
- tegelvloer (assets/tiles.jpg), groot genoeg voor het hele object, met een
+- **Omgeving en render (v0.4.6).** Keuzemenu in elke 3D-werkbalk: Ontwerp
+ (geen omgeving) / Dag / Nacht (core/skybox.js, keuze onthouden). Het
+ panorama (assets/skybox.webp / skybox-night.webp) wordt op de grond
+ geprojecteerd (port van three.js GroundedSkybox); onder het object ligt een
+ ronde tegelvloer (assets/tiles.jpg, 20% ruimer dan object + 1,5 m) met een
witte opstaande rand van 100 x 25 mm. Vloer en rand vangen licht en
schaduw. Woning: de tegelvloer ligt op het maaiveld (woning-instelling,
standaard 350 mm onder bovenkant vloer). Knop "Render" (camera): lampen en
spots als echte lichtbronnen in het gewone daglicht; Nacht: omgevingslicht
- 15%, lampen altijd aan (100%).
+ 15%, lampen altijd aan. Buitenlampen 15% minder fel dan in v0.4.5.
+- **Binnenspots (v0.4.6).** LightingModel.computeIndoor: per unit een raster
+ spots in het plafond (onderkant dak), min. 800 / max. 1500 mm h.o.h. in
+ beide richtingen, min. 600 mm van de binnenzijde van elke wand (of van de
+ unitrand bij een naad); spots te dicht bij een binnenwand vervallen.
+ Woning-instellingen › Verlichting › Binnenspots. In 3D (filter Lampen),
+ plattegrond (open cirkeltje), render en totalen.
- **Mijlpaal v0.4 — gevelopbouw.** Samenvatting van de v0.3.11–0.3.19-iteraties:
kruislat-latwerk op vochtdoek (richting gevelbekleding globaal), lampen op de
afgewerkte gevel (+52 mm), logo-watermerk op het doek, trasraam (cement-
diff --git a/css/app.css b/css/app.css
index cc40edb..a364ed8 100644
--- a/css/app.css
+++ b/css/app.css
@@ -638,3 +638,6 @@ h1 { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight:
.hn-title { display: flex; align-items: center; gap: 6px; }
.file-protocol-warning { position: fixed; left: 50%; bottom: 16px; transform: translateX(-50%); z-index: 9000; max-width: 640px; box-shadow: 0 8px 20px rgba(33,33,33,.2); }
.file-protocol-warning code { background: rgba(0,0,0,.06); padding: 0 4px; border-radius: 3px; }
+.vf-option { gap: 9px; }
+.vf-option.active { color: var(--primary-on-dark); font-weight: 600; }
+.vf-menu .vf-option:hover { color: var(--primary-on-dark); }
diff --git a/js/app.js b/js/app.js
index 84bb2b5..9486465 100644
--- a/js/app.js
+++ b/js/app.js
@@ -4,7 +4,7 @@
* Alle rechten voorbehouden. Gebruik uitsluitend met schriftelijke toestemming.
* Zie LICENTIE.md.
*/
-const APP_VERSION = '0.4.5';
+const APP_VERSION = '0.4.6';
// 0.0.X per kleine iteratie, 0.X.0 per mijlpaal, X.0.0 bij live-gang.
let tabs = [];
@@ -294,7 +294,7 @@ document.addEventListener('DOMContentLoaded', () => {
if (location.protocol === 'file:') {
const note = document.createElement('div');
note.className = 'ui-warn file-protocol-warning';
- note.innerHTML = 'Tectum is geopend als bestand. Start het via een webserver: ./start.sh of python3 -m http.server, en open http://localhost:8000. Lucht en gras werken anders niet.';
+ note.innerHTML = 'Tectum is geopend als bestand. Start het via een webserver: ./start.sh of python3 -m http.server, en open http://localhost:8000. De omgeving (Dag/Nacht) werkt anders niet.';
document.body.appendChild(note);
}
openNew('woning', 'L');
diff --git a/js/core/skybox.js b/js/core/skybox.js
index 0f0c42f..6998b1a 100644
--- a/js/core/skybox.js
+++ b/js/core/skybox.js
@@ -5,7 +5,7 @@
* Zie LICENTIE.md.
*/
// ============================================================
-// core/skybox.js — omgeving voor de 3D-weergaven ("Lucht": geen/dag/nacht).
+// core/skybox.js — omgeving voor de 3D-weergaven (Ontwerp / Dag / Nacht).
// Een panorama (assets/skybox.webp of skybox-night.webp) wordt op de grond
// geprojecteerd, zodat het object op de grond staat; onder het object ligt
// een ronde tegelvloer (assets/tiles.jpg) met een witte opstaande rand, groot
@@ -28,6 +28,7 @@ window.Skybox = (() => {
const RADIUS_M = 60; // straal van de omgevingsbol
const TILE_M = 2.4; // één tegeltextuur (1024 px) beslaat zoveel meter
const MARGIN_M = 1.5; // vrije rand tussen object en opstaande rand
+ const SIZE_FACTOR = 1.2; // tegelvloer 20% ruimer dan object + marge
const RIM_HEIGHT_M = 0.10, RIM_THICK_M = 0.025;
const NIGHT_FACTOR = 0.15; // omgevingslicht 's nachts
const SUN_OFFSET = { x: 8, y: 14, z: 6 };
@@ -130,7 +131,7 @@ window.Skybox = (() => {
if (box.isEmpty()) return;
const c = box.getCenter(new THREE.Vector3());
group.position.set(c.x, groundY, c.z);
- setTerrace(Math.hypot(box.max.x - box.min.x, box.max.z - box.min.z) / 2 + MARGIN_M);
+ setTerrace((Math.hypot(box.max.x - box.min.x, box.max.z - box.min.z) / 2 + MARGIN_M) * SIZE_FACTOR);
}
};
}
@@ -176,26 +177,39 @@ window.Skybox = (() => {
if (o.shadowRoot) o.shadowRoot.traverse(obj => { if (obj.isMesh) obj.castShadow = on; });
}
- // Knop in een 3D-werkbalk die door geen -> dag -> nacht wisselt.
- const LABELS = { none: ['cloud', 'Lucht'], day: ['sun', 'Dag'], night: ['moon-stars', 'Nacht'] };
+ // Keuzemenu in een 3D-werkbalk: Ontwerp (geen omgeving) / Dag / Nacht.
+ const LABELS = { none: ['pencil-square', 'Ontwerp'], day: ['sun', 'Dag'], night: ['moon-stars', 'Nacht'] };
function createToggle(toolbar, onChange) {
- const btn = document.createElement('button');
- btn.type = 'button';
- btn.title = 'Omgeving: geen / dag / nacht';
let m = getMode();
+ const wrap = document.createElement('div');
+ wrap.className = 'view-filter';
+ wrap.innerHTML = `
+