v0.6.0: ruimtes (verfemmer: functie, netto m², vloerafwerking, FIBO-wandpanelen, eigen verfkleur, vals plafond, ruimtestaat op de PDF), inrichting (sanitair, keuken, kookeiland, kasten, bed, zithoek, boiler; slepen met snappen op het wandvlak, draaien, kosten), kozijnen met deurrichting, glasdeur en schuifdeuren (inbouw/opbouw, deuren open in de loopmodus) plus dagkanten, gevel stucwerk en wandstukken splitsen met eigen gevel, dak over de hele woning met overkapping, geschilderd plafond, model Amstel als nieuw ontwerp, kosten en prijzen uit kosten/intern.csv en kosten/leveranciers.csv (CostCsv); easter egg verwijderd; overbodige comments opgeschoond (alleen copyright, uitzonderingen en valkuilen blijven)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b5510d56c7
commit
ceda0b554d
+10
-31
@@ -4,33 +4,20 @@
|
||||
* Alle rechten voorbehouden. Gebruik uitsluitend met schriftelijke toestemming.
|
||||
* Zie LICENTIE.md.
|
||||
*/
|
||||
// ============================================================
|
||||
// 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
|
||||
// genoeg voor het hele object. Vloer en rand reageren op het licht en vangen
|
||||
// de schaduw op. Nacht: omgevingslicht op NIGHT_FACTOR (lampen blijven 100%).
|
||||
//
|
||||
// Grondprojectie: port van three.js GroundedSkybox (r157+, MIT; wij draaien
|
||||
// r128): een binnenstebuiten bol waarvan de onderhelft plat gedrukt wordt op
|
||||
// een vloer op CAMERA_HEIGHT_M onder het midden van de bol.
|
||||
//
|
||||
// Vereist een webserver (texturen via TextureLoader). Plain script.
|
||||
// ============================================================
|
||||
// Grondprojectie: port van three.js GroundedSkybox (r157+, MIT); wij draaien r128.
|
||||
|
||||
window.Skybox = (() => {
|
||||
const PREF_KEY = 'tectum.sky';
|
||||
const MODES = ['none', 'day', 'night'];
|
||||
const SKY_URLS = { day: 'assets/skybox.webp', night: 'assets/skybox-night.webp' };
|
||||
const TILES_URL = 'assets/tiles.jpg';
|
||||
const CAMERA_HEIGHT_M = 1.7; // hoogte van de panoramacamera boven de grond
|
||||
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 CAMERA_HEIGHT_M = 1.7;
|
||||
const RADIUS_M = 60;
|
||||
const TILE_M = 2.4;
|
||||
const MARGIN_M = 1.5;
|
||||
const SIZE_FACTOR = 1.2;
|
||||
const RIM_HEIGHT_M = 0.10, RIM_THICK_M = 0.025;
|
||||
const NIGHT_FACTOR = 0.15; // omgevingslicht 's nachts
|
||||
const NIGHT_FACTOR = 0.15;
|
||||
const SUN_OFFSET = { x: 8, y: 14, z: 6 };
|
||||
|
||||
const cache = {};
|
||||
@@ -51,7 +38,6 @@ window.Skybox = (() => {
|
||||
for (let i = 0; i < pos.count; i++) {
|
||||
v.fromBufferAttribute(pos, i);
|
||||
if (v.y < 0) {
|
||||
// Onderhelft plat op y = -h; vloeiende overgang naar de bol.
|
||||
const f = v.y < y1 ? -h / v.y : (1 - v.y * v.y / (3 * y1 * y1));
|
||||
v.multiplyScalar(f);
|
||||
pos.setXYZ(i, v.x, v.y, v.z);
|
||||
@@ -59,12 +45,11 @@ window.Skybox = (() => {
|
||||
}
|
||||
pos.needsUpdate = true;
|
||||
const mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ map, depthWrite: false }));
|
||||
mesh.position.y = h - 0.01; // vlakke vloer net onder de tegelvloer
|
||||
mesh.position.y = h - 0.01;
|
||||
mesh.renderOrder = -1;
|
||||
return mesh;
|
||||
}
|
||||
|
||||
// Ronde tegelvloer (straal r) + witte opstaande rand erlangs.
|
||||
function buildTerrace(map, r) {
|
||||
const group = new THREE.Group();
|
||||
const tex = map.clone();
|
||||
@@ -86,13 +71,12 @@ window.Skybox = (() => {
|
||||
new THREE.ExtrudeGeometry(ring, { depth: RIM_HEIGHT_M, bevelEnabled: false, curveSegments: 128 }),
|
||||
new THREE.MeshStandardMaterial({ color: 0xffffff, roughness: 0.5 })
|
||||
);
|
||||
rim.rotation.x = -Math.PI / 2; // extrusie omhoog
|
||||
rim.rotation.x = -Math.PI / 2;
|
||||
rim.castShadow = rim.receiveShadow = true;
|
||||
group.add(rim);
|
||||
return group;
|
||||
}
|
||||
|
||||
// Omgeving voor één scene: { group, setMode(mode), fitTo(object3D, groundY) }.
|
||||
function createEnvironment(scene) {
|
||||
const group = new THREE.Group();
|
||||
group.visible = false;
|
||||
@@ -124,7 +108,6 @@ window.Skybox = (() => {
|
||||
return {
|
||||
group,
|
||||
setMode(m) { mode = m; group.visible = m !== 'none'; showSky(); },
|
||||
// Midden en straal uit de omhullende van het object (horizontaal), vloer op groundY (m).
|
||||
fitTo(object3D, groundY) {
|
||||
if (!object3D) return;
|
||||
const box = new THREE.Box3().setFromObject(object3D);
|
||||
@@ -144,14 +127,11 @@ window.Skybox = (() => {
|
||||
} catch (e) { return 'none'; }
|
||||
}
|
||||
function remember(m) {
|
||||
try { localStorage.setItem(PREF_KEY, m); } catch (e) { /* geen opslag: alleen deze sessie */ }
|
||||
try { localStorage.setItem(PREF_KEY, m); } catch (e) { }
|
||||
}
|
||||
|
||||
const lightFactor = (m) => m === 'night' ? NIGHT_FACTOR : 1;
|
||||
|
||||
// Omgeving toepassen: lucht/vloer, raster, camera niet onder de grond, zon
|
||||
// met schaduw, en het licht (nacht: NIGHT_FACTOR).
|
||||
// o: { env, grid, controls, sun, ambient, base: { ambient, sun }, shadowRoot }
|
||||
function apply(m, o) {
|
||||
const on = m !== 'none';
|
||||
o.env.setMode(m);
|
||||
@@ -177,7 +157,6 @@ window.Skybox = (() => {
|
||||
if (o.shadowRoot) o.shadowRoot.traverse(obj => { if (obj.isMesh) obj.castShadow = on; });
|
||||
}
|
||||
|
||||
// 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) {
|
||||
let m = getMode();
|
||||
|
||||
Reference in New Issue
Block a user