diff --git a/src/Core/Layer/Layer.js b/src/Core/Layer/Layer.js index f6ae6a233a..68f7e5d0f4 100644 --- a/src/Core/Layer/Layer.js +++ b/src/Core/Layer/Layer.js @@ -80,6 +80,21 @@ function GeometryLayer(id, object3d) { // Setup default picking method this.pickObjectsAt = (view, mouse, radius) => Picking.pickObjectsAt(view, mouse, radius, this.object3d); + // Attached layers expect to receive the visual representation of a layer (= THREE object with a material). + // So if a layer's update function don't process this kind of object, the layer must provide + // a getObjectToUpdateForAttachedLayers function that returns the correct object to update for attached + // layer. + // See 3dtilesProvider or PointCloudProvider for examples. + // eslint-disable-next-line arrow-body-style + this.getObjectToUpdateForAttachedLayers = (obj) => { + if (obj.parent && obj.material) { + return { + element: obj, + parent: obj.parent, + }; + } + }; + this.postUpdate = () => {}; } diff --git a/src/Core/MainLoop.js b/src/Core/MainLoop.js index bd7a1f7a3a..d2a36a9bd3 100644 --- a/src/Core/MainLoop.js +++ b/src/Core/MainLoop.js @@ -65,10 +65,37 @@ function updateElements(context, geometryLayer, elements) { // and then update Debug.js:addGeometryLayerDebugFeatures const newElementsToUpdate = geometryLayer.update(context, geometryLayer, element); - // update attached layers - for (const attachedLayer of geometryLayer._attachedLayers) { - if (attachedLayer.ready) { - attachedLayer.update(context, attachedLayer, element); + const sub = geometryLayer.getObjectToUpdateForAttachedLayers(element); + + if (sub) { + if (sub.element) { + if (__DEBUG__) { + if (!(sub.element.isObject3D)) { + throw new Error(` + Invalid object for attached layer to update. + Must be a THREE.Object and have a THREE.Material`); + } + } + // update attached layers + for (const attachedLayer of geometryLayer._attachedLayers) { + if (attachedLayer.ready) { + attachedLayer.update(context, attachedLayer, sub.element, sub.parent); + } + } + } else if (sub.elements) { + for (let i = 0; i < sub.elements.length; i++) { + if (!(sub.elements[i].isObject3D)) { + throw new Error(` + Invalid object for attached layer to update. + Must be a THREE.Object and have a THREE.Material`); + } + // update attached layers + for (const attachedLayer of geometryLayer._attachedLayers) { + if (attachedLayer.ready) { + attachedLayer.update(context, attachedLayer, sub.elements[i], sub.parent); + } + } + } } } updateElements(context, geometryLayer, newElementsToUpdate); diff --git a/src/Process/3dTilesProcessing.js b/src/Process/3dTilesProcessing.js index 18a9be13af..8f78e4b6a6 100644 --- a/src/Process/3dTilesProcessing.js +++ b/src/Process/3dTilesProcessing.js @@ -16,6 +16,11 @@ function requestNewTile(view, scheduler, geometryLayer, metadata, parent, redraw return scheduler.execute(command); } +function getChildTiles(tile) { + // only keep children that have the same layer and a valid tileId + return tile.children.filter(n => n.layer == tile.layer && n.tileId); +} + function subdivideNode(context, layer, node, cullingTest) { if (node.additiveRefinement) { // Additive refinement can only fetch visible children. @@ -88,7 +93,7 @@ function _subdivideNodeAdditive(context, layer, node, cullingTest) { } function _subdivideNodeSubstractive(context, layer, node) { - if (!node.pendingSubdivision && node.children.filter(n => n.layer == layer).length == 0) { + if (!node.pendingSubdivision && getChildTiles(node).length == 0) { const childrenTiles = layer.tileIndex.index[node.tileId].children; if (childrenTiles === undefined || childrenTiles.length === 0) { return; @@ -195,7 +200,7 @@ function cleanup3dTileset(layer, n, depth = 0) { n.parent.remove(n); } } else { - const tiles = n.children.filter(n => n.tileId != undefined); + const tiles = getChildTiles(n); n.remove(...tiles); } } @@ -330,11 +335,11 @@ export function process3dTilesNode(cullingTest, subdivisionTest) { subdivideNode(context, layer, node, cullingTest); // display iff children aren't ready setDisplayed(node, node.pendingSubdivision || node.additiveRefinement); - returnValue = node.children.filter(n => n.layer == layer); + returnValue = getChildTiles(node); } else { setDisplayed(node, true); - for (const n of node.children.filter(n => n.layer == layer)) { + for (const n of getChildTiles(node)) { n.visible = false; markForDeletion(layer, n); } @@ -342,7 +347,7 @@ export function process3dTilesNode(cullingTest, subdivisionTest) { // toggle wireframe if (node.content && node.content.visible) { node.content.traverse((o) => { - if (o.material) { + if (o.layer == layer && o.material) { o.material.wireframe = layer.wireframe; } }); @@ -351,8 +356,6 @@ export function process3dTilesNode(cullingTest, subdivisionTest) { } markForDeletion(layer, node); - - return undefined; }; } diff --git a/src/Process/LayeredMaterialNodeProcessing.js b/src/Process/LayeredMaterialNodeProcessing.js index 9af513f9c5..f7064899f1 100644 --- a/src/Process/LayeredMaterialNodeProcessing.js +++ b/src/Process/LayeredMaterialNodeProcessing.js @@ -140,11 +140,7 @@ function checkNodeElevationTextureValidity(texture, noDataValue) { tData[l - Math.sqrt(l)] > noDataValue; } -export function updateLayeredMaterialNodeImagery(context, layer, node) { - if (!node.parent) { - return; - } - +export function updateLayeredMaterialNodeImagery(context, layer, node, parent) { const material = node.material; // Initialisation @@ -156,10 +152,10 @@ export function updateLayeredMaterialNodeImagery(context, layer, node) { // because even if this tile is outside of the layer, it could inherit it's // parent texture if (!layer.noTextureParentOutsideLimit && - node.parent && - node.parent.material && - node.parent.getIndexLayerColor && - node.parent.getIndexLayerColor(layer.id) >= 0) { + parent && + parent.material && + parent.getIndexLayerColor && + parent.getIndexLayerColor(layer.id) >= 0) { // ok, we're going to inherit our parent's texture } else { node.layerUpdateState[layer.id].noMoreUpdatePossible(); @@ -185,7 +181,7 @@ export function updateLayeredMaterialNodeImagery(context, layer, node) { const sequence = ImageryLayers.getColorLayersIdOrderedBySequence(imageryLayers); material.setSequence(sequence); - initNodeImageryTexturesFromParent(node, node.parent, layer); + initNodeImageryTexturesFromParent(node, parent, layer); } // Proposed new process, two separate processes: @@ -303,10 +299,7 @@ export function updateLayeredMaterialNodeImagery(context, layer, node) { }); } -export function updateLayeredMaterialNodeElevation(context, layer, node) { - if (!node.parent) { - return; - } +export function updateLayeredMaterialNodeElevation(context, layer, node, parent) { // TODO: we need either // - compound or exclusive layers // - support for multiple elevation layers @@ -320,7 +313,7 @@ export function updateLayeredMaterialNodeElevation(context, layer, node) { // Init elevation layer, and inherit from parent if possible if (node.layerUpdateState[layer.id] === undefined) { node.layerUpdateState[layer.id] = new LayerUpdateState(); - initNodeElevationTextureFromParent(node, node.parent, layer); + initNodeElevationTextureFromParent(node, parent, layer); currentElevation = material.getElevationLayerLevel(); const minLevel = layer.options.zoom ? layer.options.zoom.min : 0; if (currentElevation >= minLevel) { @@ -401,7 +394,7 @@ export function updateLayeredMaterialNodeElevation(context, layer, node) { // Quick check to avoid using elevation texture with no data value // If we have no data values, we use value from the parent tile // We should later implement multi elevation layer to choose the one to use at each level - insertSignificantValuesFromParent(terrain.texture, node, node.parent, layer); + insertSignificantValuesFromParent(terrain.texture, node, parent, layer); } node.setTextureElevation(terrain); diff --git a/src/Process/PointCloudProcessing.js b/src/Process/PointCloudProcessing.js index 92d7183873..53df6562d1 100644 --- a/src/Process/PointCloudProcessing.js +++ b/src/Process/PointCloudProcessing.js @@ -206,7 +206,6 @@ export default { layer.group.add(elt.obj); elt.obj.updateMatrixWorld(true); - elt.obj.owner = elt; elt.promise = null; }, (err) => { if (err instanceof CancelledCommandException) { @@ -265,7 +264,7 @@ export default { // This format doesn't require points to be evenly distributed, so // we're going to sort the nodes by "importance" (= on screen size) // and display only the first N nodes - layer.group.children.sort((p1, p2) => p2.owner.sse - p1.owner.sse); + layer.group.children.sort((p1, p2) => p2.userData.metadata.sse - p1.userData.metadata.sse); let limitHit = false; layer.displayedCount = 0; @@ -284,7 +283,7 @@ export default { const now = Date.now(); for (let i = layer.group.children.length - 1; i >= 0; i--) { const obj = layer.group.children[i]; - if (!obj.material.visible && (now - obj.owner.notVisibleSince) > 10000) { + if (!obj.material.visible && (now - obj.userData.metadata.notVisibleSince) > 10000) { // remove from group layer.group.children.splice(i, 1); @@ -292,7 +291,7 @@ export default { obj.geometry.dispose(); obj.material = null; obj.geometry = null; - obj.owner.obj = null; + obj.userData.metadata.obj = null; if (__DEBUG__) { if (obj.boxHelper) { diff --git a/src/Provider/3dTilesProvider.js b/src/Provider/3dTilesProvider.js index 0453882f7c..1d572d83ef 100644 --- a/src/Provider/3dTilesProvider.js +++ b/src/Provider/3dTilesProvider.js @@ -8,7 +8,7 @@ import { init3dTilesLayer } from '../Process/3dTilesProcessing'; import utf8Decoder from '../utils/Utf8Decoder'; export function $3dTilesIndex(tileset, baseURL) { - let counter = 0; + let counter = 1; this.index = {}; const inverseTileTransform = new THREE.Matrix4(); const recurse = function recurse_f(node, baseURL, parent) { @@ -60,9 +60,33 @@ export function $3dTilesIndex(tileset, baseURL) { }; } +export function getObjectToUpdateForAttachedLayers(meta) { + if (meta.content) { + const result = []; + meta.content.traverse((obj) => { + if (obj.isObject3D && obj.material && obj.layer == meta.layer) { + result.push(obj); + } + }); + const p = meta.parent; + if (p && p.content) { + return { + elements: result, + parent: p.content, + }; + } else { + return { + elements: result, + }; + } + } +} + function preprocessDataLayer(layer, view, scheduler) { layer.sseThreshold = layer.sseThreshold || 16; layer.cleanupDelay = layer.cleanupDelay || 1000; + // override the default method, since updated objects are metadata in this case + layer.getObjectToUpdateForAttachedLayers = getObjectToUpdateForAttachedLayers; layer._cleanableTiles = []; return Fetcher.json(layer.url, layer.networkOptions).then((tileset) => { @@ -180,6 +204,8 @@ function executeCommand(command) { const setLayer = (obj) => { obj.layers.set(layer.threejsLayer); + obj.userData.metadata = metadata; + obj.layer = layer; }; if (path) { // Check if we have relative or absolute url (with tileset's lopocs for example) diff --git a/src/Provider/PointCloudProvider.js b/src/Provider/PointCloudProvider.js index 14ca8faa9e..001025302a 100644 --- a/src/Provider/PointCloudProvider.js +++ b/src/Provider/PointCloudProvider.js @@ -93,6 +93,7 @@ function parseOctree(layer, hierarchyStepSize, root) { baseurl: url, bbox: bounds, layer, + parent: snode, }; snode.children.push(item); stack.push(item); @@ -196,6 +197,22 @@ function parseMetadata(metadata, layer) { layer.supportsProgressiveDisplay = customBinFormat; } +export function getObjectToUpdateForAttachedLayers(meta) { + if (meta.obj) { + const p = meta.parent; + if (p && p.obj) { + return { + element: meta.obj, + parent: p.obj, + }; + } else { + return { + element: meta.obj, + }; + } + } +} + export default { preprocessDataLayer(layer, view) { if (!layer.file) { @@ -231,6 +248,9 @@ export default { layer.update = PointCloudProcessing.update; layer.postUpdate = PointCloudProcessing.postUpdate; + // override the default method, since updated objects are metadata in this case + layer.getObjectToUpdateForAttachedLayers = getObjectToUpdateForAttachedLayers; + // this probably needs to be moved to somewhere else layer.pickObjectsAt = (view, mouse, radius) => Picking.pickPointsAt(view, mouse, radius, layer); @@ -253,31 +273,32 @@ export default { executeCommand(command) { const layer = command.layer; - const node = command.requester; + const metadata = command.requester; // Query HRC if we don't have children metadata yet. - if (node.childrenBitField && node.children.length === 0) { - parseOctree(layer, layer.metadata.hierarchyStepSize, node).then(() => command.view.notifyChange(layer, false)); + if (metadata.childrenBitField && metadata.children.length === 0) { + parseOctree(layer, layer.metadata.hierarchyStepSize, metadata).then(() => command.view.notifyChange(layer, false)); } // `isLeaf` is for lopocs and allows the pointcloud server to consider that the current // node is the last one, even if we could subdivide even further. // It's necessary because lopocs doens't know about the hierarchy (it generates it on the fly // when we request .hrc files) - const url = `${node.baseurl}/r${node.name}.${layer.extension}?isleaf=${command.isLeaf ? 1 : 0}`; + const url = `${metadata.baseurl}/r${metadata.name}.${layer.extension}?isleaf=${command.isLeaf ? 1 : 0}`; return Fetcher.arrayBuffer(url, layer.fetchOptions).then(buffer => layer.parse(buffer, layer.metadata.pointAttributes)).then((geometry) => { const points = new THREE.Points(geometry, layer.material.clone()); addPickingAttribute(points); points.frustumCulled = false; points.matrixAutoUpdate = false; - points.position.copy(node.bbox.min); + points.position.copy(metadata.bbox.min); points.scale.set(layer.metadata.scale, layer.metadata.scale, layer.metadata.scale); points.updateMatrix(); points.tightbbox = geometry.boundingBox.applyMatrix4(points.matrix); points.layers.set(layer.threejsLayer); points.layer = layer; - points.extent = Extent.fromBox3(command.view.referenceCrs, node.bbox); + points.extent = Extent.fromBox3(command.view.referenceCrs, metadata.bbox); + points.userData.metadata = metadata; return points; }); }, diff --git a/test/3dtiles_unit_test.js b/test/3dtiles_unit_test.js index 2d0feaacb1..f9672b1051 100644 --- a/test/3dtiles_unit_test.js +++ b/test/3dtiles_unit_test.js @@ -65,7 +65,7 @@ describe('Distance computation using boundingVolume.region', function () { const tileset = tilesetWithRegion(); const tileIndex = new $3dTilesIndex(tileset, ''); const tile = new Object3D(); - configureTile(tile, { }, tileIndex.index['0']); + configureTile(tile, { }, tileIndex.index['1']); computeNodeSSE(camera, tile); @@ -78,7 +78,7 @@ describe('Distance computation using boundingVolume.region', function () { const tileset = tilesetWithRegion(m); const tileIndex = new $3dTilesIndex(tileset, ''); const tile = new Object3D(); - configureTile(tile, { }, tileIndex.index['0']); + configureTile(tile, { }, tileIndex.index['1']); computeNodeSSE(camera, tile); @@ -99,7 +99,7 @@ describe('Distance computation using boundingVolume.box', function () { const tileIndex = new $3dTilesIndex(tileset, ''); const tile = new Object3D(); - configureTile(tile, { }, tileIndex.index['0']); + configureTile(tile, { }, tileIndex.index['1']); computeNodeSSE(camera, tile); @@ -114,7 +114,7 @@ describe('Distance computation using boundingVolume.box', function () { const tileIndex = new $3dTilesIndex(tileset, ''); const tile = new Object3D(); - configureTile(tile, { }, tileIndex.index['0']); + configureTile(tile, { }, tileIndex.index['1']); tile.updateMatrixWorld(true); @@ -137,7 +137,7 @@ describe('Distance computation using boundingVolume.sphere', function () { const tileIndex = new $3dTilesIndex(tileset, ''); const tile = new Object3D(); - configureTile(tile, { }, tileIndex.index['0']); + configureTile(tile, { }, tileIndex.index['1']); computeNodeSSE(camera, tile); @@ -152,7 +152,7 @@ describe('Distance computation using boundingVolume.sphere', function () { const tileIndex = new $3dTilesIndex(tileset, ''); const tile = new Object3D(); - configureTile(tile, { }, tileIndex.index['0']); + configureTile(tile, { }, tileIndex.index['1']); tile.updateMatrixWorld(true); diff --git a/test/3dtilesprovider_unit_test.js b/test/3dtilesprovider_unit_test.js new file mode 100644 index 0000000000..24045a29e6 --- /dev/null +++ b/test/3dtilesprovider_unit_test.js @@ -0,0 +1,24 @@ +/* global describe, it */ +import assert from 'assert'; +import { Group, Mesh } from 'three'; +import { getObjectToUpdateForAttachedLayers } from '../src/Provider/3dTilesProvider'; + +describe('getObjectToUpdateForAttachedLayers', function () { + it('should correctly return all children', function () { + const layer = { }; + const tile = { + content: new Group(), + layer, + }; + + for (let i = 0; i < 3; i++) { + const mesh = new Mesh(); + mesh.layer = layer; + tile.content.add(mesh); + } + + const result = getObjectToUpdateForAttachedLayers(tile); + assert.ok(Array.isArray(result.elements)); + assert.ok(result.elements.length, 3); + }); +}); diff --git a/test/pointcloudprovider_unit_test.js b/test/pointcloudprovider_unit_test.js index c33b10b5ff..6141311ba5 100644 --- a/test/pointcloudprovider_unit_test.js +++ b/test/pointcloudprovider_unit_test.js @@ -1,7 +1,5 @@ -/* global describe, it */ import assert from 'assert'; -import { _testing } from '../src/Provider/PointCloudProvider'; - +import { getObjectToUpdateForAttachedLayers, _testing } from '../src/Provider/PointCloudProvider'; describe('PointCloudProvider', function () { it('should correctly parse normal information in metadata', function () { @@ -51,3 +49,23 @@ describe('PointCloudProvider', function () { }); }); + +describe('getObjectToUpdateForAttachedLayers', function () { + it('should correctly no-parent for the root', function () { + const meta = { + obj: 'a', + }; + assert.equal(getObjectToUpdateForAttachedLayers(meta).element, 'a'); + }); + it('should correctly return the element and its parent', function () { + const meta = { + obj: 'a', + parent: { + obj: 'b', + }, + }; + const result = getObjectToUpdateForAttachedLayers(meta); + assert.equal(result.element, 'a'); + assert.equal(result.parent, 'b'); + }); +}); diff --git a/utils/debug/3dTilesDebug.js b/utils/debug/3dTilesDebug.js index 7b92572690..b6999ecc00 100644 --- a/utils/debug/3dTilesDebug.js +++ b/utils/debug/3dTilesDebug.js @@ -3,14 +3,20 @@ import OBBHelper from './OBBHelper'; import View from '../../src/Core/View'; import GeometryDebug from './GeometryDebug'; -export default function create3dTilesDebugUI(datDebugTool, view, layer) { - const gui = GeometryDebug.createGeometryDebugUI(datDebugTool, view, layer); +const invMatrixChangeUpVectorZtoY = new THREE.Matrix4().getInverse(new THREE.Matrix4().makeRotationX(Math.PI / 2)); +const invMatrixChangeUpVectorZtoX = new THREE.Matrix4().getInverse(new THREE.Matrix4().makeRotationZ(-Math.PI / 2)); + +export default function create3dTilesDebugUI(datDebugTool, view, _3dTileslayer) { + const gui = GeometryDebug.createGeometryDebugUI(datDebugTool, view, _3dTileslayer); + + const regionBoundingBoxParent = new THREE.Group(); + view.scene.add(regionBoundingBoxParent); // add wireframe - GeometryDebug.addWireFrameCheckbox(gui, view, layer); + GeometryDebug.addWireFrameCheckbox(gui, view, _3dTileslayer); // Bounding box control - const obb_layer_id = `${layer.id}_obb_debug`; + const obb_layer_id = `${_3dTileslayer.id}_obb_debug`; const debugIdUpdate = function debugIdUpdate(context, layer, node) { const enabled = context.camera.camera3D.layers.test({ mask: 1 << layer.threejsLayer }); @@ -18,74 +24,74 @@ export default function create3dTilesDebugUI(datDebugTool, view, layer) { if (!enabled) { return; } - var obbChildren = node.children.filter(n => n.layer == layer); + const metadata = node.userData.metadata; - if (node.visible && node.boundingVolume) { - // 3dTiles case - let helper; - if (obbChildren.length == 0) { + let helper = node.userData.obb; + + if (node.visible && metadata.boundingVolume) { + if (!helper) { // 3dtiles with region - if (node.boundingVolume.region) { - helper = new OBBHelper(node.boundingVolume.region, `id:${node.id}`); - helper.position.copy(node.boundingVolume.region.position); - helper.rotation.copy(node.boundingVolume.region.rotation); - node.add(helper); - helper.layer = layer; - // add the ability to hide all the debug obj for one layer at once - const l = context.view.getLayers(l => l.id === obb_layer_id)[0]; - const l3js = l.threejsLayer; - helper.layers.set(l3js); - helper.children[0].layers.set(l3js); - helper.updateMatrixWorld(); + if (metadata.boundingVolume.region) { + helper = new OBBHelper(metadata.boundingVolume.region, `id:${node.id}`); + helper.position.copy(metadata.boundingVolume.region.position); + helper.rotation.copy(metadata.boundingVolume.region.rotation); + regionBoundingBoxParent.add(helper); } // 3dtiles with box - if (node.boundingVolume.box) { - const size = node.boundingVolume.box.getSize(); + if (metadata.boundingVolume.box) { + const size = metadata.boundingVolume.box.getSize(); const g = new THREE.BoxGeometry(size.x, size.y, size.z); const material = new THREE.MeshBasicMaterial({ wireframe: true }); helper = new THREE.Mesh(g, material); - node.boundingVolume.box.getCenter(helper.position); - node.add(helper); - helper.layer = layer; - // add the ability to hide all the debug obj for one layer at once - const l = context.view.getLayers(l => l.id === obb_layer_id)[0]; - const l3js = l.threejsLayer; - helper.layers.set(l3js); - helper.updateMatrixWorld(); + metadata.boundingVolume.box.getCenter(helper.position); } // 3dtiles with Sphere - if (node.boundingVolume.sphere) { - const geometry = new THREE.SphereGeometry(node.boundingVolume.sphere.radius, 32, 32); + if (metadata.boundingVolume.sphere) { + const geometry = new THREE.SphereGeometry(metadata.boundingVolume.sphere.radius, 32, 32); const material = new THREE.MeshBasicMaterial({ wireframe: true }); helper = new THREE.Mesh(geometry, material); - helper.position.copy(node.boundingVolume.sphere.center); - node.add(helper); + helper.position.copy(metadata.boundingVolume.sphere.center); + } + + if (helper) { helper.layer = layer; // add the ability to hide all the debug obj for one layer at once - const l = context.view.getLayers(l => l.id === obb_layer_id)[0]; - const l3js = l.threejsLayer; + const l3js = layer.threejsLayer; helper.layers.set(l3js); + if (helper.children.length) { + helper.children[0].layers.set(l3js); + } + node.userData.obb = helper; + helper.updateMatrixWorld(); + } + + if (helper && !metadata.boundingVolume.region) { + // compensate B3dm orientation correction + const gltfUpAxis = _3dTileslayer.asset.gltfUpAxis; + helper.updateMatrix(); + if (gltfUpAxis === undefined || gltfUpAxis === 'Y') { + helper.matrix.premultiply(invMatrixChangeUpVectorZtoY); + } else if (gltfUpAxis === 'X') { + helper.matrix.premultiply(invMatrixChangeUpVectorZtoX); + } + helper.applyMatrix(new THREE.Matrix4()); + + node.add(helper); helper.updateMatrixWorld(); } } else { - helper = obbChildren[0]; + helper = node.userData.obb; } if (helper) { helper.visible = true; - for (const child of node.children.filter(n => n.layer == layer)) { - if (typeof child.setMaterialVisibility === 'function') { - child.setMaterialVisibility(true); - } - child.visible = true; + if (typeof helper.setMaterialVisibility === 'function') { + helper.setMaterialVisibility(true); } } - } else { - // hide obb children - for (const child of node.children.filter(n => n.layer == layer)) { - if (typeof child.setMaterialVisibility === 'function') { - child.setMaterialVisibility(false); - } - child.visible = false; + } else if (helper) { + helper.visible = false; + if (typeof helper.setMaterialVisibility === 'function') { + helper.setMaterialVisibility(false); } } }; @@ -96,14 +102,14 @@ export default function create3dTilesDebugUI(datDebugTool, view, layer) { type: 'debug', update: debugIdUpdate, visible: false, - }, layer).then((l) => { + }, _3dTileslayer).then((l) => { gui.add(l, 'visible').name('Bounding boxes').onChange(() => { view.notifyChange(); }); }); // The sse Threshold for each tile - gui.add(layer, 'sseThreshold', 0, 100).name('sseThreshold').onChange(() => { + gui.add(_3dTileslayer, 'sseThreshold', 0, 100).name('sseThreshold').onChange(() => { view.notifyChange(); }); } diff --git a/utils/debug/PointCloudDebug.js b/utils/debug/PointCloudDebug.js index 840b9511c4..6e7da5216d 100644 --- a/utils/debug/PointCloudDebug.js +++ b/utils/debug/PointCloudDebug.js @@ -59,11 +59,11 @@ export default { for (const pts of layer.group.children) { pts.material.visible = false; for (const name of stickies) { - if (pts.owner.name == name) { + if (pts.userData.metadata.name == name) { pts.material.visible = true; - } else if (!isInHierarchy(pts.owner, name)) { + } else if (!isInHierarchy(pts.userData.metadata, name)) { continue; - } else if (pts.owner.name.length < name.length) { + } else if (pts.userData.metadata.name.length < name.length) { pts.material.visible = layer.dbgDisplayParents; break; } else {