@hello-terrain/three 0.0.0-alpha.1 → 0.0.0-alpha.2

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.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as THREE from 'three';
1
2
  import { BufferGeometry } from 'three';
2
3
  import * as three_src_nodes_TSL_js from 'three/src/nodes/TSL.js';
3
4
  import { Node } from 'three/webgpu';
@@ -113,4 +114,261 @@ declare const isSkirtVertex: three_src_nodes_TSL_js.ShaderNodeFn<[segments: numb
113
114
  */
114
115
  declare const isSkirtUV: three_src_nodes_TSL_js.ShaderNodeFn<[segments: number | Node]>;
115
116
 
116
- export { TerrainGeometry, isSkirtUV, isSkirtVertex };
117
+ type NeighborIndices = [number, number, number, number];
118
+ type ChildIndices = [number, number, number, number];
119
+ /**
120
+ * Class that manages all node-related buffer arrays and provides access methods
121
+ */
122
+ declare class QuadtreeNodeView {
123
+ private maxNodeCount;
124
+ private childrenIndicesBuffer;
125
+ private neighborsIndicesBuffer;
126
+ private nodeBuffer;
127
+ private leafNodeMask;
128
+ private leafNodeCountBuffer;
129
+ private activeLeafIndices;
130
+ private activeLeafCount;
131
+ constructor(maxNodeCount: number, childrenIndicesBuffer?: Uint16Array, neighborsIndicesBuffer?: Uint16Array, nodeBuffer?: Int32Array, leafNodeMask?: Uint8Array, leafNodeCountBuffer?: Uint16Array);
132
+ /**
133
+ * Clear all buffers
134
+ */
135
+ clear(): void;
136
+ /**
137
+ * Get buffer references for direct access (useful for GPU operations)
138
+ */
139
+ getBuffers(): {
140
+ childrenIndicesBuffer: Uint16Array<ArrayBufferLike>;
141
+ neighborsIndicesBuffer: Uint16Array<ArrayBufferLike>;
142
+ nodeBuffer: Int32Array<ArrayBufferLike>;
143
+ leafNodeMask: Uint8Array<ArrayBufferLike>;
144
+ };
145
+ /**
146
+ * Get the maximum node count
147
+ */
148
+ getMaxNodeCount(): number;
149
+ getLevel(index: number): number;
150
+ getX(index: number): number;
151
+ getY(index: number): number;
152
+ getLeafNodeCount(): number;
153
+ getLeaf(index: number): boolean;
154
+ getChildren(index: number): ChildIndices;
155
+ getNeighbors(index: number): NeighborIndices;
156
+ setLevel(index: number, level: number): void;
157
+ setX(index: number, x: number): void;
158
+ setY(index: number, y: number): void;
159
+ setLeaf(index: number, leaf: boolean): void;
160
+ setChildren(index: number, children: ChildIndices): void;
161
+ setNeighbors(index: number, neighbors: NeighborIndices): void;
162
+ /**
163
+ * Get array of active leaf node indices with count (zero-copy, no allocation)
164
+ */
165
+ getActiveLeafNodeIndices(): {
166
+ indices: Uint16Array;
167
+ count: number;
168
+ };
169
+ /**
170
+ * Release internal buffers and mark this view as destroyed
171
+ */
172
+ destroy(): void;
173
+ clone(): QuadtreeNodeView;
174
+ }
175
+
176
+ /**
177
+ * Context passed to subdivision strategy functions.
178
+ * Contains all information needed to make subdivision decisions.
179
+ */
180
+ interface SubdivisionContext {
181
+ /** Current node's quadtree level (0 = root) */
182
+ level: number;
183
+ /** Distance from camera/position to node center in world units */
184
+ distance: number;
185
+ /** World-space size of the node (edge length) */
186
+ nodeSize: number;
187
+ /** Minimum allowed node size from config */
188
+ minNodeSize: number;
189
+ /** Root terrain size from config */
190
+ rootSize: number;
191
+ }
192
+ /**
193
+ * Function type for subdivision strategies.
194
+ * Returns true if the node should be subdivided, false otherwise.
195
+ */
196
+ type SubdivisionStrategy = (context: SubdivisionContext) => boolean;
197
+ /**
198
+ * Screen-space projection info for LOD calculations.
199
+ * Computed from camera properties each frame.
200
+ */
201
+ interface ScreenSpaceInfo {
202
+ /**
203
+ * Projection factor: screenHeight / (2 * tan(fovY / 2))
204
+ * This converts world-space size to screen-space pixels at distance 1.
205
+ */
206
+ projectionFactor: number;
207
+ /**
208
+ * Screen height in pixels (for reference/debugging)
209
+ */
210
+ screenHeight: number;
211
+ }
212
+ /**
213
+ * Distance-based subdivision strategy with hysteresis to prevent LOD flickering.
214
+ * Subdivides when: distance < nodeSize * factor
215
+ *
216
+ * @param factor Multiplier for subdivision threshold (default: 2)
217
+ * @returns SubdivisionStrategy function
218
+ */
219
+ declare function distanceBasedSubdivision(factor?: number): SubdivisionStrategy;
220
+ /**
221
+ * Screen-space subdivision strategy.
222
+ * Subdivides based on projected triangle size in pixels.
223
+ * Ensures triangles don't exceed a target pixel size on screen.
224
+ *
225
+ * @param options Configuration for screen-space subdivision
226
+ * @returns SubdivisionStrategy function
227
+ */
228
+ declare function screenSpaceSubdivision(options: {
229
+ /**
230
+ * Target triangle size in screen pixels.
231
+ * Subdivide when triangles would be larger than this.
232
+ * Recommended: 4-8 pixels
233
+ * @default 6
234
+ */
235
+ targetTrianglePixels?: number;
236
+ /**
237
+ * Number of segments per tile edge.
238
+ * Should match TerrainMesh.innerTileSegments.
239
+ * @default 13
240
+ */
241
+ tileSegments?: number;
242
+ /**
243
+ * Function that returns current screen-space projection info.
244
+ * Called each time subdivision is evaluated.
245
+ */
246
+ getScreenSpaceInfo: () => ScreenSpaceInfo | null;
247
+ }): SubdivisionStrategy;
248
+ /**
249
+ * Compute screen-space info from camera parameters.
250
+ * Helper function to create ScreenSpaceInfo from typical Three.js camera values.
251
+ *
252
+ * @param fovY Vertical field of view in radians
253
+ * @param screenHeight Screen height in pixels
254
+ * @returns ScreenSpaceInfo for use with screenSpaceSubdivision
255
+ *
256
+ * @example
257
+ * ```ts
258
+ * // In your render loop:
259
+ * const fovRadians = camera.fov * Math.PI / 180;
260
+ * const screenInfo = computeScreenSpaceInfo(fovRadians, renderer.domElement.height);
261
+ * ```
262
+ */
263
+ declare function computeScreenSpaceInfo(fovY: number, screenHeight: number): ScreenSpaceInfo;
264
+
265
+ interface QuadtreeParams {
266
+ maxLevel: number;
267
+ rootSize: number;
268
+ minNodeSize: number;
269
+ origin: THREE.Vector3;
270
+ maxNodes: number;
271
+ }
272
+ declare class Quadtree {
273
+ private nodeCount;
274
+ private deepestLevel;
275
+ private config;
276
+ private nodeView;
277
+ private subdivisionStrategy;
278
+ private tempChildIndices;
279
+ private tempNeighborIndices;
280
+ /**
281
+ * Create a new Quadtree.
282
+ *
283
+ * @param config Quadtree configuration parameters
284
+ * @param subdivisionStrategy Strategy function for subdivision decisions.
285
+ * Defaults to distanceBasedSubdivision(2).
286
+ * @param nodeView Optional pre-allocated NodeView for buffer reuse
287
+ */
288
+ constructor(config: QuadtreeParams, subdivisionStrategy?: SubdivisionStrategy, nodeView?: QuadtreeNodeView);
289
+ /**
290
+ * Set the subdivision strategy.
291
+ * Use this to change LOD behavior at runtime.
292
+ *
293
+ * @param strategy The subdivision strategy function
294
+ */
295
+ setSubdivisionStrategy(strategy: SubdivisionStrategy): void;
296
+ /**
297
+ * Get the current subdivision strategy
298
+ */
299
+ getSubdivisionStrategy(): SubdivisionStrategy;
300
+ private initialize;
301
+ /**
302
+ * Update the quadtree based on the given position and return the index
303
+ * of the leaf node that best corresponds to the position (closest leaf).
304
+ */
305
+ update(position: THREE.Vector3, frustum?: THREE.Frustum): number;
306
+ /**
307
+ * Recursively update a node and its children based on distance and size criteria
308
+ * and return the closest leaf node index to the provided position.
309
+ */
310
+ private updateNode;
311
+ /**
312
+ * Determine if a node should be subdivided using the configured strategy
313
+ */
314
+ private shouldSubdivide;
315
+ /**
316
+ * Create a new node and return its index
317
+ */
318
+ private createNode;
319
+ /**
320
+ * Subdivide a node by creating its four children
321
+ */
322
+ private subdivideNode;
323
+ /**
324
+ * Update neighbor relationships for child nodes
325
+ */
326
+ private updateChildNeighbors;
327
+ /**
328
+ * Get the deepest subdivision level currently in the quadtree
329
+ */
330
+ getDeepestLevel(): number;
331
+ /**
332
+ * Get the total number of nodes
333
+ */
334
+ getNodeCount(): number;
335
+ getLeafNodeCount(): number;
336
+ /**
337
+ * Get active leaf node indices for efficient GPU processing
338
+ */
339
+ getActiveLeafNodeIndices(): {
340
+ indices: Uint16Array;
341
+ count: number;
342
+ };
343
+ /**
344
+ * Get the configuration
345
+ */
346
+ getConfig(): QuadtreeParams;
347
+ /**
348
+ * Get all leaf nodes as an array of node objects
349
+ */
350
+ getLeafNodes(): Array<{
351
+ level: number;
352
+ x: number;
353
+ y: number;
354
+ }>;
355
+ /**
356
+ * Reset the quadtree
357
+ */
358
+ reset(): void;
359
+ /**
360
+ * Get the NodeView instance for direct access
361
+ */
362
+ getNodeView(): QuadtreeNodeView;
363
+ /**
364
+ * Release internal resources associated with this quadtree
365
+ */
366
+ destroy(): void;
367
+ /**
368
+ * Set the configuration
369
+ */
370
+ setConfig(config: QuadtreeParams, reset?: boolean): void;
371
+ }
372
+
373
+ export { Quadtree, TerrainGeometry, computeScreenSpaceInfo, distanceBasedSubdivision, isSkirtUV, isSkirtVertex, screenSpaceSubdivision };
374
+ export type { QuadtreeParams, ScreenSpaceInfo, SubdivisionContext, SubdivisionStrategy };