From 06c71816f5c5834dc7a385bd001e32d3e884faf7 Mon Sep 17 00:00:00 2001 From: Anthony GULLIENT Date: Thu, 22 Feb 2024 15:34:04 +0100 Subject: [PATCH] feat(TiledGeometryLayer): layer can now hide skirt --- src/Converter/convertToTile.js | 3 ++- src/Core/Prefab/TileBuilder.js | 2 +- src/Core/Prefab/computeBufferTileGeometry.js | 16 ++++++++++------ src/Core/TileGeometry.js | 10 ++++++++-- src/Layer/TiledGeometryLayer.js | 17 ++++++++++++++++- src/Renderer/OBB.js | 4 ++-- test/unit/obb.js | 2 +- test/unit/tilemesh.js | 8 ++++---- 8 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/Converter/convertToTile.js b/src/Converter/convertToTile.js index 3cece0f3fa..c22d89154c 100644 --- a/src/Converter/convertToTile.js +++ b/src/Converter/convertToTile.js @@ -45,8 +45,9 @@ export default { const paramsGeometry = { extent, level, - segment: layer.segments || 16, + segments: layer.segments || 16, disableSkirt: layer.disableSkirt, + hideSkirt: layer.hideSkirt, }; return newTileGeometry(builder, paramsGeometry).then((result) => { diff --git a/src/Core/Prefab/TileBuilder.js b/src/Core/Prefab/TileBuilder.js index a6ae3f60ed..b4436a5fec 100644 --- a/src/Core/Prefab/TileBuilder.js +++ b/src/Core/Prefab/TileBuilder.js @@ -10,7 +10,7 @@ const cacheTile = new Cache(); export default function newTileGeometry(builder, params) { const { sharableExtent, quaternion, position } = builder.computeSharableExtent(params.extent); const south = sharableExtent.south.toFixed(6); - const bufferKey = `${builder.crs}_${params.disableSkirt ? 0 : 1}_${params.segment}`; + const bufferKey = `${builder.crs}_${params.disableSkirt ? 0 : 1}_${params.segments}`; let promiseGeometry = cacheTile.get(south, params.level, bufferKey); // build geometry if doesn't exist diff --git a/src/Core/Prefab/computeBufferTileGeometry.js b/src/Core/Prefab/computeBufferTileGeometry.js index 11e9709f4a..a7f5fcabdf 100644 --- a/src/Core/Prefab/computeBufferTileGeometry.js +++ b/src/Core/Prefab/computeBufferTileGeometry.js @@ -1,5 +1,10 @@ import * as THREE from 'three'; +export function getBufferIndexSize(segments, noSkirt) { + const triangles = (segments) * (segments) * 2 + (noSkirt ? 0 : 4 * segments * 2); + return triangles * 3; +} + export default function computeBuffers(params) { // Create output buffers. const outBuffers = { @@ -26,7 +31,7 @@ export default function computeBuffers(params) { const computeUvs = []; const builder = params.builder; - const nSeg = params.segment || 8; + const nSeg = params.segments; // segments count : // Tile : (nSeg + 1) * (nSeg + 1) // Skirt : 8 * (nSeg - 1) @@ -35,8 +40,6 @@ export default function computeBuffers(params) { throw new Error('Tile segments count is too big'); } - const triangles = (nSeg) * (nSeg) * 2 + (params.disableSkirt ? 0 : 4 * nSeg * 2); - outBuffers.position = new Float32Array(nVertex * 3); outBuffers.normal = new Float32Array(nVertex * 3); @@ -46,13 +49,14 @@ export default function computeBuffers(params) { } computeUvs[0] = () => {}; + const bufferIndexSize = getBufferIndexSize(nSeg, params.disableSkirt); if (params.buildIndexAndUv_0) { if (nVertex < 2 ** 8) { - outBuffers.index = new Uint8Array(triangles * 3); + outBuffers.index = new Uint8Array(bufferIndexSize); } else if (nVertex < 2 ** 16) { - outBuffers.index = new Uint16Array(triangles * 3); + outBuffers.index = new Uint16Array(bufferIndexSize); } else if (nVertex < 2 ** 32) { - outBuffers.index = new Uint32Array(triangles * 3); + outBuffers.index = new Uint32Array(bufferIndexSize); } outBuffers.uvs[0] = new Float32Array(nVertex * 2); computeUvs[0] = (id, u, v) => { diff --git a/src/Core/TileGeometry.js b/src/Core/TileGeometry.js index daa9a86db8..0656f6a3e9 100644 --- a/src/Core/TileGeometry.js +++ b/src/Core/TileGeometry.js @@ -1,5 +1,5 @@ import * as THREE from 'three'; -import computeBuffers from 'Core/Prefab/computeBufferTileGeometry'; +import computeBuffers, { getBufferIndexSize } from 'Core/Prefab/computeBufferTileGeometry'; function defaultBuffers(params) { params.buildIndexAndUv_0 = true; @@ -20,7 +20,7 @@ class TileGeometry extends THREE.BufferGeometry { super(); this.center = params.center; this.extent = params.extent; - + this.segments = params.segments; this.setIndex(buffers.index); this.setAttribute('position', buffers.position); this.setAttribute('normal', buffers.normal); @@ -31,6 +31,12 @@ class TileGeometry extends THREE.BufferGeometry { this.computeBoundingBox(); this.OBB = {}; + if (params.hideSkirt) { + this.hideSkirt = params.hideSkirt; + } + } + set hideSkirt(value) { + this.setDrawRange(0, getBufferIndexSize(this.segments, value)); } } diff --git a/src/Layer/TiledGeometryLayer.js b/src/Layer/TiledGeometryLayer.js index 1c82923021..3d43ad6cf4 100644 --- a/src/Layer/TiledGeometryLayer.js +++ b/src/Layer/TiledGeometryLayer.js @@ -16,7 +16,8 @@ const boundingSphereCenter = new THREE.Vector3(); * @property {boolean} isTiledGeometryLayer - Used to checkout whether this * layer is a TiledGeometryLayer. Default is true. You should not change this, * as it is used internally for optimisation. - * + * @property {boolean} hideSkirt (default false) - Used to hide the skirt (tile borders). + * Useful when the layer opacity < 1 */ class TiledGeometryLayer extends GeometryLayer { /** @@ -70,6 +71,7 @@ class TiledGeometryLayer extends GeometryLayer { this.object3d.geoidHeight = 0; this.protocol = 'tile'; + this._hideSkirt = false; this.sseSubdivisionThreshold = this.sseSubdivisionThreshold || 1.0; @@ -101,6 +103,19 @@ class TiledGeometryLayer extends GeometryLayer { this.maxScreenSizeNode = this.sseSubdivisionThreshold * (SIZE_DIAGONAL_TEXTURE * 2); } + get hideSkirt() { + return this._hideSkirt; + } + set hideSkirt(value) { + this._hideSkirt = value; + for (const node of this.level0Nodes) { + node.traverse((obj) => { + if (obj.isTileMesh) { + obj.geometry.hideSkirt = value; + } + }); + } + } /** * Picking method for this layer. It uses the {@link Picking#pickTilesAt} * method. diff --git a/src/Renderer/OBB.js b/src/Renderer/OBB.js index 50ebc99387..360b53e41f 100644 --- a/src/Renderer/OBB.js +++ b/src/Renderer/OBB.js @@ -107,11 +107,11 @@ class OBB extends THREE.Object3D { if (extent.crs == 'EPSG:4326') { const { sharableExtent, quaternion, position } = builder.computeSharableExtent(extent); // Compute the minimum count of segment to build tile - const segment = Math.max(Math.floor(sharableExtent.planarDimensions(dimension).x / 90 + 1), 2); + const segments = Math.max(Math.floor(sharableExtent.planarDimensions(dimension).x / 90 + 1), 2); const paramsGeometry = { extent: sharableExtent, level: 0, - segment, + segments, disableSkirt: true, builder, }; diff --git a/test/unit/obb.js b/test/unit/obb.js index 2ce563abc1..b2e4dd8f01 100644 --- a/test/unit/obb.js +++ b/test/unit/obb.js @@ -51,7 +51,7 @@ function assertVerticesAreInOBB(builder, extent) { extent, disableSkirt: true, level: 0, - segment: 1, + segments: 1, }; return newTileGeometry(builder, params) diff --git a/test/unit/tilemesh.js b/test/unit/tilemesh.js index d0288225e5..0d6b211f6d 100644 --- a/test/unit/tilemesh.js +++ b/test/unit/tilemesh.js @@ -79,7 +79,7 @@ describe('TileMesh', function () { const paramsGeometry = { extent: planarlayer.object3d.children[0].extent, level: 0, - segment: 260, + segments: 260, disableSkirt: true, }; @@ -91,7 +91,7 @@ describe('TileMesh', function () { const paramsGeometry2 = { extent: planarlayer.object3d.children[0].extent, level: 0, - segment: (2 ** 16), + segments: (2 ** 16), disableSkirt: true, }; @@ -130,7 +130,7 @@ describe('TileMesh', function () { const paramsGeometry = { extent: planarlayer.object3d.children[0].extent, level: 0, - segment: 4, + segments: 4, disableSkirt: true, }; @@ -147,7 +147,7 @@ describe('TileMesh', function () { const paramsGeometry = { extent: planarlayer.object3d.children[0].extent, level: 0, - segment: 2, + segments: 2, disableSkirt: true, };