Skip to content

Commit

Permalink
fix(TileBuilder): use cached buffers correctly (#2491)
Browse files Browse the repository at this point in the history
Fixes skirt rendering from cache and cleans up one of the magic booleans in tile generation.

Squashed commit history (older first):
 - fix(TileBuilder): pass cache directly to tile gen
 - fix: remove unnecessary optional
 - fix(TileBuilder): add type hint to index cache
  • Loading branch information
HoloTheDrunk authored Jan 24, 2025
1 parent f01365d commit f3d2e90
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 26 deletions.
32 changes: 21 additions & 11 deletions src/Core/Prefab/TileBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, { [buf: string]: THREE.BufferAttribute }>();
const cacheBuffer = new Map<string, {
index: THREE.BufferAttribute,
uv: THREE.BufferAttribute,
}>();
const cacheTile = new Cache();

export type GpuBufferAttributes = {
Expand All @@ -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
Expand Down Expand Up @@ -99,21 +97,33 @@ 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
Uint8Array | Uint16Array | 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);
Expand Down
38 changes: 23 additions & 15 deletions src/Core/Prefab/computeBufferTileGeometry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,27 @@ function getUintArrayConstructor(
return picked;
}

type BufferCache = {
index: Exclude<IndexArray, undefined>;
uv: Float32Array;
};

function allocateIndexBuffer(
nVertex: number,
nSeg: number,
params: TileBuilderParams,
): Option<{ index: IndexArray, skirt: IndexArray }> {
if (!params.buildIndexAndUv_0) {
return undefined;
}

cache?: BufferCache['index'],
): { index: IndexArray, skirt: IndexArray } {
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
Expand All @@ -77,11 +84,12 @@ function allocateBuffers(
nSeg: number,
builder: TileBuilder<TileBuilderParams>,
params: TileBuilderParams,
cache?: BufferCache,
): BuffersAndSkirt {
const {
index,
skirt,
} = allocateIndexBuffer(nVertex, nSeg, params) ?? {};
} = allocateIndexBuffer(nVertex, nSeg, params, cache?.index);

return {
index,
Expand All @@ -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,
Expand All @@ -132,6 +138,7 @@ type ComputeUvs =
export function computeBuffers(
builder: TileBuilder<TileBuilderParams>,
params: TileBuilderParams,
cache?: BufferCache,
): Buffers {
// n seg, n+1 vert + <- skirt, n verts per side
// <---------------> / |
Expand All @@ -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);

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -270,15 +278,15 @@ 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()
.fromArray(outBuffers.position)
.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,
Expand All @@ -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;
Expand Down

0 comments on commit f3d2e90

Please sign in to comment.