Skip to content

Commit

Permalink
fix(TileBuilder): pass cache directly to tile gen
Browse files Browse the repository at this point in the history
  • Loading branch information
HoloTheDrunk committed Jan 23, 2025
1 parent f01365d commit a9b5ac8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 25 deletions.
26 changes: 15 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,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);
Expand Down
36 changes: 22 additions & 14 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,
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
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 a9b5ac8

Please sign in to comment.