From a9b5ac854c835e5090d794b42e6426f59fe37984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Duhen?= Date: Thu, 23 Jan 2025 18:42:50 +0100 Subject: [PATCH] fix(TileBuilder): pass cache directly to tile gen --- src/Core/Prefab/TileBuilder.ts | 26 ++++++++------ src/Core/Prefab/computeBufferTileGeometry.ts | 36 ++++++++++++-------- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/Core/Prefab/TileBuilder.ts b/src/Core/Prefab/TileBuilder.ts index 35e1a2d97f..5e0b35afc9 100644 --- a/src/Core/Prefab/TileBuilder.ts +++ b/src/Core/Prefab/TileBuilder.ts @@ -6,7 +6,10 @@ import OBB from 'Renderer/OBB'; import type Extent from 'Core/Geographic/Extent'; import Coordinates from 'Core/Geographic/Coordinates'; -const cacheBuffer = new Map(); +const cacheBuffer = new Map(); const cacheTile = new Cache(); export type GpuBufferAttributes = { @@ -31,11 +34,6 @@ export interface TileBuilderParams { disableSkirt: boolean; /** Whether to render the skirt. */ hideSkirt: boolean; - /** - * Cache-related. - * Tells the function whether to build or skip the index and uv buffers. - */ - buildIndexAndUv_0: boolean; /** Number of segments (edge loops) inside tiles. */ segments: number; // TODO: Move this out of the interface @@ -99,21 +97,27 @@ export function newTileGeometry( // Read previously cached values (index and uv.wgs84 only // depend on the # of triangles) let cachedBuffers = cacheBuffer.get(bufferKey); - params.buildIndexAndUv_0 = !cachedBuffers; + let buffers; try { - buffers = computeBuffers(builder, params); + buffers = computeBuffers(builder, params, + cachedBuffers !== undefined ? { + index: cachedBuffers.index.array as Uint32Array, + uv: cachedBuffers.uv.array as Float32Array, + } : undefined); } catch (e) { return Promise.reject(e); } if (!cachedBuffers) { - cachedBuffers = {}; // We know the fields will exist due to the condition // matching with the one for buildIndexAndUv_0. // TODO: Make this brain-based check compiler-based. - cachedBuffers.index = new THREE.BufferAttribute(buffers.index!, 1); - cachedBuffers.uv = new THREE.BufferAttribute(buffers.uvs[0]!, 2); + + cachedBuffers = { + index: new THREE.BufferAttribute(buffers.index!, 1), + uv: new THREE.BufferAttribute(buffers.uvs[0]!, 2), + }; // Update cacheBuffer cacheBuffer.set(bufferKey, cachedBuffers); diff --git a/src/Core/Prefab/computeBufferTileGeometry.ts b/src/Core/Prefab/computeBufferTileGeometry.ts index 9176aaa064..ff387e0470 100644 --- a/src/Core/Prefab/computeBufferTileGeometry.ts +++ b/src/Core/Prefab/computeBufferTileGeometry.ts @@ -40,20 +40,27 @@ function getUintArrayConstructor( return picked; } +type BufferCache = { + index: Exclude; + uv: Float32Array; +}; + function allocateIndexBuffer( nVertex: number, nSeg: number, params: TileBuilderParams, + cache?: BufferCache['index'], ): Option<{ index: IndexArray, skirt: IndexArray }> { - if (!params.buildIndexAndUv_0) { - return undefined; - } - const indexBufferSize = getBufferIndexSize(nSeg, params.disableSkirt); const indexConstructor = getUintArrayConstructor(nVertex); const tileLen = indexBufferSize; const skirtLen = 4 * nSeg; + + if (cache !== undefined) { + return { index: cache, skirt: cache.subarray(tileLen, tileLen + skirtLen) }; + } + const indexBuffer = new ArrayBuffer(( // Tile tileLen @@ -77,11 +84,12 @@ function allocateBuffers( nSeg: number, builder: TileBuilder, params: TileBuilderParams, + cache?: BufferCache, ): BuffersAndSkirt { const { index, skirt, - } = allocateIndexBuffer(nVertex, nSeg, params) ?? {}; + } = allocateIndexBuffer(nVertex, nSeg, params, cache?.index) ?? {}; return { index, @@ -105,9 +113,7 @@ function allocateBuffers( // * u = wgs84.u // * v = textureid + v in builder texture uvs: [ - params.buildIndexAndUv_0 - ? new Float32Array(nVertex * 2) - : undefined, + cache?.uv ?? new Float32Array(nVertex * 2), builder.computeExtraOffset !== undefined ? new Float32Array(nVertex) : undefined, @@ -132,6 +138,7 @@ type ComputeUvs = export function computeBuffers( builder: TileBuilder, params: TileBuilderParams, + cache?: BufferCache, ): Buffers { // n seg, n+1 vert + <- skirt, n verts per side // <---------------> / | @@ -158,10 +165,11 @@ export function computeBuffers( const outBuffers: BuffersAndSkirt = allocateBuffers( nTotalVertex, nSeg, builder, params, + cache, ); const computeUvs: ComputeUvs = - [params.buildIndexAndUv_0 ? computeUv0 : () => { }]; + [cache === undefined ? computeUv0 : () => { }]; params = builder.prepare(params); @@ -209,7 +217,7 @@ export function computeBuffers( } // Fill skirt index buffer - if (params.buildIndexAndUv_0 && !params.disableSkirt) { + if (cache === undefined && !params.disableSkirt) { for (let x = 0; x < nVertex; x++) { // --------> // 0---1---2 @@ -251,7 +259,7 @@ export function computeBuffers( outBuffers.index![id + 2] = vc; } - if (params.buildIndexAndUv_0) { + if (cache === undefined) { for (let y = 0; y < nSeg; y++) { for (let x = 0; x < nSeg; x++) { const v1 = y * nVertex + (x + 1); @@ -270,7 +278,7 @@ export function computeBuffers( // INFO: The size of the skirt is now a ratio of the size of the tile. // To be perfect it should depend on the real elevation delta but too heavy // to compute - if (params.buildIndexAndUv_0 && !params.disableSkirt) { + if (!params.disableSkirt) { // We compute the actual size of tile segment to use later for // the skirt. const segmentSize = new THREE.Vector3() @@ -278,7 +286,7 @@ export function computeBuffers( .distanceTo(new THREE.Vector3() .fromArray(outBuffers.position, 3)); - const buildSkirt = { + const buildSkirt = cache === undefined ? { index: ( id: number, v1: number, v2: number, v3: number, v4: number, @@ -291,7 +299,7 @@ export function computeBuffers( buf![idTo * 2 + 0] = buf![idFrom * 2 + 0]; buf![idTo * 2 + 1] = buf![idFrom * 2 + 1]; }, - }; + } : { index: () => { }, uv: () => { } }; // Alias for readability const start = nTileVertex;