diff --git a/examples/3dtiles_25d.html b/examples/3dtiles_25d.html index 16fb4cfacd..41cc65ad15 100644 --- a/examples/3dtiles_25d.html +++ b/examples/3dtiles_25d.html @@ -114,7 +114,7 @@ var menu = new GuiTools('menuDiv', view); var d = new debug.Debug(view, menu.gui); debug.createTileDebugUI(menu.gui, view, view.tileLayer, d); - debug.create3dTilesDebugUI(menu.gui, view, $3dTilesLayer, d); + debug.create3dTilesDebugUI(menu.gui, view, $3dTilesLayer); diff --git a/examples/3dtiles_basic.html b/examples/3dtiles_basic.html index 3dff817953..9db050b8a3 100644 --- a/examples/3dtiles_basic.html +++ b/examples/3dtiles_basic.html @@ -81,8 +81,8 @@ // Add the UI Debug var d = new debug.Debug(view, menuGlobe.gui); debug.createTileDebugUI(menuGlobe.gui, view, view.tileLayer, d); - debug.create3dTilesDebugUI(menuGlobe.gui, view, $3dTilesLayerDiscreteLOD, d); - debug.create3dTilesDebugUI(menuGlobe.gui, view, $3dTilesLayerRequestVolume, d); + debug.create3dTilesDebugUI(menuGlobe.gui, view, $3dTilesLayerDiscreteLOD); + debug.create3dTilesDebugUI(menuGlobe.gui, view, $3dTilesLayerRequestVolume); d.zoom = function() { view.camera3D.position.set(1215013.9, -4736315.5, 4081597.5); view.camera3D.quaternion.set(0.9108514448729665, 0.13456816437801225, 0.1107206134840362, 0.3741416847378546); diff --git a/examples/3dtiles_batch_table.html b/examples/3dtiles_batch_table.html index 4e074f8cd3..4471f98eb4 100644 --- a/examples/3dtiles_batch_table.html +++ b/examples/3dtiles_batch_table.html @@ -80,9 +80,7 @@ // Add a debug UI var d = new debug.Debug(view, menuGlobe.gui); debug.createTileDebugUI(menuGlobe.gui, view, view.tileLayer, d); - debug.create3dTilesDebugUI(menuGlobe.gui, view, - $3dTilesLayerBTHierarchy, - d); + debug.create3dTilesDebugUI(menuGlobe.gui, view, $3dTilesLayerBTHierarchy); diff --git a/examples/3dtiles_pointcloud.html b/examples/3dtiles_pointcloud.html index 2441b08ad9..25300f0727 100644 --- a/examples/3dtiles_pointcloud.html +++ b/examples/3dtiles_pointcloud.html @@ -58,14 +58,15 @@ } // Create a new Layer 3d-tiles For Pointcloud // ------------------------------------------- + var $3dTilesSource = new itowns.C3DTilesSource({ + url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/pnts-sete-2021-0756_6256/tileset.json', + }); var $3dTilesLayerSetePC = new itowns.C3DTilesLayer('3d-tiles-sete', { name: 'SetePC', sseThreshold: 5, pntsMode: itowns.PNTS_MODE.CLASSIFICATION, pntsShape : itowns.PNTS_SHAPE.CIRCLE, - source: new itowns.C3DTilesSource({ - url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/pnts-sete-2021-0756_6256/tileset.json', - }), + source: $3dTilesSource, }, view); $3dTilesLayerSetePC.addEventListener( @@ -84,18 +85,11 @@ // Add the UI Debug var d = new debug.Debug(view, menuGlobe.gui); - debug.createTileDebugUI(menuGlobe.gui, view, view.tileLayer, d); - debug.create3dTilesDebugUI(menuGlobe.gui, view, $3dTilesLayerSetePC, d); - - d.switch = function() { - switchMode(); - } - menuGlobe.gui.add(d, 'switch').name('Mode Switch'); - - - - - + $3dTilesLayerSetePC.whenReady + .then(() => { + debug.createTileDebugUI(menuGlobe.gui, view, view.tileLayer, d); + debug.create3dTilesDebugUI(menuGlobe.gui, view, $3dTilesLayerSetePC); + }); diff --git a/examples/copc_simple_loader.html b/examples/copc_simple_loader.html index da58880913..adc29f35a6 100644 --- a/examples/copc_simple_loader.html +++ b/examples/copc_simple_loader.html @@ -109,7 +109,7 @@ pointBudget: 3000000, }); view.addLayer(layer).then(onLayerReady); - debug.PotreeDebug.initTools(view, layer, gui); + debug.PointCloudDebug.initTools(view, layer, gui); } function loadAutzen() { diff --git a/examples/entwine_3d_loader.html b/examples/entwine_3d_loader.html index 1b9f303a41..bc75139d36 100644 --- a/examples/entwine_3d_loader.html +++ b/examples/entwine_3d_loader.html @@ -98,7 +98,7 @@ itowns.View.prototype.addLayer.call(view, eptLayer).then(onLayerReady); - debug.PotreeDebug.initTools(view, eptLayer, debugGui); + debug.PointCloudDebug.initTools(view, eptLayer, debugGui); } readEPTURL(); diff --git a/examples/entwine_simple_loader.html b/examples/entwine_simple_loader.html index 5d4dd1fab6..15e436e5e2 100644 --- a/examples/entwine_simple_loader.html +++ b/examples/entwine_simple_loader.html @@ -104,7 +104,7 @@ view.addLayer(eptLayer).then(onLayerReady); eptLayer.whenReady - .then(() => debug.PotreeDebug.initTools(view, eptLayer, debugGui)); + .then(() => debug.PointCloudDebug.initTools(view, eptLayer, debugGui)); function dblClickHandler(event) { var pick = view.pickObjectsAt(event, 5, eptLayer); diff --git a/examples/potree_25d_map.html b/examples/potree_25d_map.html index 1be0029a7e..74efbfc34e 100644 --- a/examples/potree_25d_map.html +++ b/examples/potree_25d_map.html @@ -102,7 +102,7 @@ potreeLayer.root.bbox.getSize(size); potreeLayer.root.bbox.getCenter(lookAt); - debug.PotreeDebug.initTools(view, potreeLayer, debugGui); + debug.PointCloudDebug.initTools(view, potreeLayer, debugGui); view.camera3D.far = 2.0 * size.length(); diff --git a/examples/potree_3d_map.html b/examples/potree_3d_map.html index 2df2b1a1e8..553a959ed5 100644 --- a/examples/potree_3d_map.html +++ b/examples/potree_3d_map.html @@ -71,7 +71,7 @@ // add potreeLayer to scene function onLayerReady() { - debug.PotreeDebug.initTools(view, potreeLayer, debugGui); + debug.PointCloudDebug.initTools(view, potreeLayer, debugGui); // update stats window var info = document.getElementById('info'); diff --git a/src/Layer/C3DTilesLayer.js b/src/Layer/C3DTilesLayer.js index ee48c5d62d..1a9710bbe3 100644 --- a/src/Layer/C3DTilesLayer.js +++ b/src/Layer/C3DTilesLayer.js @@ -95,7 +95,9 @@ class C3DTilesLayer extends GeometryLayer { * @param {Number} [config.cleanupDelay=1000] The time (in ms) after which a tile content (and its children) are * removed from the scene. * @param {C3DTExtensions} [config.registeredExtensions] 3D Tiles extensions managers registered for this tileset. - * @param {String} [config.pntsMode= PNTS_MODE.COLOR] {@link PointsMaterials} Point cloud coloring mode. Only 'COLOR' or 'CLASSIFICATION' are possible. COLOR uses RGB colors of the points, CLASSIFICATION uses a classification property of the batch table to color points. + * @param {String} [config.pntsMode= PNTS_MODE.COLOR] {@link PointsMaterials} Point cloud coloring mode. + * Only 'COLOR' or 'CLASSIFICATION' are possible. COLOR uses RGB colors of the points, + * CLASSIFICATION uses a classification property of the batch table to color points. * @param {String} [config.pntsShape= PNTS_SHAPE.CIRCLE] Point cloud point shape. Only 'CIRCLE' or 'SQUARE' are possible. * @param {String} [config.pntsSizeMode= PNTS_SIZE_MODE.VALUE] {@link PointsMaterials} Point cloud size mode. Only 'VALUE' or 'ATTENUATED' are possible. VALUE use constant size, ATTENUATED compute size depending on distance from point to camera. * @param {Number} [config.pntsMinAttenuatedSize=3] Minimum scale used by 'ATTENUATED' size mode diff --git a/src/Layer/PointCloudLayer.js b/src/Layer/PointCloudLayer.js index aa58275122..a46df7f027 100644 --- a/src/Layer/PointCloudLayer.js +++ b/src/Layer/PointCloudLayer.js @@ -194,7 +194,7 @@ class PointCloudLayer extends GeometryLayer { if (this.material) { this.material.visible = this.visible; this.material.opacity = this.opacity; - this.material.transparent = this.opacity < 1; + this.material.transparent = this.opacity < 1 || this.material.userData.needTransparency[this.material.mode]; this.material.size = this.pointSize; this.material.scale = context.camera.preSSE; if (this.material.updateUniforms) { diff --git a/src/Layer/ReferencingLayerProperties.js b/src/Layer/ReferencingLayerProperties.js index c4286f17fd..ee6e2aae3f 100644 --- a/src/Layer/ReferencingLayerProperties.js +++ b/src/Layer/ReferencingLayerProperties.js @@ -1,7 +1,6 @@ // next step is move these properties to Style class // and hide transparent mechanism - function ReferLayerProperties(material, layer) { if (layer && layer.isGeometryLayer) { let transparent = material.transparent; @@ -16,26 +15,31 @@ function ReferLayerProperties(material, layer) { get: () => material.layer.opacity, }); } + if (material.uniforms && material.uniforms.mode != undefined) { Object.defineProperty(material.uniforms.mode, 'value', { get: () => material.layer.pntsMode, }); } + if (material.uniforms && material.uniforms.shape != undefined) { Object.defineProperty(material.uniforms.shape, 'value', { get: () => material.layer.pntsShape, }); } + if (material.uniforms && material.uniforms.sizeMode != undefined) { Object.defineProperty(material.uniforms.sizeMode, 'value', { get: () => material.layer.pntsSizeMode, }); } + if (material.uniforms && material.uniforms.minAttenuatedSize != undefined) { Object.defineProperty(material.uniforms.minAttenuatedSize, 'value', { get: () => material.layer.pntsMinAttenuatedSize, }); } + if (material.uniforms && material.uniforms.maxAttenuatedSize != undefined) { Object.defineProperty(material.uniforms.maxAttenuatedSize, 'value', { get: () => material.layer.pntsMaxAttenuatedSize, @@ -45,11 +49,13 @@ function ReferLayerProperties(material, layer) { Object.defineProperty(material, 'wireframe', { get: () => material.layer.wireframe, }); + Object.defineProperty(material, 'transparent', { get: () => { - if (transparent != material.layer.opacity < 1.0) { + const needTransparency = material.userData.needTransparency?.[material.mode] || material.layer.opacity < 1.0; + if (transparent != needTransparency) { material.needsUpdate = true; - transparent = material.layer.opacity < 1.0; + transparent = needTransparency; } return transparent; }, diff --git a/src/Provider/3dTilesProvider.js b/src/Provider/3dTilesProvider.js index 864b632f77..7448c56721 100644 --- a/src/Provider/3dTilesProvider.js +++ b/src/Provider/3dTilesProvider.js @@ -119,6 +119,7 @@ function executeCommand(command) { } else if (magic == 'b3dm') { func = supportedFormats.b3dm; } else if (magic == 'pnts') { + layer.hasPnts = true; func = supportedFormats.pnts; } else if (magic == 'glTF') { func = supportedFormats.gltf; diff --git a/src/Renderer/PointsMaterial.js b/src/Renderer/PointsMaterial.js index a365930d58..d9d51e4b4f 100644 --- a/src/Renderer/PointsMaterial.js +++ b/src/Renderer/PointsMaterial.js @@ -61,7 +61,7 @@ export const ClassificationScheme = { 10: { visible: true, name: 'rail', color: new THREE.Color(0.8, 0.8, 1.0), opacity: 1.0 }, 11: { visible: true, name: 'road Surface', color: new THREE.Color(0.4, 0.4, 0.7), opacity: 1.0 }, 12: { visible: true, name: 'overlap', color: new THREE.Color(1.0, 1.0, 0.0), opacity: 1.0 }, - DEFAULT: { visible: true, name: 'default', color: new THREE.Color(0.3, 0.6, 0.6), opacity: 0.5 }, + DEFAULT: { visible: true, name: 'default', color: new THREE.Color(0.3, 0.6, 0.6), opacity: 1.0 }, }, }; @@ -75,7 +75,7 @@ const DiscreteScheme = { 5: { visible: true, name: '5', color: new THREE.Color('rgb(230, 25, 75)'), opacity: 1.0 }, 6: { visible: true, name: '6', color: new THREE.Color('rgb(66, 212, 244)'), opacity: 1.0 }, 7: { visible: true, name: '7', color: new THREE.Color('rgb(240, 50, 230)'), opacity: 1.0 }, - DEFAULT: { visible: true, name: 'default', color: white, opacity: 0.5 }, + DEFAULT: { visible: true, name: 'default', color: white, opacity: 1.0 }, }, }; @@ -116,6 +116,7 @@ function generateGradientTexture(gradient) { } function recomputeTexture(scheme, texture, nbClass) { + let needTransparency; const data = texture.image.data; const width = texture.image.width; if (!nbClass) { nbClass = Object.keys(scheme).length; } @@ -147,9 +148,11 @@ function recomputeTexture(scheme, texture, nbClass) { data[j + 1] = parseInt(255 * color.g, 10); data[j + 2] = parseInt(255 * color.b, 10); data[j + 3] = visible ? parseInt(255 * opacity, 10) : 0; - } + needTransparency = needTransparency || opacity < 1; + } texture.needsUpdate = true; + return needTransparency; } class PointsMaterial extends THREE.ShaderMaterial { @@ -163,7 +166,6 @@ class PointsMaterial extends THREE.ShaderMaterial { * @param {THREE.Vector2} [options.intensityRange=new THREE.Vector2(1, 65536)] intensity range. * @param {THREE.Vector2} [options.elevationRange=new THREE.Vector2(0, 1000)] elevation range. * @param {THREE.Vector2} [options.angleRange=new THREE.Vector2(-90, 90)] scan angle range. - * @param {boolean} [options.applyOpacityClassication=false] apply opacity classification on all display mode. * @param {Scheme} [options.classification] LUT for point classification colorization. * @param {Scheme} [options.discreteScheme] LUT for other discret point values colorization. * @param {string} [options.gradient] Descrition of the gradient to use for continuous point values. @@ -191,7 +193,6 @@ class PointsMaterial extends THREE.ShaderMaterial { const oiMaterial = options.orientedImageMaterial; const classificationScheme = options.classification || ClassificationScheme.DEFAULT; const discreteScheme = options.discreteScheme || DiscreteScheme.DEFAULT; - const applyOpacityClassication = options.applyOpacityClassication == undefined ? false : options.applyOpacityClassication; const size = options.size || 0; const mode = options.mode || PNTS_MODE.COLOR; const shape = options.shape || PNTS_SHAPE.CIRCLE; @@ -212,7 +213,6 @@ class PointsMaterial extends THREE.ShaderMaterial { delete options.orientedImageMaterial; delete options.classification; delete options.discreteScheme; - delete options.applyOpacityClassication; delete options.size; delete options.mode; delete options.shape; @@ -222,6 +222,7 @@ class PointsMaterial extends THREE.ShaderMaterial { delete options.gradient; super(options); + this.userData.needTransparency = {}; this.gradients = gradients; this.gradientTexture = new THREE.CanvasTexture(); @@ -242,7 +243,6 @@ class PointsMaterial extends THREE.ShaderMaterial { CommonMaterial.setUniformProperty(this, 'intensityRange', intensityRange); CommonMaterial.setUniformProperty(this, 'elevationRange', elevationRange); CommonMaterial.setUniformProperty(this, 'angleRange', angleRange); - CommonMaterial.setUniformProperty(this, 'applyOpacityClassication', applyOpacityClassication); CommonMaterial.setUniformProperty(this, 'sizeMode', sizeMode); CommonMaterial.setUniformProperty(this, 'scale', scale); CommonMaterial.setUniformProperty(this, 'minAttenuatedSize', minAttenuatedSize); @@ -299,7 +299,8 @@ class PointsMaterial extends THREE.ShaderMaterial { } recomputeClassification() { - recomputeTexture(this.classificationScheme, this.classificationTexture, 32); + const needTransparency = recomputeTexture(this.classificationScheme, this.classificationTexture, 32); + this.userData.needTransparency[PNTS_MODE.CLASSIFICATION] = needTransparency; this.dispatchEvent({ type: 'material_property_changed', target: this.uniforms, @@ -307,7 +308,11 @@ class PointsMaterial extends THREE.ShaderMaterial { } recomputeDiscreteTexture() { - recomputeTexture(this.discreteScheme, this.discreteTexture); + const needTransparency = recomputeTexture(this.discreteScheme, this.discreteTexture); + this.userData.needTransparency[PNTS_MODE.RETURN_NUMBER] = needTransparency; + this.userData.needTransparency[PNTS_MODE.RETURN_TYPE] = needTransparency; + this.userData.needTransparency[PNTS_MODE.RETURN_COUNT] = needTransparency; + this.userData.needTransparency[PNTS_MODE.POINT_SOURCE_ID] = needTransparency; this.dispatchEvent({ type: 'material_property_changed', target: this.uniforms, diff --git a/src/Renderer/Shader/PointsVS.glsl b/src/Renderer/Shader/PointsVS.glsl index c799bf31d6..e932eb5d25 100644 --- a/src/Renderer/Shader/PointsVS.glsl +++ b/src/Renderer/Shader/PointsVS.glsl @@ -19,8 +19,6 @@ uniform vec2 elevationRange; uniform vec2 intensityRange; uniform vec2 angleRange; -uniform bool applyOpacityClassication; - uniform sampler2D classificationTexture; uniform sampler2D discreteTexture; uniform sampler2D gradientTexture; @@ -93,14 +91,11 @@ void main() { if (picking) { vColor = unique_id; } else { - vColor.a = opacity; - if (applyOpacityClassication || mode == PNTS_MODE_CLASSIFICATION) { + vColor.a = 1.0; + if (mode == PNTS_MODE_CLASSIFICATION) { vec2 uv = vec2(classification/255., 0.5); vColor = texture2D(classificationTexture, uv); - vColor.a *= opacity; - } - - if (mode == PNTS_MODE_NORMAL) { + } else if (mode == PNTS_MODE_NORMAL) { vColor.rgb = abs(normal); } else if (mode == PNTS_MODE_COLOR) { // default to color mode @@ -150,6 +145,8 @@ void main() { vec2 uv = vec2(i, (1. - i)); vColor = texture2D(gradientTexture, uv); } + + vColor.a *= opacity; } #include diff --git a/test/functional/source_stream_wfs_25d.js b/test/functional/source_stream_wfs_25d.js index 7e542e702a..5afa5f081c 100644 --- a/test/functional/source_stream_wfs_25d.js +++ b/test/functional/source_stream_wfs_25d.js @@ -14,7 +14,8 @@ describe('source_stream_wfs_25d', function _() { // Test picking a feature geometry property from `wfsBuilding` layer. // Picking is done at the given screen coordinates. const buildingId = await page.evaluate(() => picking({ x: 97, y: 213 })); - assert.equal(buildingId.geojson.id, 'batiment.46260502'); + assert.ok(buildingId, 'no buildings picked'); + assert.equal(buildingId.cleabs, 'BATIMENT0000000241634062'); }); it('should remove GeometryLayer', async () => { const countGeometryLayerStart = await page.evaluate(() => view.getLayers(l => l.isGeometryLayer).length); diff --git a/test/unit/fetcher.js b/test/unit/fetcher.js index 340790cf5f..b2b60f6083 100644 --- a/test/unit/fetcher.js +++ b/test/unit/fetcher.js @@ -110,7 +110,7 @@ describe('Fetcher', function () { done(); }) .catch(done); - }).timeout(8000); + }).timeout(10000); }); describe('multiple', function () { diff --git a/utils/debug/3dTilesDebug.js b/utils/debug/3dTilesDebug.js index 7f01c31f49..a6a0e79f8e 100644 --- a/utils/debug/3dTilesDebug.js +++ b/utils/debug/3dTilesDebug.js @@ -2,7 +2,7 @@ import * as THREE from 'three'; import View from 'Core/View'; import GeometryLayer from 'Layer/GeometryLayer'; import { C3DTilesBoundingVolumeTypes } from 'Core/3DTiles/C3DTilesEnums'; -import { PNTS_SHAPE, PNTS_SIZE_MODE } from 'Renderer/PointsMaterial'; +import { PNTS_MODE, PNTS_SHAPE, PNTS_SIZE_MODE } from 'Renderer/PointsMaterial'; import GeometryDebug from './GeometryDebug'; const bboxMesh = new THREE.Mesh(); @@ -83,18 +83,28 @@ export default function create3dTilesDebugUI(datDebugTool, view, _3dTileslayer) _3dTileslayer.frozen = value; view.notifyChange(_3dTileslayer); })); - gui.add(_3dTileslayer, 'pntsShape', PNTS_SHAPE).name('Points Shape').onChange(() => { - view.notifyChange(view.camera.camera3D); - }); - gui.add(_3dTileslayer, 'pntsSizeMode', PNTS_SIZE_MODE).name('Pnts size mode').onChange(() => { - view.notifyChange(view.camera.camera3D); - }); - gui.add(_3dTileslayer, 'pntsMinAttenuatedSize', 0, 15).name('Min attenuated size').onChange(() => { - view.notifyChange(view.camera.camera3D); - }); + if (_3dTileslayer.hasPnts) { + const _3DTILES_PNTS_MODE = { + CLASSIFICATION: PNTS_MODE.CLASSIFICATION, + COLOR: PNTS_MODE.COLOR, + }; + gui.add(_3dTileslayer, 'pntsMode', _3DTILES_PNTS_MODE).name('Display mode').onChange(() => { + _3dTileslayer.pntsMode = +_3dTileslayer.pntsMode; + view.notifyChange(view.camera.camera3D); + }); + gui.add(_3dTileslayer, 'pntsShape', PNTS_SHAPE).name('Points Shape').onChange(() => { + view.notifyChange(view.camera.camera3D); + }); + gui.add(_3dTileslayer, 'pntsSizeMode', PNTS_SIZE_MODE).name('Pnts size mode').onChange(() => { + view.notifyChange(view.camera.camera3D); + }); - gui.add(_3dTileslayer, 'pntsMaxAttenuatedSize', 0, 15).name('Max attenuated size').onChange(() => { - view.notifyChange(view.camera.camera3D); - }); + gui.add(_3dTileslayer, 'pntsMinAttenuatedSize', 0, 15).name('Min attenuated size').onChange(() => { + view.notifyChange(view.camera.camera3D); + }); + gui.add(_3dTileslayer, 'pntsMaxAttenuatedSize', 0, 15).name('Max attenuated size').onChange(() => { + view.notifyChange(view.camera.camera3D); + }); + } } diff --git a/utils/debug/Main.js b/utils/debug/Main.js index cbec7bf055..92d02a47b3 100644 --- a/utils/debug/Main.js +++ b/utils/debug/Main.js @@ -1,5 +1,5 @@ export { default as Debug } from './Debug'; -export { default as PotreeDebug } from './PotreeDebug'; +export { default as PointCloudDebug } from './PointCloudDebug'; export { default as createTileDebugUI } from './TileDebug'; export { default as create3dTilesDebugUI } from './3dTilesDebug'; export { default as GeometryDebug } from './GeometryDebug'; diff --git a/utils/debug/PotreeDebug.js b/utils/debug/PointCloudDebug.js similarity index 86% rename from utils/debug/PotreeDebug.js rename to utils/debug/PointCloudDebug.js index 9944626179..136f061a7d 100644 --- a/utils/debug/PotreeDebug.js +++ b/utils/debug/PointCloudDebug.js @@ -75,13 +75,18 @@ export default { const styleUI = layer.debugUI.addFolder('Styling'); if (layer.material.mode != undefined) { - styleUI.add(layer.material, 'mode', PNTS_MODE).name('Display mode').onChange(update); - const gradiantsName = Object.keys(layer.material.gradients); - styleUI.add({ gradient: gradiantsName[0] }, 'gradient', gradiantsName).name('gradient') + const modeNames = Object.keys(PNTS_MODE); + const mode = modeNames.filter(v => PNTS_MODE[v] === layer.material.mode)[0]; + styleUI.add({ mode }, 'mode', modeNames).name('Display mode') + .onChange((value) => { + layer.material.mode = PNTS_MODE[value]; + update(); + }); + const gradiantsNames = Object.keys(layer.material.gradients); + styleUI.add({ gradient: gradiantsNames[0] }, 'gradient', gradiantsNames).name('gradient') .onChange((value) => { layer.material.gradient = layer.material.gradients[value]; - setupControllerVisibily(layer.debugUI, layer.material.mode); - view.notifyChange(layer, true); + update(); }); styleUI.add(layer, 'minIntensityRange', layer.minIntensityRange, layer.maxIntensityRange - 1).name('Intensity min') .onChange((value) => { @@ -89,8 +94,7 @@ export default { layer.maxIntensityRange = value + 1; getController(layer.debugUI, 'maxIntensityRange').updateDisplay(); } - setupControllerVisibily(layer.debugUI, layer.material.mode); - view.notifyChange(layer, true); + update(); }); styleUI.add(layer, 'maxIntensityRange', layer.minIntensityRange + 1, layer.maxIntensityRange).name('Intensity max') .onChange((value) => { @@ -98,8 +102,7 @@ export default { layer.minIntensityRange = value - 1; getController(layer.debugUI, 'minIntensityRange').updateDisplay(); } - setupControllerVisibily(layer.debugUI, layer.material.mode); - view.notifyChange(layer, true); + update(); }); styleUI.add(layer, 'minElevationRange', layer.minElevationRange, layer.maxElevationRange).name('Elevation min') .onChange((value) => { @@ -107,8 +110,7 @@ export default { layer.maxElevationRange = value + 1; getController(layer.debugUI, 'maxElevationRange').updateDisplay(); } - setupControllerVisibily(layer.debugUI, layer.material.mode); - view.notifyChange(layer, true); + update(); }); styleUI.add(layer, 'maxElevationRange', layer.minElevationRange, layer.maxElevationRange).name('Elevation max') .onChange((value) => { @@ -116,8 +118,7 @@ export default { layer.minElevationRange = value - 1; getController(layer.debugUI, 'minElevationRange').updateDisplay(); } - setupControllerVisibily(layer.debugUI, layer.material.mode); - view.notifyChange(layer, true); + update(); }); styleUI.add(layer, 'minAngleRange', layer.minAngleRange, layer.maxAngleRange).name('Angle min') .onChange((value) => { @@ -125,8 +126,7 @@ export default { layer.maxAngleRange = value + 1; getController(layer.debugUI, 'maxAngleRange').updateDisplay(); } - setupControllerVisibily(layer.debugUI, layer.material.mode); - view.notifyChange(layer, true); + update(); }); styleUI.add(layer, 'maxAngleRange', layer.minAngleRange, layer.maxAngleRange).name('Angle max') .onChange((value) => { @@ -134,8 +134,7 @@ export default { layer.minAngleRange = value - 1; getController(layer.debugUI, 'minAngleRange').updateDisplay(); } - setupControllerVisibily(layer.debugUI, layer.material.mode); - view.notifyChange(layer, true); + update(); }); } if (layer.material.shape != undefined) {