From 7299df6f1eed9d1ec85702a19e9287921544ee91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20P?= Date: Fri, 17 Oct 2025 16:13:49 +0200 Subject: [PATCH] UI and config changes + tentative light probe switch --- assets/hemi-grey.jpg | Bin 0 -> 2348 bytes config.js | 6 +- js/scene.js | 128 +++++++++++++++++++++++-------------------- js/state.js | 1 + 4 files changed, 76 insertions(+), 59 deletions(-) create mode 100644 assets/hemi-grey.jpg diff --git a/assets/hemi-grey.jpg b/assets/hemi-grey.jpg new file mode 100644 index 0000000000000000000000000000000000000000..69f1a232b6950cb1be281cfc95818be3641ed2b4 GIT binary patch literal 2348 zcmcgs&u`mQ9Dj~eCri^VURJ5Bm1aDI*hJzVOPa-M$e5FgAO*ToC^vBI*VStM1KTBO zC0Gv}IH3x0>U|*Kf;e#DKsE6nOp^w?usZ^zZ9)Pe^X$aQ%jT8|Bwn7K&-eHD`@Y|2 z|BinT%r<-aIsmQK1&{`#<^K%m#_q_ld*t;E&$A_tGu@)1SshqZEraVR zHYXH$4lLGtwxVuAkLkc`x>;j?{q{SS(X|@8R&MicTZS9@OS=wyZTFQ`b$3&(YHa-l zX0a#r4BLR7!t{(S)0KKPHgql_9I!c-301t!8v9}pm3gzh%*d7lnR2mQP|kz^Nh#~C5{(3;bK9kN~My-^UPqeD4L_KODm0~K`cbo*g;X6Xa^9+i%@?bTS6X}<)+ZnuYyV^7O4g1SO& z*IR+3G-9>g)g2phE6}yJ9Tg(=bCEGRyW;}|iYOcDRYylnQMMYEx@|zyYc*;tk`y&v zlQhV81SnJrkXP3WRlc-PP}DLkKm{>NP+aebO5`Wbz9~1G)hgd;2(lmu%_~=UaY3$# z3w)_`X{o#9@xsq+Dftm70+^3Eo&>9g5?d%v)m2KW@I_+I`iC` zZfaK7Js-5GUv&dI`nynDax8-h&soxAa(J@(`}W$uJwFa5#RbEH4Nt^E6B)qaRY1h> zGC>pFAO~F){}=FVcmaTRh^{0-f|(>qWu^e2K0?pe0Hl`zIB~(h3qAl;GMSu6QWF!@ z2?{-vX^KiuW;2<|OeUMlhAWqyKAAf?oz3S@pU&s!=jP_-&kh%nN~NZ)b>w3 z#>s~P667cb{m#|5_xWYp{}E(K0wqJz==dI99%+E5Fih-W#4Lu77Vwx>9>ZhF%`=$f z(ji8;7zQ6=1pY||dzfI_#)z}1urxYCVj}Syb)bJ5yYCv`#O_$-1O3M9|82c-gx}A? zToXaAKczxUVmOhY>IqQq^D#^iBR)YA^{4;HeDVLT&tG2oI?6+g=d`g?D!-G2Dbuip { + const aoCurrentState = AppState.ambientOcclusion; + if (!AppState.clipping.enabled) { + AppState.clipping.enabled = true; + trigger.className += ' border border-2 border-white'; + Scene.toggleAmbientOcclusion(false); + //Scene.activateClipper() + } else { + AppState.clipping.enabled = false; + ATON.disableClipPlanes(); + AppState.root.remove(AppState.clipping.helper); + AppState.clipping.helper = null; + let noBorder = trigger.className.replace(/ border.*$/g, ''); + trigger.className = noBorder; + Scene.toggleAmbientOcclusion(aoCurrentState); + } + } + ); +} + /** * @todo Experimental... * @param {THREE.Object3D} object - A THREE Object3D instance @@ -39,18 +67,20 @@ Scene.showEdges = function(object) { * Activate clipping plane */ Scene.activateClipper = function() { - const geometry = new THREE.PlaneGeometry( 24, 24 ); - const material = new THREE.MeshPhongMaterial({ - color: 0xffffee, - opacity: 0.5, - transparent: true, - }); - const plane = new THREE.Mesh( geometry, material ); - const root = AppState.root; - console.log(root, plane); - root.add(plane); - AppState.clipping.enabled = true; - AppState.clipping.plane = plane; + const point = ATON.getSceneQueriedPoint(); + if (point) { + // First remove any existing clipping planes + ATON.disableClipPlanes(); + // Normal of the clipping plane along the Y axis facing down + const plane = ATON.addClipPlane(new THREE.Vector3(0, -1, 0), point); + // Add a visible plane helper for the clipping plane + const helper = new THREE.PlaneHelper(plane, 24, 0xffff00); + // Remove any already visbile helper plane + if (AppState.clipping.helper !== null) AppState.root.remove(AppState.clipping.helper); + AppState.root.add(helper); + AppState.clipping.helper = helper; + console.log("I'm clipping, baby!"); + } } /** @@ -155,11 +185,21 @@ Scene.toggleSettingsPanel = function(triggerId) { `; + const lightProbeSwitch = document.createElement('div'); + lightProbeSwitch.className = 'form-check form-switch ms-4 mt-2'; + lightProbeSwitch.innerHTML = ` + + + `; + shadowsSwitch.querySelector('input[type="checkbox"').checked = AppState.shadows; ambientOcclSwitch.querySelector('input[type="checkbox"').checked = AppState.ambientOcclusion; + lightProbeSwitch.querySelector('input[type="checkbox"').checked = AppState.lightProbe; ATON.UI.elSidePanel.appendChild(ambientOcclSwitch); ATON.UI.elSidePanel.appendChild(shadowsSwitch); + ATON.UI.elSidePanel.appendChild(lightProbeSwitch); + // TODO: move somewhere else... document.querySelector('#aoSwitch').addEventListener( 'change', @@ -176,35 +216,19 @@ Scene.toggleSettingsPanel = function(triggerId) { AppState.shadows = checked; } ); - }); -} - -/** - * @todo Get clipping button from state? Review logic!! - * @param {String} triggerSelector - */ -Scene.UI.toggleClipper = function(triggerSelector) { - const trigger = document.querySelector(triggerSelector); - trigger.addEventListener( - 'click', - () => { - const aoCurrentState = AppState.ambientOcclusion; - if (!AppState.clipping.enabled) { - AppState.clipping.enabled = true; - trigger.className += ' border border-2 border-white'; - Scene.toggleAmbientOcclusion(false); - //Scene.activateClipper() - } else { - AppState.clipping.enabled = false; - ATON.disableClipPlanes(); - AppState.root.remove(AppState.clipping.helper); - AppState.clipping.helper = null; - let noBorder = trigger.className.replace(/ border.*$/g, ''); - trigger.className = noBorder; - Scene.toggleAmbientOcclusion(aoCurrentState); + // Not working properly? + document.querySelector('#lpSwitch').addEventListener( + 'change', + event => { + const checked = event.target.checked; + ATON.setAutoLP(checked); + //if (!checked) ATON.clearLightProbes(); + AppState.lightProbe = checked; + if (checked) ATON.updateLightProbes(); + console.log('Light probe: ', checked); } - } - ); + ); + }); } Scene.init = function() { @@ -214,32 +238,19 @@ Scene.init = function() { ATON.UI.init(); // All assets for this app are stored here ATON.setPathCollection('./assets/'); - // Light direction should be dynamic / user-defined + // Initial light direction ATON.setMainLightDirection(new THREE.Vector3(0.2,-0.3,-0.7)); - ATON.toggleShadows(true); - ATON.setExposure(0.8); + ATON.setExposure(config.scene.initialExposure); // Open settings side panel when clicking on settings btn Scene.toggleSettingsPanel('settings'); Scene.toggleContentMenu('menu'); + // TODO: move to dedicated function!! window.addEventListener('mousedown', event => { // Activate clipping when left-clicking on the scene if (AppState.clipping.enabled && event.buttons === 1) { - const point = ATON.getSceneQueriedPoint(); - if (point) { - // First remove any existing clipping planes - ATON.disableClipPlanes(); - // Normal of the clipping plane along the Y axis facing down - const plane = ATON.addClipPlane(new THREE.Vector3(0, -1, 0), point); - // Add a visible plane helper for the clipping plane - const helper = new THREE.PlaneHelper(plane, 24, 0xffff00); - // Remove any already visbile helper plane - if (AppState.clipping.helper !== null) AppState.root.remove(AppState.clipping.helper); - AppState.root.add(helper); - AppState.clipping.helper = helper; - console.log("I'm clipping, baby!"); - } + this.activateClipper(); } }); } @@ -285,7 +296,8 @@ Scene.openScene = function(marker) { mainNode.attachToRoot(); - ATON.setAutoLP(true); + ATON.setAutoLP(config.scene.autoLP); + AppState.lightProbe = config.scene.autoLP; Scene.toggleAmbientOcclusion(true); AppState.ambientOcclusion = true; diff --git a/js/state.js b/js/state.js index 549f16f..1ad882c 100644 --- a/js/state.js +++ b/js/state.js @@ -9,6 +9,7 @@ export const AppState = { ], ambientOcclusion : true, shadows : true, + lightProbe : false, map : null, clipping : { enabled: false,