@hello-terrain/three 0.0.0-alpha.11 → 0.0.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2865 -2152
- package/dist/index.d.cts +478 -215
- package/dist/index.d.mts +478 -215
- package/dist/index.d.ts +478 -215
- package/dist/index.mjs +2857 -2153
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { BufferGeometry,
|
|
1
|
+
import { BufferGeometry, Vector3 as Vector3$1, Ray, Raycaster, Intersection } from 'three';
|
|
2
2
|
import * as three_webgpu from 'three/webgpu';
|
|
3
3
|
import { StorageArrayTexture, StorageTexture, Node, WebGPURenderer, StorageBufferAttribute, StorageBufferNode, UniformNode, Vector3, Vector3Like, InstancedMesh, NodeMaterial, ConstNode } from 'three/webgpu';
|
|
4
4
|
import Node$1 from 'three/src/nodes/core/Node.js';
|
|
5
|
-
import * as three_src_nodes_TSL_js from 'three/src/nodes/TSL.js';
|
|
6
|
-
import { ShaderCallNodeInternal } from 'three/src/nodes/TSL.js';
|
|
7
5
|
import * as _hello_terrain_work from '@hello-terrain/work';
|
|
8
6
|
import { TaskRef, Graph } from '@hello-terrain/work';
|
|
7
|
+
import * as three_src_nodes_TSL_js from 'three/src/nodes/TSL.js';
|
|
8
|
+
import { ShaderCallNodeInternal } from 'three/src/nodes/TSL.js';
|
|
9
9
|
import * as three_tsl from 'three/tsl';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -103,6 +103,100 @@ declare class TerrainGeometry extends BufferGeometry {
|
|
|
103
103
|
private generateNormals;
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
type TerrainFieldStorageBackendType = "array-texture" | "atlas" | "texture-3d";
|
|
107
|
+
type TerrainFieldStorageFormat = "rgba16float" | "rgba32float";
|
|
108
|
+
type TerrainFieldStorageOptions = {
|
|
109
|
+
backend?: TerrainFieldStorageBackendType;
|
|
110
|
+
filter?: "nearest" | "linear";
|
|
111
|
+
format?: TerrainFieldStorageFormat;
|
|
112
|
+
};
|
|
113
|
+
interface TerrainFieldStorage {
|
|
114
|
+
readonly backendType: TerrainFieldStorageBackendType;
|
|
115
|
+
readonly edgeVertexCount: number;
|
|
116
|
+
readonly tileCount: number;
|
|
117
|
+
readonly texture: StorageArrayTexture | StorageTexture;
|
|
118
|
+
uv(ix: Node, iy: Node, tileIndex: Node): Node;
|
|
119
|
+
texel(ix: Node, iy: Node, tileIndex: Node): Node;
|
|
120
|
+
/** UV-based filtered sample. `u, v` in [0, 1] tile-local space. */
|
|
121
|
+
sample(u: Node, v: Node, tileIndex: Node): Node;
|
|
122
|
+
resize(width: number, height: number, tileCount: number): void;
|
|
123
|
+
}
|
|
124
|
+
declare function ArrayTextureBackend(edgeVertexCount: number, tileCount: number, options: Required<Pick<TerrainFieldStorageOptions, "format" | "filter">>): TerrainFieldStorage;
|
|
125
|
+
declare function AtlasBackend(edgeVertexCount: number, tileCount: number, options: Required<Pick<TerrainFieldStorageOptions, "format" | "filter">>): TerrainFieldStorage;
|
|
126
|
+
declare function createTerrainFieldStorage(edgeVertexCount: number, tileCount: number, renderer?: WebGPURenderer, options?: TerrainFieldStorageOptions): TerrainFieldStorage;
|
|
127
|
+
declare function storeTerrainField(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node, value: Node): Node;
|
|
128
|
+
declare function loadTerrainField(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
129
|
+
declare function loadTerrainFieldElevation(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
130
|
+
declare function loadTerrainFieldNormal(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
131
|
+
/**
|
|
132
|
+
* UV-based filtered sample. `u, v` are in [0, 1] tile-local space.
|
|
133
|
+
* Respects the filter mode (nearest / linear) set on the storage.
|
|
134
|
+
*/
|
|
135
|
+
declare function sampleTerrainField(storage: TerrainFieldStorage, u: Node, v: Node, tileIndex: Node): Node;
|
|
136
|
+
declare function sampleTerrainFieldElevation(storage: TerrainFieldStorage, u: Node, v: Node, tileIndex: Node): Node;
|
|
137
|
+
/**
|
|
138
|
+
* Pack a terrain field sample into RGBA: `[height, Nx, Ny, Nz]` where
|
|
139
|
+
* `(Nx, Ny, Nz)` is the unit world-space surface normal. Storing the full
|
|
140
|
+
* world normal (rather than a face-local tangent pair) keeps shading
|
|
141
|
+
* continuous across cube-face seams, since adjacent faces no longer rotate the
|
|
142
|
+
* normal through their own parametric tangent frame.
|
|
143
|
+
*/
|
|
144
|
+
declare function packTerrainFieldSample(height: Node, normal: Node): Node;
|
|
145
|
+
|
|
146
|
+
interface TerrainUniformsParams {
|
|
147
|
+
rootSize: number;
|
|
148
|
+
rootOrigin: Vector3Like;
|
|
149
|
+
innerTileSegments: number;
|
|
150
|
+
skirtScale: number;
|
|
151
|
+
elevationScale: number;
|
|
152
|
+
radius: number;
|
|
153
|
+
instanceId: string;
|
|
154
|
+
}
|
|
155
|
+
interface TerrainUniformsContext {
|
|
156
|
+
uRootOrigin: UniformNode<Vector3>;
|
|
157
|
+
uRootSize: UniformNode<number>;
|
|
158
|
+
uInnerTileSegments: UniformNode<number>;
|
|
159
|
+
uSkirtScale: UniformNode<number>;
|
|
160
|
+
uElevationScale: UniformNode<number>;
|
|
161
|
+
uRadius: UniformNode<number>;
|
|
162
|
+
}
|
|
163
|
+
interface LeafStorageState {
|
|
164
|
+
data: Int32Array<ArrayBuffer>;
|
|
165
|
+
attribute: StorageBufferAttribute;
|
|
166
|
+
node: StorageBufferNode;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Shared (projection-independent) tile-compute helpers. */
|
|
170
|
+
type SharedTileCompute = {
|
|
171
|
+
tileLevel: (nodeIndex: Node) => Node;
|
|
172
|
+
tileFace: (nodeIndex: Node) => Node;
|
|
173
|
+
tileOriginVec2: (nodeIndex: Node) => Node;
|
|
174
|
+
/** Face-local (u, v) in [0, 1] for a grid sample, including skirt border. */
|
|
175
|
+
tileFaceUV: (nodeIndex: Node, ix: Node, iy: Node) => Node;
|
|
176
|
+
};
|
|
177
|
+
/** Projection-specific tile-compute builders. */
|
|
178
|
+
type TileComputeParts = {
|
|
179
|
+
tileSize: (nodeIndex: Node) => Node;
|
|
180
|
+
rootUV: (nodeIndex: Node, ix: Node, iy: Node) => Node;
|
|
181
|
+
tileVertexWorldPosition: (nodeIndex: Node, ix: Node, iy: Node) => Node;
|
|
182
|
+
};
|
|
183
|
+
type TileComputePartsContext = {
|
|
184
|
+
leafStorage: LeafStorageState;
|
|
185
|
+
uniforms: TerrainUniformsContext;
|
|
186
|
+
shared: SharedTileCompute;
|
|
187
|
+
};
|
|
188
|
+
type TileCompute = SharedTileCompute & {
|
|
189
|
+
tileSize: (nodeIndex: Node) => Node;
|
|
190
|
+
rootUVCompute: (nodeIndex: Node, ix: Node, iy: Node) => Node;
|
|
191
|
+
tileVertexWorldPositionCompute: (nodeIndex: Node, ix: Node, iy: Node) => Node;
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Build the per-tile compute helpers, composing projection-independent
|
|
195
|
+
* decoders with the projection-specific position/size/uv builders supplied by
|
|
196
|
+
* `projection.gpu.createTileComputeParts`.
|
|
197
|
+
*/
|
|
198
|
+
declare function createTileCompute(leafStorage: LeafStorageState, uniforms: TerrainUniformsContext, projection: SurfaceProjection): TileCompute;
|
|
199
|
+
|
|
106
200
|
declare const Dir: {
|
|
107
201
|
readonly LEFT: 0;
|
|
108
202
|
readonly RIGHT: 1;
|
|
@@ -128,27 +222,21 @@ type TileBounds = {
|
|
|
128
222
|
/** conservative radius */
|
|
129
223
|
r: number;
|
|
130
224
|
};
|
|
131
|
-
|
|
225
|
+
/** Scaled world-space elevation displacement range for a tile. */
|
|
226
|
+
type ElevationRangeOut = {
|
|
227
|
+
min: number;
|
|
228
|
+
max: number;
|
|
229
|
+
};
|
|
132
230
|
type Topology = {
|
|
133
231
|
spaceCount: number;
|
|
134
232
|
/** maximum number of roots returned by `rootTiles` */
|
|
135
233
|
maxRootCount: number;
|
|
136
234
|
/**
|
|
137
|
-
*
|
|
138
|
-
*
|
|
235
|
+
* Injected surface projection strategy. Encapsulates the GPU position/normal
|
|
236
|
+
* assembly and the CPU query/raycast/LOD behavior for this topology, so the
|
|
237
|
+
* pipeline never branches on a projection kind.
|
|
139
238
|
*/
|
|
140
|
-
projection
|
|
141
|
-
/** Sphere radius in world units (cube-sphere projection only). */
|
|
142
|
-
radius?: number;
|
|
143
|
-
/**
|
|
144
|
-
* Planet center in world space (cube-sphere projection only). Used to apply
|
|
145
|
-
* the camera elevation offset along the radial up-direction during LOD.
|
|
146
|
-
*/
|
|
147
|
-
center?: {
|
|
148
|
-
x: number;
|
|
149
|
-
y: number;
|
|
150
|
-
z: number;
|
|
151
|
-
};
|
|
239
|
+
projection: SurfaceProjection;
|
|
152
240
|
/**
|
|
153
241
|
* Compute the same-level neighbor TileId in the requested direction.
|
|
154
242
|
* Returns false if the neighbor is outside the valid topology.
|
|
@@ -159,12 +247,13 @@ type Topology = {
|
|
|
159
247
|
/**
|
|
160
248
|
* Conservative camera-relative bounds for LOD decisions.
|
|
161
249
|
* Avoids absolute world coordinates so Earth-scale worlds remain stable.
|
|
250
|
+
* When `elevationRange` is provided, bounds should account for displaced geometry.
|
|
162
251
|
*/
|
|
163
252
|
tileBounds(tile: TileId, cameraOrigin: {
|
|
164
253
|
x: number;
|
|
165
254
|
y: number;
|
|
166
255
|
z: number;
|
|
167
|
-
}, out: TileBounds): void;
|
|
256
|
+
}, out: TileBounds, elevationRange?: ElevationRangeOut): void;
|
|
168
257
|
/**
|
|
169
258
|
* Fill root tiles for the current frame and return the count.
|
|
170
259
|
* Implementations should write level-0 tiles into `out[0..count)`.
|
|
@@ -205,37 +294,36 @@ type SeamTable = {
|
|
|
205
294
|
declare function allocSeamTable(capacity: number): SeamTable;
|
|
206
295
|
declare function resetSeamTable(seams: SeamTable): void;
|
|
207
296
|
type LodMode = "distance" | "screen";
|
|
297
|
+
/**
|
|
298
|
+
* How subdivision decisions are made. A discriminated union so each mode only
|
|
299
|
+
* carries (and requires) its own thresholds.
|
|
300
|
+
* - `distance` (default): split when the camera is within `distanceFactor × r`.
|
|
301
|
+
* - `screen`: split when the projected pixel radius exceeds `targetPixels`.
|
|
302
|
+
*/
|
|
303
|
+
type LodCriteria = {
|
|
304
|
+
mode?: "distance";
|
|
305
|
+
distanceFactor?: number;
|
|
306
|
+
} | {
|
|
307
|
+
mode: "screen";
|
|
308
|
+
/** Screen-space projection factor = screenHeight / (2*tan(fovY/2)). */
|
|
309
|
+
projectionFactor: number;
|
|
310
|
+
/** Target pixel radius/size threshold for screen-space refinement. */
|
|
311
|
+
targetPixels: number;
|
|
312
|
+
};
|
|
313
|
+
/**
|
|
314
|
+
* Per-tile elevation range provider: previous-frame world-space displacement
|
|
315
|
+
* min/max (already scaled by `elevationScale`). Returns false when no data is
|
|
316
|
+
* available yet. Allocation-free via the `out` scratch.
|
|
317
|
+
*/
|
|
318
|
+
type TileElevationRangeFn = (tile: TileId, out: ElevationRangeOut) => boolean;
|
|
208
319
|
type UpdateParams = {
|
|
209
320
|
cameraOrigin: {
|
|
210
321
|
x: number;
|
|
211
322
|
y: number;
|
|
212
323
|
z: number;
|
|
213
324
|
};
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
* refinement it offsets the camera toward the terrain surface so LOD distance
|
|
217
|
-
* is measured relative to the surface rather than the datum:
|
|
218
|
-
* - flat: subtracted from `cameraOrigin.y`.
|
|
219
|
-
* - cube-sphere: subtracted along the radial up-direction from the planet center.
|
|
220
|
-
*/
|
|
221
|
-
elevationAtCameraXZ?: number;
|
|
222
|
-
/**
|
|
223
|
-
* Controls how subdivision decisions are made.
|
|
224
|
-
* `distance` is the initial focus; `screen` is supported for future parity.
|
|
225
|
-
*/
|
|
226
|
-
mode?: LodMode;
|
|
227
|
-
/**
|
|
228
|
-
* Distance-based refinement threshold.
|
|
229
|
-
* Interpretation is criteria-dependent; keep it stable across surfaces by using bounds.
|
|
230
|
-
*/
|
|
231
|
-
distanceFactor?: number;
|
|
232
|
-
/** Screen-space projection factor = screenHeight / (2*tan(fovY/2)) */
|
|
233
|
-
projectionFactor?: number;
|
|
234
|
-
/** Target pixel radius/size threshold for screen-space refinement */
|
|
235
|
-
targetPixels?: number;
|
|
236
|
-
/** Prevent flicker by separating split/merge thresholds (0..1 typical) */
|
|
237
|
-
hysteresis?: number;
|
|
238
|
-
};
|
|
325
|
+
tileElevationRange?: TileElevationRangeFn;
|
|
326
|
+
} & LodCriteria;
|
|
239
327
|
type QuadtreeConfig = {
|
|
240
328
|
maxNodes: number;
|
|
241
329
|
maxLevel: number;
|
|
@@ -301,6 +389,7 @@ type QuadtreeState = {
|
|
|
301
389
|
scratchTile: TileId;
|
|
302
390
|
scratchNeighbor: TileId;
|
|
303
391
|
scratchBounds: TileBounds;
|
|
392
|
+
scratchElevationRange: ElevationRangeOut;
|
|
304
393
|
scratchRootTiles: TileId[];
|
|
305
394
|
/** topology space count is fixed for a given state */
|
|
306
395
|
spaceCount: number;
|
|
@@ -334,8 +423,6 @@ type FlatTopologyConfig = {
|
|
|
334
423
|
y: number;
|
|
335
424
|
z: number;
|
|
336
425
|
};
|
|
337
|
-
/** optional conservative vertical extent, included in bounds radius */
|
|
338
|
-
maxHeight?: number;
|
|
339
426
|
};
|
|
340
427
|
declare function createFlatTopology(cfg: FlatTopologyConfig): Topology;
|
|
341
428
|
|
|
@@ -346,8 +433,6 @@ type InfiniteFlatTopologyConfig = {
|
|
|
346
433
|
y: number;
|
|
347
434
|
z: number;
|
|
348
435
|
};
|
|
349
|
-
/** optional conservative vertical extent, included in bounds radius */
|
|
350
|
-
maxHeight?: number;
|
|
351
436
|
/** half-width of root grid in root tiles (1 => 3x3 roots) */
|
|
352
437
|
rootGridRadius?: number;
|
|
353
438
|
};
|
|
@@ -362,8 +447,8 @@ type CubeSphereTopologyConfig = {
|
|
|
362
447
|
y: number;
|
|
363
448
|
z: number;
|
|
364
449
|
};
|
|
365
|
-
/**
|
|
366
|
-
|
|
450
|
+
/** When true, elevation displaces inward and skirts point outward. */
|
|
451
|
+
invert?: boolean;
|
|
367
452
|
};
|
|
368
453
|
/**
|
|
369
454
|
* Cube-sphere topology: six quadtree faces wrapped onto a sphere.
|
|
@@ -401,13 +486,13 @@ type CubeFace = {
|
|
|
401
486
|
declare const CUBE_FACE_COUNT = 6;
|
|
402
487
|
declare const CUBE_FACES: readonly CubeFace[];
|
|
403
488
|
|
|
404
|
-
type Vec3Mutable = [number, number, number];
|
|
489
|
+
type Vec3Mutable$1 = [number, number, number];
|
|
405
490
|
/**
|
|
406
491
|
* Cube-space point for a face-local coordinate (u, v) in [0, 1]:
|
|
407
492
|
* cube = forward + (2u-1) * right + (2v-1) * up
|
|
408
493
|
* The result is unnormalized; normalize it to obtain the sphere direction.
|
|
409
494
|
*/
|
|
410
|
-
declare function faceUVToCube(face: number, u: number, v: number, out: Vec3Mutable): void;
|
|
495
|
+
declare function faceUVToCube(face: number, u: number, v: number, out: Vec3Mutable$1): void;
|
|
411
496
|
/** Pick the cube face whose normal axis dominates the direction. */
|
|
412
497
|
declare function directionToFace(d: Vec3): number;
|
|
413
498
|
/** Face-local (u, v) in [0, 1] for a direction known to fall on `face`. */
|
|
@@ -420,45 +505,258 @@ declare function directionToFaceUV(face: number, d: Vec3, out: [number, number])
|
|
|
420
505
|
* - longitude is the angle around the +Y axis, in `[-180, 180]`,
|
|
421
506
|
* measured from +Z toward +X (lon = 0 points along +Z).
|
|
422
507
|
*/
|
|
423
|
-
declare function latLongToDirection(latDeg: number, lonDeg: number, out: Vec3Mutable): void;
|
|
508
|
+
declare function latLongToDirection(latDeg: number, lonDeg: number, out: Vec3Mutable$1): void;
|
|
424
509
|
/** Inverse of {@link latLongToDirection}; returns degrees. */
|
|
425
510
|
declare function directionToLatLong(d: Vec3): {
|
|
426
511
|
latitude: number;
|
|
427
512
|
longitude: number;
|
|
428
513
|
};
|
|
429
514
|
|
|
430
|
-
type
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
515
|
+
type TorusTopologyConfig = {
|
|
516
|
+
/** Distance from the torus center to the tube center (the donut radius). */
|
|
517
|
+
majorRadius: number;
|
|
518
|
+
/** Radius of the tube cross-section. */
|
|
519
|
+
minorRadius: number;
|
|
520
|
+
/** Torus center in world space (defaults to origin). */
|
|
521
|
+
center?: {
|
|
522
|
+
x: number;
|
|
523
|
+
y: number;
|
|
524
|
+
z: number;
|
|
525
|
+
};
|
|
526
|
+
/** When true, elevation displaces inward and skirts point outward. */
|
|
527
|
+
invert?: boolean;
|
|
436
528
|
};
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
529
|
+
/**
|
|
530
|
+
* Torus (donut) topology: a single quadtree space whose `(u, v)` axes wrap
|
|
531
|
+
* around the major circle and the tube cross-section. Both axes are periodic,
|
|
532
|
+
* so every same-level neighbor exists (wrapping modulo the level resolution).
|
|
533
|
+
*
|
|
534
|
+
* Level-0 resolution is anisotropic: `baseU = round(major/minor)` tiles along
|
|
535
|
+
* `u` and `baseV = 1` along `v`, so root tiles are approximately square in
|
|
536
|
+
* world space before isotropic LOD subdivision.
|
|
537
|
+
*/
|
|
538
|
+
declare function createTorusTopology(cfg: TorusTopologyConfig): Topology;
|
|
539
|
+
|
|
540
|
+
type Vec3Mutable = [number, number, number];
|
|
541
|
+
/** Wrap a value into [0, 1). */
|
|
542
|
+
declare function wrap01(t: number): number;
|
|
543
|
+
/**
|
|
544
|
+
* Torus surface point for parameters (u, v) in [0, 1].
|
|
545
|
+
*
|
|
546
|
+
* Convention (matches `latLongToDirection`'s longitude axis):
|
|
547
|
+
* - `theta = 2*pi*u` sweeps around the +Y axis, measured from +Z toward +X.
|
|
548
|
+
* - `phi = 2*pi*v` sweeps around the tube cross-section, `phi = 0` pointing
|
|
549
|
+
* radially outward in the XZ plane and `phi = pi/2` pointing toward +Y.
|
|
550
|
+
*
|
|
551
|
+
* `displacement` is the elevation added to the tube (minor) radius.
|
|
552
|
+
*/
|
|
553
|
+
declare function torusUVToPoint(u: number, v: number, majorRadius: number, minorRadius: number, displacement: number, center: {
|
|
554
|
+
x: number;
|
|
555
|
+
y: number;
|
|
556
|
+
z: number;
|
|
557
|
+
}, out: Vec3Mutable, invert?: boolean): void;
|
|
558
|
+
/** Outward unit surface normal of the base (undisplaced) torus at (u, v). */
|
|
559
|
+
declare function torusOutwardNormal(u: number, v: number, out: Vec3Mutable, invert?: boolean): void;
|
|
560
|
+
type TorusSurfaceParams = {
|
|
561
|
+
/** Wrapped major-circle parameter in [0, 1). */
|
|
562
|
+
u: number;
|
|
563
|
+
/** Wrapped tube parameter in [0, 1). */
|
|
564
|
+
v: number;
|
|
565
|
+
/** Distance from the point to the tube center circle. */
|
|
566
|
+
tubeDistance: number;
|
|
567
|
+
};
|
|
568
|
+
/**
|
|
569
|
+
* Map a world point to torus surface parameters. `tubeDistance - minorRadius`
|
|
570
|
+
* is the signed radial displacement of the point relative to the base torus.
|
|
571
|
+
*/
|
|
572
|
+
declare function positionToTorusParams(px: number, py: number, pz: number, majorRadius: number, center: {
|
|
573
|
+
x: number;
|
|
574
|
+
y: number;
|
|
575
|
+
z: number;
|
|
576
|
+
}, out: TorusSurfaceParams): void;
|
|
577
|
+
|
|
578
|
+
type TerrainQueryConfig = {
|
|
579
|
+
rootSize: number;
|
|
580
|
+
originX: number;
|
|
581
|
+
originY: number;
|
|
582
|
+
originZ: number;
|
|
583
|
+
innerTileSegments: number;
|
|
584
|
+
elevationScale: number;
|
|
585
|
+
maxLevel: number;
|
|
586
|
+
/** Representative surface radius (curved projections only). */
|
|
587
|
+
radius: number;
|
|
588
|
+
/** Level-0 tile count along u before LOD subdivision (defaults to 1). */
|
|
589
|
+
baseU?: number;
|
|
590
|
+
/** Level-0 tile count along v before LOD subdivision (defaults to 1). */
|
|
591
|
+
baseV?: number;
|
|
592
|
+
};
|
|
593
|
+
interface CpuTerrainCache {
|
|
594
|
+
readonly generation: number;
|
|
595
|
+
readonly ready: boolean;
|
|
596
|
+
updateConfig(config: TerrainQueryConfig): void;
|
|
597
|
+
triggerReadback(renderer: WebGPURenderer, attribute: StorageBufferAttribute, spatialIndex: SpatialIndex, boundsAttribute?: StorageBufferAttribute, activeLeafCount?: number): void;
|
|
598
|
+
/** Release GPU readback staging buffers owned by this cache. */
|
|
599
|
+
dispose(): void;
|
|
600
|
+
getElevation(worldX: number, worldZ: number): number | null;
|
|
601
|
+
getNormal(worldX: number, worldZ: number): Vector3$1 | null;
|
|
602
|
+
getTile(worldX: number, worldZ: number): TerrainTile | null;
|
|
603
|
+
getTileBounds(worldX: number, worldZ: number): TerrainTileBounds | null;
|
|
604
|
+
getGlobalElevationRange(): ElevationRange | null;
|
|
605
|
+
sampleTerrainBatch(positions: Float32Array): TerrainSampleBatch;
|
|
606
|
+
sampleTerrain(worldX: number, worldZ: number): TerrainSample;
|
|
607
|
+
/** True when the active projection supplies surface ops. */
|
|
608
|
+
readonly hasSurface: boolean;
|
|
609
|
+
/**
|
|
610
|
+
* Swap the projection surface ops (CPU position/normal math). Used when the
|
|
611
|
+
* surface geometry changes (e.g. cube-sphere radius/center) without changing
|
|
612
|
+
* the buffer shape, so picks/queries stay in sync without reallocating.
|
|
613
|
+
*/
|
|
614
|
+
setSurfaceOps(surfaceOps: CpuSurfaceOps | null): void;
|
|
615
|
+
sampleSurfaceByPosition(px: number, py: number, pz: number): TerrainSurfaceSample;
|
|
616
|
+
getElevationBySurfacePosition(px: number, py: number, pz: number): number | null;
|
|
617
|
+
getNormalBySurfacePosition(px: number, py: number, pz: number): Vector3$1 | null;
|
|
618
|
+
getTileBySurfacePosition(px: number, py: number, pz: number): TerrainTile | null;
|
|
619
|
+
getTileBoundsBySurfacePosition(px: number, py: number, pz: number): TerrainTileBounds | null;
|
|
620
|
+
sampleSurfaceBatchByPosition(positions: Float32Array): TerrainSurfaceSampleBatch;
|
|
621
|
+
/**
|
|
622
|
+
* Previous-frame raw elevation min/max for a tile (unscaled field values).
|
|
623
|
+
* Returns false when no snapshot data is available for the tile.
|
|
624
|
+
*/
|
|
625
|
+
getTileElevationRange(space: number, level: number, x: number, y: number, out: {
|
|
626
|
+
min: number;
|
|
627
|
+
max: number;
|
|
628
|
+
}): boolean;
|
|
447
629
|
}
|
|
448
|
-
|
|
449
|
-
declare function AtlasBackend(edgeVertexCount: number, tileCount: number, options: Required<Pick<TerrainFieldStorageOptions, "format" | "filter">>): TerrainFieldStorage;
|
|
450
|
-
declare function createTerrainFieldStorage(edgeVertexCount: number, tileCount: number, renderer?: WebGPURenderer, options?: TerrainFieldStorageOptions): TerrainFieldStorage;
|
|
451
|
-
declare function storeTerrainField(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node, value: Node): Node;
|
|
452
|
-
declare function loadTerrainField(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
453
|
-
declare function loadTerrainFieldElevation(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
454
|
-
declare function loadTerrainFieldNormal(storage: TerrainFieldStorage, ix: Node, iy: Node, tileIndex: Node): Node;
|
|
630
|
+
|
|
455
631
|
/**
|
|
456
|
-
*
|
|
457
|
-
*
|
|
632
|
+
* CPU sampling over a snapshot elevation-field buffer laid out as
|
|
633
|
+
* `maxNodes × (edgeVertexCount × edgeVertexCount)` raw heights.
|
|
634
|
+
*
|
|
635
|
+
* Plain-number math only (no three.js, no TSL); callers build vectors at the
|
|
636
|
+
* consumer-facing boundary.
|
|
458
637
|
*/
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
638
|
+
interface ElevationGridShape {
|
|
639
|
+
edgeVertexCount: number;
|
|
640
|
+
verticesPerNode: number;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/** Stable projection identifier — for debugging/telemetry only, never switched on. */
|
|
644
|
+
type ProjectionKind = "flat" | "cubeSphere" | "torus" | (string & {});
|
|
645
|
+
interface Vec3Like {
|
|
646
|
+
x: number;
|
|
647
|
+
y: number;
|
|
648
|
+
z: number;
|
|
649
|
+
}
|
|
650
|
+
interface RenderVertexPositionContext {
|
|
651
|
+
leafStorage: LeafStorageState;
|
|
652
|
+
uniforms: TerrainUniformsContext;
|
|
653
|
+
terrainFieldStorage?: TerrainFieldStorage;
|
|
654
|
+
}
|
|
655
|
+
interface FieldNormalContext {
|
|
656
|
+
elevationFieldNode: Node;
|
|
657
|
+
edgeVertexCount: number;
|
|
658
|
+
tile: TileCompute;
|
|
659
|
+
uniforms: TerrainUniformsContext;
|
|
660
|
+
}
|
|
661
|
+
/** Per-vertex field-stage normal: `(nodeIndex, ix, iy) => unit world normal`. */
|
|
662
|
+
type FieldNormalFn = (nodeIndex: Node, ix: Node, iy: Node) => Node;
|
|
663
|
+
interface SurfaceProjectionGpu {
|
|
664
|
+
/** Render-path world position; also assigns the vertex normal varying. */
|
|
665
|
+
renderVertexPosition(ctx: RenderVertexPositionContext): Node;
|
|
666
|
+
/** Projection-specific compute-stage tile builders (size / uv / position). */
|
|
667
|
+
createTileComputeParts(ctx: TileComputePartsContext): TileComputeParts;
|
|
668
|
+
/** Field-stage surface normal builder. */
|
|
669
|
+
createFieldNormal(ctx: FieldNormalContext): FieldNormalFn;
|
|
670
|
+
/** Optional extra GPU samplers (e.g. sphere ByDirection); no-op for flat. */
|
|
671
|
+
augmentSampler?(sampler: TerrainSampler, params: CreateTerrainSamplerParams): void;
|
|
672
|
+
}
|
|
673
|
+
/** A world point projected onto a closed surface: tile space + face-local uv. */
|
|
674
|
+
interface SurfaceKey {
|
|
675
|
+
/** Tile space/face index (0 for torus, 0..5 for cube-sphere faces). */
|
|
676
|
+
space: number;
|
|
677
|
+
/** Face-local u in [0, 1). */
|
|
678
|
+
u: number;
|
|
679
|
+
/** Face-local v in [0, 1). */
|
|
680
|
+
v: number;
|
|
681
|
+
/** Outward unit direction at the key (for the surface sample `direction`). */
|
|
682
|
+
dirX: number;
|
|
683
|
+
dirY: number;
|
|
684
|
+
dirZ: number;
|
|
685
|
+
}
|
|
686
|
+
/** Grid neighborhood passed to {@link CpuSurfaceOps.surfaceNormal}. */
|
|
687
|
+
interface SurfaceNormalContext {
|
|
688
|
+
elevation: Float32Array;
|
|
689
|
+
shape: ElevationGridShape;
|
|
690
|
+
leafIndex: number;
|
|
691
|
+
/** Fractional grid coords of the sample within the leaf. */
|
|
692
|
+
gx: number;
|
|
693
|
+
gy: number;
|
|
694
|
+
innerTileSegments: number;
|
|
695
|
+
elevationScale: number;
|
|
696
|
+
level: number;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Projection-specific CPU surface math, injected into the terrain cache so the
|
|
700
|
+
* cache stays projection-agnostic. Implementations own their scratch (no
|
|
701
|
+
* module-scope state).
|
|
702
|
+
*/
|
|
703
|
+
interface CpuSurfaceOps {
|
|
704
|
+
/** Map a world position to a surface key; `false` if it has no projection. */
|
|
705
|
+
positionToKey(px: number, py: number, pz: number, out: SurfaceKey): boolean;
|
|
706
|
+
/** Displaced world position from a key + scaled elevation (writes `out`). */
|
|
707
|
+
surfacePosition(key: SurfaceKey, elevation: number, out: Vector3$1): void;
|
|
708
|
+
/** Unit world-space surface normal from a key + grid neighborhood. */
|
|
709
|
+
surfaceNormal(key: SurfaceKey, ctx: SurfaceNormalContext): Vector3$1;
|
|
710
|
+
}
|
|
711
|
+
interface ProjectionRaycastContext {
|
|
712
|
+
ray: Ray;
|
|
713
|
+
options?: RaycastOptions;
|
|
714
|
+
terrainQuery: TerrainQuery | null;
|
|
715
|
+
surfaceQuery: TerrainSurfaceQuery | null;
|
|
716
|
+
sphereQuery: TerrainSphereQuery | null;
|
|
717
|
+
config: TerrainRaycastConfig;
|
|
718
|
+
}
|
|
719
|
+
interface RuntimeQueries {
|
|
720
|
+
query: TerrainQuery;
|
|
721
|
+
/** Generic surface query (position/uv keyed); `null` on flat surfaces. */
|
|
722
|
+
surfaceQuery: TerrainSurfaceQuery | null;
|
|
723
|
+
/** Cube-sphere query (adds direction/lat-long); `null` unless cube-sphere. */
|
|
724
|
+
sphereQuery: TerrainSphereQuery | null;
|
|
725
|
+
}
|
|
726
|
+
interface SurfaceProjectionCpu {
|
|
727
|
+
/**
|
|
728
|
+
* Surface sampling ops injected into the terrain cache; `null` for flat
|
|
729
|
+
* surfaces (which have no closed-surface query).
|
|
730
|
+
*/
|
|
731
|
+
createSurfaceOps(): CpuSurfaceOps | null;
|
|
732
|
+
/** Build the runtime query objects the projection exposes. */
|
|
733
|
+
createRuntimeQueries(cache: CpuTerrainCache): RuntimeQueries;
|
|
734
|
+
/**
|
|
735
|
+
* Projection-specific CPU raycast against the displaced surface. Returns
|
|
736
|
+
* `null` when the ray misses the surface or the query snapshot isn't ready.
|
|
737
|
+
*/
|
|
738
|
+
raycast(ctx: ProjectionRaycastContext): TerrainRaycastResult | null;
|
|
739
|
+
}
|
|
740
|
+
interface SurfaceProjection {
|
|
741
|
+
/** Identifier; never switched on internally. */
|
|
742
|
+
readonly kind: ProjectionKind;
|
|
743
|
+
/** Representative radius (bounds/uniform helper); undefined for flat. */
|
|
744
|
+
readonly radius?: number;
|
|
745
|
+
/** Surface center in world space; undefined for flat. */
|
|
746
|
+
readonly center?: Vec3Like;
|
|
747
|
+
/** Closed surfaces face outward → flip triangle winding. */
|
|
748
|
+
readonly faceOutward: boolean;
|
|
749
|
+
/**
|
|
750
|
+
* Per-axis level-0 tile count before LOD subdivision. Defaults to `{ u: 1, v: 1 }`.
|
|
751
|
+
* At level `L`, resolution is `baseU * 2^L` by `baseV * 2^L` tiles.
|
|
752
|
+
*/
|
|
753
|
+
readonly baseResolution?: {
|
|
754
|
+
u: number;
|
|
755
|
+
v: number;
|
|
756
|
+
};
|
|
757
|
+
gpu: SurfaceProjectionGpu;
|
|
758
|
+
cpu: SurfaceProjectionCpu;
|
|
759
|
+
}
|
|
462
760
|
|
|
463
761
|
interface ElevationParams {
|
|
464
762
|
worldPosition: Node$1;
|
|
@@ -472,29 +770,6 @@ interface ElevationParams {
|
|
|
472
770
|
}
|
|
473
771
|
type ElevationCallback = (params: ElevationParams) => Node$1;
|
|
474
772
|
|
|
475
|
-
interface TerrainUniformsParams {
|
|
476
|
-
rootSize: number;
|
|
477
|
-
rootOrigin: Vector3Like;
|
|
478
|
-
innerTileSegments: number;
|
|
479
|
-
skirtScale: number;
|
|
480
|
-
elevationScale: number;
|
|
481
|
-
radius: number;
|
|
482
|
-
instanceId: string;
|
|
483
|
-
}
|
|
484
|
-
interface TerrainUniformsContext {
|
|
485
|
-
uRootOrigin: UniformNode<Vector3>;
|
|
486
|
-
uRootSize: UniformNode<number>;
|
|
487
|
-
uInnerTileSegments: UniformNode<number>;
|
|
488
|
-
uSkirtScale: UniformNode<number>;
|
|
489
|
-
uElevationScale: UniformNode<number>;
|
|
490
|
-
uRadius: UniformNode<number>;
|
|
491
|
-
}
|
|
492
|
-
interface LeafStorageState {
|
|
493
|
-
data: Int32Array<ArrayBuffer>;
|
|
494
|
-
attribute: StorageBufferAttribute;
|
|
495
|
-
node: StorageBufferNode;
|
|
496
|
-
}
|
|
497
|
-
|
|
498
773
|
interface GpuSpatialIndexContext {
|
|
499
774
|
data: Uint32Array<ArrayBuffer>;
|
|
500
775
|
size: number;
|
|
@@ -524,7 +799,8 @@ interface CreateTerrainSamplerParams {
|
|
|
524
799
|
elevationCallback: ElevationCallback;
|
|
525
800
|
/** Maximum quadtree level to probe during tile lookup. */
|
|
526
801
|
maxLevel: number;
|
|
527
|
-
projection
|
|
802
|
+
/** Active surface projection (drives optional GPU sampler augmentation). */
|
|
803
|
+
projection: SurfaceProjection;
|
|
528
804
|
}
|
|
529
805
|
interface TerrainSample {
|
|
530
806
|
elevation: number;
|
|
@@ -589,31 +865,42 @@ interface TerrainQuery {
|
|
|
589
865
|
readonly generation: number;
|
|
590
866
|
}
|
|
591
867
|
/**
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
596
|
-
*
|
|
868
|
+
* Generic closed-surface terrain query, keyed on a world position projected
|
|
869
|
+
* onto the surface. Exposed for every non-flat projection (cube-sphere, torus,
|
|
870
|
+
* ...); `null` on flat surfaces. Elevation is the displacement above the base
|
|
871
|
+
* surface (already scaled by `elevationScale`); `position` is the full
|
|
872
|
+
* world-space surface point.
|
|
873
|
+
*/
|
|
874
|
+
interface TerrainSurfaceQuery {
|
|
875
|
+
readonly generation: number;
|
|
876
|
+
getElevationByPosition(position: Vector3$1): number | null;
|
|
877
|
+
getNormalByPosition(position: Vector3$1): Vector3$1 | null;
|
|
878
|
+
sampleTerrainByPosition(position: Vector3$1): TerrainSurfaceSample;
|
|
879
|
+
getTileByPosition(position: Vector3$1): TerrainTile | null;
|
|
880
|
+
getTileBoundsByPosition(position: Vector3$1): TerrainTileBounds | null;
|
|
881
|
+
/** Batch sample; `positions` is a Float32Array of xyz triples. */
|
|
882
|
+
sampleTerrainBatchByPosition(positions: Float32Array): TerrainSurfaceSampleBatch;
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* Cube-sphere terrain query. Extends the generic surface query with the
|
|
886
|
+
* sphere-only direction/lat-long keys. A surface location is identified by a
|
|
887
|
+
* direction from the planet center (the canonical form); `ByPosition` projects
|
|
888
|
+
* any world point onto its direction, and `ByLatLong` takes degrees (latitude
|
|
889
|
+
* `[-90, 90]`, longitude `[-180, 180]`).
|
|
597
890
|
*
|
|
598
891
|
* Exposed only when the active surface uses the `cubeSphere` projection
|
|
599
892
|
* (otherwise `null` on the query context / runtime).
|
|
600
893
|
*/
|
|
601
|
-
interface TerrainSphereQuery {
|
|
602
|
-
readonly generation: number;
|
|
894
|
+
interface TerrainSphereQuery extends TerrainSurfaceQuery {
|
|
603
895
|
getElevationByDirection(direction: Vector3$1): number | null;
|
|
604
|
-
getElevationByPosition(position: Vector3$1): number | null;
|
|
605
896
|
getElevationByLatLong(latitudeDeg: number, longitudeDeg: number): number | null;
|
|
606
897
|
getNormalByDirection(direction: Vector3$1): Vector3$1 | null;
|
|
607
|
-
getNormalByPosition(position: Vector3$1): Vector3$1 | null;
|
|
608
898
|
getNormalByLatLong(latitudeDeg: number, longitudeDeg: number): Vector3$1 | null;
|
|
609
899
|
sampleTerrainByDirection(direction: Vector3$1): TerrainSurfaceSample;
|
|
610
|
-
sampleTerrainByPosition(position: Vector3$1): TerrainSurfaceSample;
|
|
611
900
|
sampleTerrainByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainSurfaceSample;
|
|
612
901
|
getTileByDirection(direction: Vector3$1): TerrainTile | null;
|
|
613
|
-
getTileByPosition(position: Vector3$1): TerrainTile | null;
|
|
614
902
|
getTileByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainTile | null;
|
|
615
903
|
getTileBoundsByDirection(direction: Vector3$1): TerrainTileBounds | null;
|
|
616
|
-
getTileBoundsByPosition(position: Vector3$1): TerrainTileBounds | null;
|
|
617
904
|
getTileBoundsByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainTileBounds | null;
|
|
618
905
|
/** Batch sample; `directions` is a Float32Array of xyz triples. */
|
|
619
906
|
sampleTerrainBatchByDirection(directions: Float32Array): TerrainSurfaceSampleBatch;
|
|
@@ -623,6 +910,22 @@ interface RaycastOptions {
|
|
|
623
910
|
refinementSteps?: number;
|
|
624
911
|
maxDistance?: number;
|
|
625
912
|
}
|
|
913
|
+
/**
|
|
914
|
+
* Shared raycast bounds for the CPU marcher. Flat raycasts use the XZ extent +
|
|
915
|
+
* `[minY, maxY]`; curved projections derive their own radial shell from their
|
|
916
|
+
* geometry plus the query's global elevation range, and only read `center*`.
|
|
917
|
+
*/
|
|
918
|
+
interface TerrainRaycastConfig {
|
|
919
|
+
rootSize: number;
|
|
920
|
+
originX: number;
|
|
921
|
+
originY: number;
|
|
922
|
+
originZ: number;
|
|
923
|
+
minY: number;
|
|
924
|
+
maxY: number;
|
|
925
|
+
centerX: number;
|
|
926
|
+
centerY: number;
|
|
927
|
+
centerZ: number;
|
|
928
|
+
}
|
|
626
929
|
interface TerrainRaycastResult {
|
|
627
930
|
position: Vector3$1;
|
|
628
931
|
normal: Vector3$1;
|
|
@@ -707,59 +1010,6 @@ declare function createComputePipelineTasks(leafStageTask: TaskRef<ComputePipeli
|
|
|
707
1010
|
}>;
|
|
708
1011
|
};
|
|
709
1012
|
|
|
710
|
-
declare function createTileCompute(leafStorage: LeafStorageState, uniforms: TerrainUniformsContext, projection?: TopologyProjection): {
|
|
711
|
-
tileLevel: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
712
|
-
tileFace: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
713
|
-
tileOriginVec2: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
714
|
-
tileSize: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node]>;
|
|
715
|
-
tileFaceUV: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node, number | Node, number | Node]>;
|
|
716
|
-
rootUVCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node, number | Node, number | Node]>;
|
|
717
|
-
tileVertexWorldPositionCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | Node, number | Node, number | Node]>;
|
|
718
|
-
};
|
|
719
|
-
|
|
720
|
-
type TerrainQueryConfig = {
|
|
721
|
-
rootSize: number;
|
|
722
|
-
originX: number;
|
|
723
|
-
originY: number;
|
|
724
|
-
originZ: number;
|
|
725
|
-
innerTileSegments: number;
|
|
726
|
-
elevationScale: number;
|
|
727
|
-
maxLevel: number;
|
|
728
|
-
/** Topology projection; `cubeSphere` enables the direction/lat-long queries. */
|
|
729
|
-
projection: TopologyProjection;
|
|
730
|
-
/** Sphere radius in world units (cube-sphere projection only). */
|
|
731
|
-
radius: number;
|
|
732
|
-
};
|
|
733
|
-
interface CpuTerrainCache {
|
|
734
|
-
readonly generation: number;
|
|
735
|
-
readonly ready: boolean;
|
|
736
|
-
updateConfig(config: TerrainQueryConfig): void;
|
|
737
|
-
triggerReadback(renderer: WebGPURenderer, attribute: StorageBufferAttribute, spatialIndex: SpatialIndex, boundsAttribute?: StorageBufferAttribute, activeLeafCount?: number): void;
|
|
738
|
-
getElevation(worldX: number, worldZ: number): number | null;
|
|
739
|
-
getNormal(worldX: number, worldZ: number): Vector3$1 | null;
|
|
740
|
-
getTile(worldX: number, worldZ: number): TerrainTile | null;
|
|
741
|
-
getTileBounds(worldX: number, worldZ: number): TerrainTileBounds | null;
|
|
742
|
-
getGlobalElevationRange(): ElevationRange | null;
|
|
743
|
-
sampleTerrainBatch(positions: Float32Array): TerrainSampleBatch;
|
|
744
|
-
sampleTerrain(worldX: number, worldZ: number): TerrainSample;
|
|
745
|
-
getElevationByDirection(direction: Vector3$1): number | null;
|
|
746
|
-
getElevationByPosition(position: Vector3$1): number | null;
|
|
747
|
-
getElevationByLatLong(latitudeDeg: number, longitudeDeg: number): number | null;
|
|
748
|
-
getNormalByDirection(direction: Vector3$1): Vector3$1 | null;
|
|
749
|
-
getNormalByPosition(position: Vector3$1): Vector3$1 | null;
|
|
750
|
-
getNormalByLatLong(latitudeDeg: number, longitudeDeg: number): Vector3$1 | null;
|
|
751
|
-
sampleTerrainByDirection(direction: Vector3$1): TerrainSurfaceSample;
|
|
752
|
-
sampleTerrainByPosition(position: Vector3$1): TerrainSurfaceSample;
|
|
753
|
-
sampleTerrainByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainSurfaceSample;
|
|
754
|
-
getTileByDirection(direction: Vector3$1): TerrainTile | null;
|
|
755
|
-
getTileByPosition(position: Vector3$1): TerrainTile | null;
|
|
756
|
-
getTileByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainTile | null;
|
|
757
|
-
getTileBoundsByDirection(direction: Vector3$1): TerrainTileBounds | null;
|
|
758
|
-
getTileBoundsByPosition(position: Vector3$1): TerrainTileBounds | null;
|
|
759
|
-
getTileBoundsByLatLong(latitudeDeg: number, longitudeDeg: number): TerrainTileBounds | null;
|
|
760
|
-
sampleTerrainBatchByDirection(directions: Float32Array): TerrainSurfaceSampleBatch;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
1013
|
interface QuadtreeConfigState {
|
|
764
1014
|
state: QuadtreeState;
|
|
765
1015
|
topology: Topology;
|
|
@@ -775,9 +1025,18 @@ interface ElevationFieldContext {
|
|
|
775
1025
|
interface TerrainQueryContext {
|
|
776
1026
|
cache: CpuTerrainCache;
|
|
777
1027
|
query: TerrainQuery;
|
|
1028
|
+
/** Generic closed-surface query; `null` on flat surfaces. */
|
|
1029
|
+
surfaceQuery: TerrainSurfaceQuery | null;
|
|
778
1030
|
/** Cube-sphere query; `null` unless the topology uses the cubeSphere projection. */
|
|
779
1031
|
sphereQuery: TerrainSphereQuery | null;
|
|
1032
|
+
/** Buffer-shape identity (maxNodes/segments/projection kind); change recreates the cache. */
|
|
780
1033
|
shapeKey: string;
|
|
1034
|
+
/**
|
|
1035
|
+
* The projection these queries close over. Recreated on any geometry change
|
|
1036
|
+
* (e.g. cube-sphere radius, torus major/minor); an identity change rebuilds
|
|
1037
|
+
* the surface ops + queries so picks/markers stay in sync.
|
|
1038
|
+
*/
|
|
1039
|
+
projection: SurfaceProjection;
|
|
781
1040
|
}
|
|
782
1041
|
/** Task refs for the standard terrain pipeline. */
|
|
783
1042
|
interface TerrainTasks {
|
|
@@ -819,15 +1078,7 @@ declare const createElevationFieldContextTask: _hello_terrain_work.Task<{
|
|
|
819
1078
|
attribute: StorageBufferAttribute;
|
|
820
1079
|
node: three_webgpu.StorageBufferNode;
|
|
821
1080
|
}, string, unknown>;
|
|
822
|
-
declare const tileNodesTask: _hello_terrain_work.Task<
|
|
823
|
-
tileLevel: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
824
|
-
tileFace: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
825
|
-
tileOriginVec2: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
826
|
-
tileSize: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
827
|
-
tileFaceUV: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
828
|
-
rootUVCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
829
|
-
tileVertexWorldPositionCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
830
|
-
}, string, unknown>;
|
|
1081
|
+
declare const tileNodesTask: _hello_terrain_work.Task<TileCompute, string, unknown>;
|
|
831
1082
|
/**
|
|
832
1083
|
* Root compute stage — generates elevation data and writes to the
|
|
833
1084
|
* elevation field storage buffer. Returns a single-element `ComputePipeline`.
|
|
@@ -908,7 +1159,7 @@ declare const elevationFn: _hello_terrain_work.ParamRef<ElevationCallback>;
|
|
|
908
1159
|
* (e.g. buffer resize), so this task stays cached during normal quadtree
|
|
909
1160
|
* updates — no unnecessary shader rebuilds.
|
|
910
1161
|
*/
|
|
911
|
-
declare const positionNodeTask: _hello_terrain_work.Task<
|
|
1162
|
+
declare const positionNodeTask: _hello_terrain_work.Task<three_webgpu.Node, string, unknown>;
|
|
912
1163
|
|
|
913
1164
|
/**
|
|
914
1165
|
* Derives the terrain topology from `rootSize` and `origin`.
|
|
@@ -964,21 +1215,13 @@ declare const terrainTasks: {
|
|
|
964
1215
|
readonly gpuSpatialIndexUpload: _hello_terrain_work.Task<GpuSpatialIndexContext, string, unknown>;
|
|
965
1216
|
readonly createUniforms: _hello_terrain_work.Task<TerrainUniformsContext, string, unknown>;
|
|
966
1217
|
readonly updateUniforms: _hello_terrain_work.Task<TerrainUniformsContext, string, unknown>;
|
|
967
|
-
readonly positionNode: _hello_terrain_work.Task<
|
|
1218
|
+
readonly positionNode: _hello_terrain_work.Task<three_webgpu.Node, string, unknown>;
|
|
968
1219
|
readonly createElevationFieldContext: _hello_terrain_work.Task<{
|
|
969
1220
|
data: Float32Array<ArrayBuffer>;
|
|
970
1221
|
attribute: three_webgpu.StorageBufferAttribute;
|
|
971
1222
|
node: three_webgpu.StorageBufferNode;
|
|
972
1223
|
}, string, unknown>;
|
|
973
|
-
readonly createTileNodes: _hello_terrain_work.Task<
|
|
974
|
-
tileLevel: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
975
|
-
tileFace: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
976
|
-
tileOriginVec2: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
977
|
-
tileSize: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node]>;
|
|
978
|
-
tileFaceUV: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
979
|
-
rootUVCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
980
|
-
tileVertexWorldPositionCompute: three_src_nodes_TSL_js.ShaderNodeFn<[number | three_webgpu.Node, number | three_webgpu.Node, number | three_webgpu.Node]>;
|
|
981
|
-
}, string, unknown>;
|
|
1224
|
+
readonly createTileNodes: _hello_terrain_work.Task<TileCompute, string, unknown>;
|
|
982
1225
|
readonly createTerrainFieldTexture: _hello_terrain_work.Task<any, string, {
|
|
983
1226
|
renderer: WebGPURenderer;
|
|
984
1227
|
}>;
|
|
@@ -992,7 +1235,7 @@ declare const terrainTasks: {
|
|
|
992
1235
|
renderer: WebGPURenderer;
|
|
993
1236
|
}>;
|
|
994
1237
|
readonly tileBoundsContext: _hello_terrain_work.Task<TileBoundsContext & {
|
|
995
|
-
kernel: ReturnType<(elevationFieldNode: three_webgpu.StorageBufferNode, boundsNode: three_webgpu.StorageBufferNode, verticesPerNode: number) => three_webgpu.ComputeNode>;
|
|
1238
|
+
kernel: ReturnType<(elevationFieldNode: three_webgpu.StorageBufferNode, boundsNode: three_webgpu.StorageBufferNode, verticesPerNode: number, edgeVertexCount: number) => three_webgpu.ComputeNode>;
|
|
996
1239
|
}, string, unknown>;
|
|
997
1240
|
readonly tileBoundsReduction: _hello_terrain_work.Task<any, string, {
|
|
998
1241
|
renderer: WebGPURenderer;
|
|
@@ -1012,35 +1255,29 @@ type ComputeDeviceLimits = {
|
|
|
1012
1255
|
};
|
|
1013
1256
|
declare function getDeviceComputeLimits(renderer: WebGPURenderer): ComputeDeviceLimits;
|
|
1014
1257
|
|
|
1258
|
+
/**
|
|
1259
|
+
* Add the cube-sphere direction samplers to a base sampler. Called from the
|
|
1260
|
+
* cube-sphere projection's `gpu.augmentSampler` hook.
|
|
1261
|
+
*/
|
|
1262
|
+
declare function augmentCubeSphereSampler(sampler: TerrainSampler, params: CreateTerrainSamplerParams): void;
|
|
1015
1263
|
declare function createTerrainSampler(params: CreateTerrainSamplerParams): TerrainSampler;
|
|
1016
1264
|
|
|
1017
1265
|
/** Flat (heightfield) query, keyed on world XZ. */
|
|
1018
1266
|
declare function createTerrainQuery(cache: CpuTerrainCache): TerrainQuery;
|
|
1019
|
-
/**
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
originX: number;
|
|
1025
|
-
originZ: number;
|
|
1026
|
-
minY: number;
|
|
1027
|
-
maxY: number;
|
|
1028
|
-
/** Topology projection; `cubeSphere` selects the radial sphere raycast. */
|
|
1029
|
-
projection?: TopologyProjection;
|
|
1030
|
-
/** Planet center (cube-sphere only). */
|
|
1031
|
-
centerX?: number;
|
|
1032
|
-
centerY?: number;
|
|
1033
|
-
centerZ?: number;
|
|
1034
|
-
/** Base sphere radius (cube-sphere only). */
|
|
1035
|
-
radius?: number;
|
|
1036
|
-
/** Inner/outer radial bounds of the terrain shell (cube-sphere only). */
|
|
1037
|
-
minRadius?: number;
|
|
1038
|
-
maxRadius?: number;
|
|
1039
|
-
};
|
|
1267
|
+
/**
|
|
1268
|
+
* Generic closed-surface query, keyed on a world position projected onto the
|
|
1269
|
+
* surface. Cube-sphere extends this with direction/lat-long keys.
|
|
1270
|
+
*/
|
|
1271
|
+
declare function createTerrainSurfaceQuery(cache: CpuTerrainCache): TerrainSurfaceQuery;
|
|
1040
1272
|
|
|
1041
|
-
|
|
1273
|
+
/**
|
|
1274
|
+
* Build a terrain raycaster that delegates the projection-specific marching to
|
|
1275
|
+
* the active surface projection — no branching on a projection kind here.
|
|
1276
|
+
*/
|
|
1042
1277
|
declare function createTerrainRaycast(params: {
|
|
1278
|
+
getProjection: () => SurfaceProjection;
|
|
1043
1279
|
getTerrainQuery: () => TerrainQuery | null;
|
|
1280
|
+
getSurfaceQuery: () => TerrainSurfaceQuery | null;
|
|
1044
1281
|
getSphereQuery: () => TerrainSphereQuery | null;
|
|
1045
1282
|
getConfig: () => TerrainRaycastConfig;
|
|
1046
1283
|
}): TerrainRaycast;
|
|
@@ -1159,5 +1396,31 @@ declare const voronoiCells: three_src_nodes_TSL_js.ShaderNodeFn<[three_tsl.Proxi
|
|
|
1159
1396
|
uv: Node;
|
|
1160
1397
|
}>]>;
|
|
1161
1398
|
|
|
1162
|
-
|
|
1163
|
-
|
|
1399
|
+
/** Flat heightfield projection: tiles in the XZ plane, elevation along +Y. */
|
|
1400
|
+
declare function createFlatProjection(): SurfaceProjection;
|
|
1401
|
+
|
|
1402
|
+
interface CubeSphereProjectionConfig {
|
|
1403
|
+
radius: number;
|
|
1404
|
+
center?: Vec3Like;
|
|
1405
|
+
/** When true, elevation displaces inward and skirts point outward. */
|
|
1406
|
+
invert?: boolean;
|
|
1407
|
+
}
|
|
1408
|
+
/** Cube-sphere projection: six faces wrapped radially onto a sphere. */
|
|
1409
|
+
declare function createCubeSphereProjection(config: CubeSphereProjectionConfig): SurfaceProjection;
|
|
1410
|
+
|
|
1411
|
+
interface TorusProjectionConfig {
|
|
1412
|
+
majorRadius: number;
|
|
1413
|
+
minorRadius: number;
|
|
1414
|
+
center?: Vec3Like;
|
|
1415
|
+
/** When true, elevation displaces inward and skirts point outward. */
|
|
1416
|
+
invert?: boolean;
|
|
1417
|
+
/** Level-0 tile count along u before LOD subdivision (defaults to 1). */
|
|
1418
|
+
baseU?: number;
|
|
1419
|
+
/** Level-0 tile count along v before LOD subdivision (defaults to 1). */
|
|
1420
|
+
baseV?: number;
|
|
1421
|
+
}
|
|
1422
|
+
/** Torus (donut) projection: a single closed surface periodic in both axes. */
|
|
1423
|
+
declare function createTorusProjection(config: TorusProjectionConfig): SurfaceProjection;
|
|
1424
|
+
|
|
1425
|
+
export { ArrayTextureBackend, AtlasBackend, CUBE_FACES, CUBE_FACE_COUNT, Dir, TerrainGeometry, TerrainMesh, U32_EMPTY, allocLeafSet, allocSeamTable, augmentCubeSphereSampler, beginUpdate, blendAngleCorrectedNormals, buildLeafIndex, buildSeams2to1, compileComputeTask, createComputePipelineTasks, createCubeSphereProjection, createCubeSphereTopology, createElevationFieldContextTask, createFlatProjection, createFlatTopology, createInfiniteFlatTopology, createSpatialIndex, createState, createTerrainFieldStorage, createTerrainFieldTextureTask, createTerrainQuery, createTerrainRaycast, createTerrainSampler, createTerrainSamplerTask, createTerrainSurfaceQuery, createTerrainUniforms, createTorusProjection, createTorusTopology, createUniformsTask, cubeFaceBasis, cubeFaceDirection, cubeFaceFromDirection, cubeFacePoint, cubeFaceUVFromDirection, deriveNormalZ, directionToFace, directionToFaceUV, directionToLatLong, elevationFieldStageTask, elevationFn, elevationScale, executeComputeTask, faceUVToCube, getDeviceComputeLimits, gpuSpatialIndexStorageTask, gpuSpatialIndexUploadTask, innerTileSegments, instanceIdTask, isSkirtUV, isSkirtVertex, latLongToDirection, leafGpuBufferTask, leafStorageTask, loadTerrainField, loadTerrainFieldElevation, loadTerrainFieldNormal, maxLevel, maxNodes, origin, packTerrainFieldSample, positionNodeTask, positionToTorusParams, quadtreeConfigTask, quadtreeUpdate, quadtreeUpdateTask, radius, resetLeafSet, resetSeamTable, rootSize, sampleTerrainField, sampleTerrainFieldElevation, skirtScale, sphereTangentFrameNormal, storeTerrainField, tangentFromAxis, terrainFieldFilter, terrainFieldStageTask, terrainGraph, terrainQueryTask, terrainRaycastTask, terrainReadbackTask, terrainTasks, textureSpaceToVectorSpace, tileNodesTask, topology, topologyTask, torusOutwardNormal, torusUVToPoint, unpackTangentNormal, update, updateUniformsTask, vElevation, vGlobalVertexIndex, vectorSpaceToTextureSpace, voronoiCells, wrap01 };
|
|
1426
|
+
export type { ComputePipeline, ComputeStageCallback, CpuSurfaceOps, CreateTerrainSamplerParams, CubeFace, CubeFaceBasis, CubeSphereProjectionConfig, CubeSphereTopologyConfig, ElevationCallback, ElevationFieldContext, ElevationParams, ElevationRange, ElevationRangeOut, FieldNormalContext, FieldNormalFn, FlatTopologyConfig, GpuSpatialIndexContext, InfiniteFlatTopologyConfig, IntNodeInput, LeafGpuBufferState, LeafSet, LeafStorageState, LodCriteria, LodMode, ProjectionKind, ProjectionRaycastContext, QuadtreeConfig, QuadtreeConfigState, QuadtreeState, RaycastOptions, RenderVertexPositionContext, RuntimeQueries, SeamTable, SpatialIndex, SurfaceKey, SurfaceNormalContext, SurfaceProjection, SurfaceProjectionCpu, SurfaceProjectionGpu, TerrainFieldStorage, TerrainFieldStorageBackendType, TerrainFieldStorageFormat, TerrainFieldStorageOptions, TerrainGraph, TerrainQuery, TerrainQueryContext, TerrainRaycast, TerrainRaycastConfig, TerrainRaycastResult, TerrainSample, TerrainSampleBatch, TerrainSampler, TerrainSphereQuery, TerrainSurfaceQuery, TerrainSurfaceSample, TerrainSurfaceSampleBatch, TerrainTasks, TerrainTile, TerrainTileBounds, TerrainUniformsContext, TerrainUniformsParams, TileBounds, TileElevationRangeFn, TileId, Topology, TorusProjectionConfig, TorusSurfaceParams, TorusTopologyConfig, UpdateParams, Vec3, Vec3Like, Vec3Mutable$1 as Vec3Mutable };
|