@series-inc/rundot-3d-engine 0.3.0

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.
Files changed (38) hide show
  1. package/LICENSE.txt +6 -0
  2. package/README.md +80 -0
  3. package/dist/ComponentRegistry-V_7WauAE.d.ts +448 -0
  4. package/dist/chunk-ZNDJR3RD.js +5623 -0
  5. package/dist/chunk-ZNDJR3RD.js.map +1 -0
  6. package/dist/index.d.ts +1484 -0
  7. package/dist/index.js +1390 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/systems/index.d.ts +3356 -0
  10. package/dist/systems/index.js +9652 -0
  11. package/dist/systems/index.js.map +1 -0
  12. package/docs/core/Component.md +321 -0
  13. package/docs/core/GameObject.md +204 -0
  14. package/docs/core/VenusGame.md +316 -0
  15. package/docs/patterns/ComponentCommunication.md +337 -0
  16. package/docs/patterns/CreatingGameObjects.md +290 -0
  17. package/docs/patterns/MeshColliders.md +338 -0
  18. package/docs/patterns/MeshLoading.md +316 -0
  19. package/docs/physics/Colliders.md +249 -0
  20. package/docs/physics/PhysicsSystem.md +151 -0
  21. package/docs/physics/RigidBodyComponent.md +201 -0
  22. package/docs/rendering/AssetManager.md +308 -0
  23. package/docs/rendering/InstancedRenderer.md +286 -0
  24. package/docs/rendering/MeshRenderer.md +286 -0
  25. package/docs/rendering/SkeletalRenderer.md +308 -0
  26. package/docs/systems/AnimationSystem.md +75 -0
  27. package/docs/systems/AudioSystem.md +79 -0
  28. package/docs/systems/InputManager.md +101 -0
  29. package/docs/systems/LightingSystem.md +101 -0
  30. package/docs/systems/NavigationSystem.md +246 -0
  31. package/docs/systems/ParticleSystem.md +44 -0
  32. package/docs/systems/PrefabSystem.md +60 -0
  33. package/docs/systems/SplineSystem.md +194 -0
  34. package/docs/systems/StowKitSystem.md +77 -0
  35. package/docs/systems/TweenSystem.md +132 -0
  36. package/docs/systems/UISystem.md +73 -0
  37. package/package.json +62 -0
  38. package/scripts/postinstall.mjs +51 -0
@@ -0,0 +1,1484 @@
1
+ import { C as Component, A as AnimationCullingManager, G as GameObject, R as RigidBodyComponentThree, a as ComponentJSON, P as PrefabNode } from './ComponentRegistry-V_7WauAE.js';
2
+ import * as THREE from 'three';
3
+ export * from '@series-inc/rundot-game-sdk';
4
+ export { default as RundotGameAPI } from '@series-inc/rundot-game-sdk/api';
5
+ import '@dimforge/rapier3d';
6
+
7
+ /**
8
+ * Component updater for Three.js components
9
+ * Handles the update loop for all registered components
10
+ */
11
+ declare class ComponentUpdater {
12
+ private static updateableComponents;
13
+ private static lateUpdateableComponents;
14
+ private static updateCount;
15
+ /**
16
+ * Register a component for updates
17
+ * @internal Only called by Component class
18
+ */
19
+ static registerComponent(component: Component): void;
20
+ /**
21
+ * Unregister a component from updates
22
+ * @internal Only called by Component class
23
+ */
24
+ static unregisterComponent(component: Component): void;
25
+ /**
26
+ * Register a component for late updates
27
+ * @internal Only called by Component class
28
+ */
29
+ static registerLateUpdateComponent(component: Component): void;
30
+ /**
31
+ * Unregister a component from late updates
32
+ * @internal Only called by Component class
33
+ */
34
+ static unregisterLateUpdateComponent(component: Component): void;
35
+ /**
36
+ * Initialize the component updater
37
+ */
38
+ static initialize(scene: THREE.Scene): void;
39
+ /**
40
+ * Update all registered components
41
+ */
42
+ static update(deltaTime: number): void;
43
+ /**
44
+ * Late update all registered components
45
+ */
46
+ static lateUpdate(deltaTime: number): void;
47
+ /**
48
+ * Dispose all components
49
+ */
50
+ static dispose(): void;
51
+ }
52
+
53
+ /**
54
+ * Configuration interface for VenusGame.
55
+ * Override getConfig() in your game class to customize these settings.
56
+ */
57
+ interface VenusGameConfig {
58
+ /** Background color as hex number (default: 0x000000) */
59
+ backgroundColor?: number;
60
+ /** Enable antialiasing for smoother edges (default: true) */
61
+ antialias?: boolean;
62
+ /** Enable shadow mapping (default: true) */
63
+ shadowMapEnabled?: boolean;
64
+ /** Shadow map type: 'vsm' for smoother shadows, 'pcf_soft' for softer edges (default: 'vsm') */
65
+ shadowMapType?: "vsm" | "pcf_soft";
66
+ /** Tone mapping: 'aces' for filmic, 'linear' for basic, 'none' to disable (default: 'aces') */
67
+ toneMapping?: "aces" | "linear" | "none";
68
+ /** Tone mapping exposure (default: 1.0) */
69
+ toneMappingExposure?: number;
70
+ /** Enable audio system and auto-create listener (default: true) */
71
+ audioEnabled?: boolean;
72
+ }
73
+ /**
74
+ * Three.js version of VenusGame
75
+ * Clean implementation without Babylon.js dependencies
76
+ */
77
+ declare abstract class VenusGame {
78
+ private static _instance;
79
+ private static _scene;
80
+ private static _renderer;
81
+ private static _camera;
82
+ protected canvas: HTMLCanvasElement;
83
+ protected renderer: THREE.WebGLRenderer;
84
+ protected scene: THREE.Scene;
85
+ protected camera: THREE.PerspectiveCamera;
86
+ private resizeListener;
87
+ private isDisposed;
88
+ private animationId;
89
+ private clock;
90
+ private maxDeltaTime;
91
+ protected config: Required<VenusGameConfig>;
92
+ protected audioListener: THREE.AudioListener | null;
93
+ private animationCullingManager;
94
+ /**
95
+ * Get the current elapsed time (not delta time)
96
+ * NOTE: For delta time, use the parameter passed to preRender() method
97
+ * This prevents accidental multiple getDelta() calls which cause frame rate dependent behavior
98
+ */
99
+ protected getElapsedTime(): number;
100
+ /**
101
+ * Override this method to provide game-specific configuration.
102
+ * The returned config is merged with DEFAULT_CONFIG.
103
+ * @example
104
+ * protected getConfig(): VenusGameConfig {
105
+ * return {
106
+ * backgroundColor: 0x0077b6,
107
+ * toneMapping: "aces",
108
+ * }
109
+ * }
110
+ */
111
+ protected getConfig(): VenusGameConfig;
112
+ /**
113
+ * Get the active VenusGame instance
114
+ */
115
+ static get instance(): VenusGame;
116
+ /**
117
+ * Get the active Three.js scene
118
+ */
119
+ static get scene(): THREE.Scene;
120
+ /**
121
+ * Get the active Three.js renderer
122
+ */
123
+ static get renderer(): THREE.WebGLRenderer;
124
+ /**
125
+ * Get the active Three.js camera
126
+ */
127
+ static get camera(): THREE.PerspectiveCamera;
128
+ /**
129
+ * Set the camera used for animation frustum culling.
130
+ * When set, animation updates are skipped for characters outside the camera's view.
131
+ * @param camera The camera to use for culling (pass null to disable)
132
+ * @param frustumExpansion How much to expand the frustum (1.2 = 20% larger, avoids pop-in). Default: 1.2
133
+ */
134
+ static setAnimationCullingCamera(camera: THREE.Camera | null, frustumExpansion?: number): void;
135
+ /**
136
+ * Get the animation culling manager for advanced configuration.
137
+ * Use this to enable distance culling, add multiple cameras, adjust LOD settings, etc.
138
+ */
139
+ static getAnimationCulling(): AnimationCullingManager;
140
+ /**
141
+ * Static factory method to create, initialize and start a VenusGame instance
142
+ * @returns A fully initialized and running VenusGame instance
143
+ */
144
+ static create<T extends VenusGame>(this: new () => T): Promise<T>;
145
+ resume(): void;
146
+ pause(): void;
147
+ /**
148
+ * Create a new VenusGame
149
+ */
150
+ constructor();
151
+ /**
152
+ * Apply rendering configuration from config
153
+ */
154
+ private applyRenderingConfig;
155
+ /**
156
+ * Set up audio listener if enabled in config.
157
+ * Attaches listener to camera and sets AudioSystem.mainListener.
158
+ */
159
+ private setupAudioListener;
160
+ /**
161
+ * Check if running on an iPhone/iPad specifically
162
+ */
163
+ private isIPhone;
164
+ /**
165
+ * Check if running on a mobile device
166
+ */
167
+ private isMobileDevice;
168
+ private isPaused;
169
+ private prevMasterVolume;
170
+ /**
171
+ * Start the render loop
172
+ */
173
+ private startRenderLoop;
174
+ /**
175
+ * Setup visibility change handling to pause/resume delta time
176
+ */
177
+ private setupVisibilityHandling;
178
+ /**
179
+ * Render method. Can be overridden for custom rendering pipelines.
180
+ */
181
+ protected render(): void;
182
+ /**
183
+ * Abstract method that derived classes must implement for game-specific initialization
184
+ */
185
+ protected abstract onStart(): Promise<void>;
186
+ /**
187
+ * Abstract method called every frame before rendering
188
+ * @param deltaTime Time in seconds since last frame - use this for all time-based calculations
189
+ * IMPORTANT: Do NOT access this.clock.getDelta() directly - use the deltaTime parameter!
190
+ */
191
+ protected abstract preRender(deltaTime: number): void;
192
+ /**
193
+ * Abstract method that derived classes must implement for game cleanup
194
+ */
195
+ protected abstract onDispose(): Promise<void>;
196
+ /**
197
+ * Dispose of the game, cleaning up all resources
198
+ * This will stop the render loop and clean up any created resources
199
+ */
200
+ dispose(): Promise<void>;
201
+ }
202
+
203
+ /**
204
+ * Asset info for a loaded asset in Three.js
205
+ */
206
+ interface AssetInfo {
207
+ path: string;
208
+ group?: THREE.Group;
209
+ gltf?: any;
210
+ isLoaded: boolean;
211
+ isLoading: boolean;
212
+ meshes: THREE.Mesh[];
213
+ materials: THREE.Material[];
214
+ animations: THREE.AnimationClip[];
215
+ }
216
+ /**
217
+ * GPU Instance batch for managing InstancedMesh objects
218
+ */
219
+ interface GPUInstanceBatch {
220
+ instancedMesh: THREE.InstancedMesh;
221
+ assetPath: string;
222
+ material: THREE.Material;
223
+ instances: GPUInstanceData[];
224
+ maxInstances: number;
225
+ needsUpdate: boolean;
226
+ cullingRadius: number;
227
+ hasDynamicObjects: boolean;
228
+ }
229
+ /**
230
+ * Individual instance data within a GPU batch
231
+ */
232
+ interface GPUInstanceData {
233
+ id: string;
234
+ gameObject: GameObject;
235
+ matrix: THREE.Matrix4;
236
+ isActive: boolean;
237
+ isStatic: boolean;
238
+ }
239
+ /**
240
+ * Instance tracking for debugging and performance monitoring
241
+ */
242
+ interface InstanceStats$1 {
243
+ totalInstances: number;
244
+ sharedInstances: number;
245
+ clonedInstances: number;
246
+ brokenInstances: number;
247
+ gpuInstances: number;
248
+ gpuBatches: number;
249
+ }
250
+ /**
251
+ * Global instancing statistics for debug display
252
+ */
253
+ interface GlobalInstanceStats {
254
+ totalAssets: number;
255
+ loadedAssets: number;
256
+ totalInstances: number;
257
+ sharedInstances: number;
258
+ clonedInstances: number;
259
+ brokenInstances: number;
260
+ gpuInstances: number;
261
+ gpuBatches: number;
262
+ geometryReuse: number;
263
+ materialReuse: number;
264
+ }
265
+ /**
266
+ * A Three.js asset manager optimized for preloading workflows
267
+ * Compatible API with the original Babylon.js AssetManager
268
+ *
269
+ * RECOMMENDED USAGE PATTERN:
270
+ * 1. Initialize: AssetManager.init(scene)
271
+ * 2. Preload all assets: await AssetManager.preloadAssets([...paths])
272
+ * 3. Use synchronously: AssetManager.getMesh() / getAssetGroup()
273
+ * 4. Create renderers: new ObjRendererThree() (now fully synchronous)
274
+ *
275
+ * SUPPORTED FORMATS:
276
+ * - .glb/.gltf (using GLTFLoader)
277
+ * - .obj (using OBJLoader)
278
+ * - .mtl (material files for OBJ)
279
+ * - .fbx (using FBXLoader)
280
+ * - .stow (using StowKitLoader)
281
+ */
282
+ declare class AssetManager {
283
+ private static _scene;
284
+ private static _assets;
285
+ private static _instanceStats;
286
+ private static _gpuBatches;
287
+ private static _baseUrl;
288
+ private static _gltfLoader;
289
+ private static _objLoader;
290
+ private static _mtlLoader;
291
+ private static _fbxLoader;
292
+ private static _isPreloadingComplete;
293
+ private static _skeletonCache;
294
+ private static _frustumCullingPadding;
295
+ private static _frustumCullingEnabled;
296
+ /**
297
+ * Initialize the AssetManager with a scene
298
+ * @param scene The Three.js scene to use
299
+ * @param renderer Optional WebGL renderer for StowKit texture support
300
+ */
301
+ static init(scene: THREE.Scene, renderer?: THREE.WebGLRenderer): void;
302
+ /**
303
+ * Set base URL for resolving relative paths (optional - defaults to relative paths)
304
+ * @param baseUrl The base URL to use
305
+ */
306
+ static setBaseUrl(baseUrl: string): void;
307
+ /**
308
+ * Get the full path for an asset - automatically handles relative paths
309
+ */
310
+ static getFullPath(path: string): string;
311
+ /**
312
+ * Preload multiple assets in bulk - RECOMMENDED WORKFLOW
313
+ * Call this once at app startup, then use synchronous methods for the rest of the app
314
+ * @param assetPaths Array of asset paths to preload
315
+ * @param progressCallback Optional callback for overall progress (0-1)
316
+ * @returns Promise that resolves when all assets are loaded (or failed)
317
+ */
318
+ static preloadAssets(assetPaths: string[], progressCallback?: (progress: number, loadedCount: number, totalCount: number) => void): Promise<{
319
+ loaded: string[];
320
+ failed: string[];
321
+ }>;
322
+ /**
323
+ * Check if preloading workflow has been completed
324
+ * This doesn't guarantee all assets loaded successfully, just that preloading finished
325
+ */
326
+ static isPreloadingComplete(): boolean;
327
+ /**
328
+ * Load an asset by path (used internally by preloadAssets)
329
+ * @param path Path to the asset
330
+ * @param progressCallback Optional callback for loading progress
331
+ */
332
+ static loadAsset(path: string, progressCallback?: (progress: number) => void): Promise<boolean>;
333
+ /**
334
+ * Check if an asset is loaded and throw an error if not
335
+ * Use this for strict preloading workflows - RECOMMENDED for ObjRendererThree
336
+ * @param path Path to the asset
337
+ * @throws Error if asset is not preloaded
338
+ */
339
+ static requireAsset(path: string): AssetInfo;
340
+ /**
341
+ * Get a list of all preloaded asset paths
342
+ */
343
+ static getPreloadedAssets(): string[];
344
+ /**
345
+ * Get a list of all failed asset paths
346
+ */
347
+ static getFailedAssets(): string[];
348
+ /**
349
+ * Get preloading statistics
350
+ */
351
+ static getPreloadingStats(): {
352
+ total: number;
353
+ loaded: number;
354
+ failed: number;
355
+ loading: number;
356
+ completionPercentage: number;
357
+ };
358
+ /**
359
+ * Get GLTF data for a loaded GLTF/GLB asset - SYNCHRONOUS (use after preloading)
360
+ * @param path Path to the asset
361
+ * @returns GLTF data or null if not a GLTF asset
362
+ */
363
+ static getGLTF(path: string): any | null;
364
+ /**
365
+ * Load GLTF/GLB asset
366
+ * @private
367
+ */
368
+ private static loadGLTFAsset;
369
+ /**
370
+ * Load OBJ asset
371
+ * @private
372
+ */
373
+ private static loadOBJAsset;
374
+ /**
375
+ * Load OBJ with or without materials
376
+ * @private
377
+ */
378
+ private static loadOBJWithMaterials;
379
+ /**
380
+ * Load FBX asset
381
+ * @private
382
+ */
383
+ private static loadFBXAsset;
384
+ /**
385
+ * Get the asset group for a loaded asset - SYNCHRONOUS (use after preloading)
386
+ * @param path Path to the asset
387
+ * @returns The Group for the asset or null if not loaded
388
+ */
389
+ static getAssetGroup(path: string): THREE.Group | null;
390
+ /**
391
+ * Get the primary mesh from a loaded asset - SYNCHRONOUS (use after preloading)
392
+ * @param path Path to the asset
393
+ * @returns The primary Mesh from the asset or null if not found
394
+ */
395
+ static getMesh(path: string): THREE.Mesh | null;
396
+ /**
397
+ * Get all meshes from a loaded asset - SYNCHRONOUS (use after preloading)
398
+ * @param path Path to the asset
399
+ * @returns Array of meshes from the asset
400
+ */
401
+ static getMeshes(path: string): THREE.Mesh[];
402
+ /**
403
+ * Get all materials from a loaded asset - SYNCHRONOUS (use after preloading)
404
+ * @param path Path to the asset
405
+ * @returns Array of materials from the asset
406
+ */
407
+ static getMaterials(path: string): THREE.Material[];
408
+ /**
409
+ * Get all animations from a loaded asset - SYNCHRONOUS (use after preloading)
410
+ * @param path Path to the asset
411
+ * @returns Array of animation clips from the asset
412
+ */
413
+ static getAnimations(path: string): THREE.AnimationClip[];
414
+ /**
415
+ * Register a StowKit-loaded asset for compatibility with existing code
416
+ * Allows StowKit assets to be accessed via the same AssetManager.getAssetGroup() API
417
+ * @param path Virtual path to register the asset under (e.g. 'v2/restaurant_display_default.fbx')
418
+ * @param group The THREE.Group loaded from StowKit
419
+ */
420
+ static registerStowKitAsset(path: string, group: THREE.Group): void;
421
+ private static _stowkitTextures;
422
+ /**
423
+ * Register a StowKit-loaded texture for use by materials
424
+ * @param name Texture name/ID
425
+ * @param texture The THREE.Texture loaded from StowKit
426
+ */
427
+ static registerStowKitTexture(name: string, texture: THREE.Texture): void;
428
+ /**
429
+ * Get a StowKit-loaded texture by name
430
+ * @param name Texture name/ID
431
+ * @returns The texture or null if not found
432
+ */
433
+ static getStowKitTexture(name: string): THREE.Texture | null;
434
+ /**
435
+ * Unload an asset to free memory
436
+ * @param path Path to the asset
437
+ */
438
+ static unloadAsset(path: string): void;
439
+ /**
440
+ * Check if an asset is loaded
441
+ * @param path Path to the asset
442
+ */
443
+ static isLoaded(path: string): boolean;
444
+ /**
445
+ * Get the current base URL being used
446
+ */
447
+ static getBaseUrl(): string;
448
+ /**
449
+ * Reset to default relative path behavior
450
+ */
451
+ static useRelativePaths(): void;
452
+ /**
453
+ * Get loading progress for all assets
454
+ * @returns Object with loading statistics
455
+ * @deprecated Use getPreloadingStats() instead for better information
456
+ */
457
+ static getLoadingStats(): {
458
+ loaded: number;
459
+ loading: number;
460
+ total: number;
461
+ };
462
+ /**
463
+ * Track when a shared instance is converted to cloned (broken instancing)
464
+ * @param assetPath Path to the asset
465
+ */
466
+ static trackInstanceBroken(assetPath: string): void;
467
+ /**
468
+ * Get instance statistics for a specific asset
469
+ * @param assetPath Path to the asset
470
+ */
471
+ static getAssetInstanceStats(assetPath: string): InstanceStats$1;
472
+ /**
473
+ * Get global instancing statistics for debug display
474
+ */
475
+ static getGlobalInstanceStats(): GlobalInstanceStats;
476
+ /**
477
+ * Get detailed instancing report for debugging
478
+ */
479
+ static getInstanceReport(): string;
480
+ /**
481
+ * Create or get a GPU instance batch for an asset
482
+ * @param assetPath Path to the asset
483
+ * @param material Material to use for the batch
484
+ * @param maxInstances Maximum instances in this batch (default: 1000)
485
+ */
486
+ static getOrCreateGPUBatch(assetPath: string, material: THREE.Material, maxInstances?: number): GPUInstanceBatch | null;
487
+ /**
488
+ * Add a GPU instance to a batch
489
+ * @param assetPath Path to the asset
490
+ * @param gameObject GameObject to instance
491
+ * @param material Material to use
492
+ * @param isStatic Whether this instance is static (won't move after creation)
493
+ * @returns Instance ID or null if failed
494
+ */
495
+ static addGPUInstance(assetPath: string, gameObject: GameObject, material: THREE.Material, isStatic?: boolean): string | null;
496
+ /**
497
+ * Remove a GPU instance from its batch
498
+ * @param assetPath Path to the asset
499
+ * @param instanceId Instance ID to remove
500
+ */
501
+ static removeGPUInstance(assetPath: string, instanceId: string): void;
502
+ /**
503
+ * Set the visibility of a specific GPU instance
504
+ * @param assetPath Path to the asset
505
+ * @param instanceId Instance ID to show/hide
506
+ * @param visible Whether the instance should be visible
507
+ */
508
+ static setGPUInstanceVisible(assetPath: string, instanceId: string, visible: boolean): void;
509
+ /**
510
+ * Get the visibility of a specific GPU instance
511
+ * @param assetPath Path to the asset
512
+ * @param instanceId Instance ID to check
513
+ * @returns Whether the instance is visible
514
+ */
515
+ static getGPUInstanceVisible(assetPath: string, instanceId: string): boolean;
516
+ /**
517
+ * Convert a GPU instance to object-level instance (for scaling, etc.)
518
+ * @param assetPath Path to the asset
519
+ * @param instanceId Instance ID to convert
520
+ * @returns New GameObject with ObjRenderer or null if failed
521
+ */
522
+ static convertGPUToObjectLevel(assetPath: string, instanceId: string): any | null;
523
+ /**
524
+ * Update GPU batch matrices and upload to GPU
525
+ * @param batch GPU batch to update
526
+ * @param camera Optional camera for frustum culling
527
+ */
528
+ static updateGPUBatch(batch: GPUInstanceBatch, camera?: THREE.Camera): void;
529
+ /**
530
+ * Update GPU batch statistics
531
+ * @param assetPath Path to the asset
532
+ */
533
+ private static updateGPUBatchStats;
534
+ /**
535
+ * Track when an instance is created from an asset
536
+ * @param assetPath Path to the asset
537
+ * @param isShared Whether this is a shared instance (true) or cloned (false)
538
+ * @param isGPU Whether this is a GPU instance (true) or object-level (false)
539
+ */
540
+ static trackInstanceCreated(assetPath: string, isShared: boolean, isGPU?: boolean): void;
541
+ /**
542
+ * Track when an instance is destroyed
543
+ * @param assetPath Path to the asset
544
+ * @param wasShared Whether this was a shared instance
545
+ * @param wasGPU Whether this was a GPU instance
546
+ */
547
+ static trackInstanceDestroyed(assetPath: string, wasShared: boolean, wasGPU?: boolean): void;
548
+ /**
549
+ * Update all GPU batches with optional frustum culling
550
+ * Now uses separated static/dynamic logic for optimal performance
551
+ * @param camera Optional camera for frustum culling
552
+ * @param debug Whether to log frustum culling statistics (default: false)
553
+ */
554
+ static updateAllGPUBatches(camera?: THREE.Camera, debug?: boolean): void;
555
+ /**
556
+ * DEBUG: Force update all GPU batches
557
+ * Call this from console to manually trigger batch updates
558
+ */
559
+ static debugUpdateAllGPUBatches(): void;
560
+ /**
561
+ * Update only dynamic GPU batches (called every frame for immediate updates)
562
+ * @param camera Optional camera for frustum culling
563
+ * @param debug Whether to log statistics (default: false)
564
+ */
565
+ static updateDynamicGPUBatches(camera?: THREE.Camera, debug?: boolean): void;
566
+ /**
567
+ * DEBUG: Show static vs dynamic batch breakdown
568
+ */
569
+ static debugBatchTypes(): void;
570
+ /**
571
+ * Set frustum culling padding multiplier
572
+ * Higher values = less aggressive culling (fewer false positives)
573
+ * Lower values = more aggressive culling (more performance, more false positives)
574
+ * @param padding Padding multiplier (default: 1.2 = 20% padding)
575
+ */
576
+ static setFrustumCullingPadding(padding: number): void;
577
+ /**
578
+ * Get current frustum culling padding multiplier
579
+ */
580
+ static getFrustumCullingPadding(): number;
581
+ /**
582
+ * Enable or disable frustum culling globally
583
+ * @param enabled Whether frustum culling should be enabled
584
+ */
585
+ static setFrustumCullingEnabled(enabled: boolean): void;
586
+ /**
587
+ * Get current frustum culling enabled state
588
+ */
589
+ static isFrustumCullingEnabled(): boolean;
590
+ /**
591
+ * DEBUG: Test frustum culling by temporarily disabling it
592
+ * @param disabled Whether to disable frustum culling entirely (for testing)
593
+ */
594
+ static debugFrustumCulling(disabled?: boolean): void;
595
+ /**
596
+ * Preload a skeletal FBX model using SkeletonCache
597
+ * Use this for character models that need proper bone cloning
598
+ */
599
+ static preloadSkeletalModel(path: string): Promise<THREE.Object3D>;
600
+ /**
601
+ * Register a skeletal model directly (for StowKit or other loaders)
602
+ * Use this for character models loaded from StowKit
603
+ */
604
+ static registerSkeletalModel(path: string, object: THREE.Object3D): void;
605
+ /**
606
+ * Get a properly cloned skeletal model
607
+ * Uses SkeletonUtils.clone() to preserve bone relationships for animation
608
+ */
609
+ static getSkeletalClone(path: string): THREE.Object3D | null;
610
+ /**
611
+ * Check if a skeletal model is loaded
612
+ */
613
+ static isSkeletalModelLoaded(path: string): boolean;
614
+ /**
615
+ * Get the original skeletal model (for reference, not for use)
616
+ */
617
+ static getSkeletalOriginal(path: string): THREE.Object3D | null;
618
+ /**
619
+ * Clear all global state (for testing) - now includes skeleton cache
620
+ */
621
+ static reset(): void;
622
+ }
623
+
624
+ /**
625
+ * Instance-based cache system for skeletal/animated FBX models
626
+ * Uses SkeletonUtils.clone() for proper bone/animation preservation
627
+ * Used internally by AssetManager
628
+ */
629
+ declare class SkeletonCache {
630
+ private loader;
631
+ private originals;
632
+ private loading;
633
+ isLoaded(path: string): boolean;
634
+ /**
635
+ * Preload a skeletal FBX model
636
+ */
637
+ preload(path: string): Promise<THREE.Object3D>;
638
+ /**
639
+ * Register a skeletal model directly (for StowKit or other loaders)
640
+ */
641
+ register(path: string, object: THREE.Object3D): void;
642
+ /**
643
+ * Get a properly cloned skeletal model
644
+ * Uses SkeletonUtils.clone() to preserve bone relationships
645
+ */
646
+ getClone(path: string): THREE.Object3D | null;
647
+ /**
648
+ * Get the original (non-cloned) model
649
+ */
650
+ getOriginal(path: string): THREE.Object3D | null;
651
+ /**
652
+ * Clear all cached models (for cleanup/testing)
653
+ */
654
+ clear(): void;
655
+ /**
656
+ * Get all cached paths
657
+ */
658
+ getCachedPaths(): string[];
659
+ }
660
+
661
+ /**
662
+ * Simple interaction zone using Rapier physics triggers
663
+ * Replaces the complex raycasting system with simple physics triggers
664
+ */
665
+ declare class InteractionZone extends Component {
666
+ readonly id: string;
667
+ private active;
668
+ private onEnterCallback?;
669
+ private onExitCallback?;
670
+ private entitiesInZone;
671
+ private rigidBody;
672
+ private visualMesh;
673
+ private options;
674
+ constructor(onEnter?: (other: GameObject) => void, onExit?: (other: GameObject) => void, options?: InteractionZoneOptions);
675
+ /**
676
+ * Set interaction callbacks
677
+ */
678
+ setCallbacks(callbacks: {
679
+ onEnter?: (other: GameObject) => void;
680
+ onExit?: (other: GameObject) => void;
681
+ }): void;
682
+ /**
683
+ * Called when component is attached to GameObject
684
+ */
685
+ protected onCreate(): void;
686
+ onEnabled(): void;
687
+ /**
688
+ * Create the visual mesh for the interaction zone
689
+ */
690
+ private createVisualMesh;
691
+ /**
692
+ * Create the physics trigger collider
693
+ */
694
+ private createTriggerCollider;
695
+ /**
696
+ * Handle trigger enter event (to be called by physics system)
697
+ */
698
+ onTriggerEnter(other: GameObject): void;
699
+ /**
700
+ * Handle trigger exit event (to be called by physics system)
701
+ */
702
+ onTriggerExit(other: GameObject): void;
703
+ /**
704
+ * Get all entities currently in the zone
705
+ */
706
+ getEntitiesInZone(): GameObject[];
707
+ /**
708
+ * Check if a specific entity is in the zone
709
+ */
710
+ hasEntity(entity: GameObject): boolean;
711
+ /**
712
+ * Set active state
713
+ */
714
+ setActive(active: boolean): void;
715
+ /**
716
+ * Check if the interaction zone is active
717
+ */
718
+ isActive(): boolean;
719
+ /**
720
+ * Get the visual mesh
721
+ */
722
+ getVisualMesh(): THREE.Mesh | null;
723
+ /**
724
+ * Get the collider component
725
+ */
726
+ getCollider(): RigidBodyComponentThree | null;
727
+ /**
728
+ * Get the GameObject this zone is attached to
729
+ */
730
+ getGameObject(): GameObject;
731
+ /**
732
+ * Component cleanup
733
+ */
734
+ protected onCleanup(): void;
735
+ }
736
+ interface InteractionZoneOptions {
737
+ width?: number;
738
+ depth?: number;
739
+ active?: boolean;
740
+ centerOffset?: THREE.Vector2;
741
+ show?: boolean;
742
+ }
743
+
744
+ interface VirtualJoystickOptions {
745
+ size?: number;
746
+ knobSize?: number;
747
+ deadZone?: number;
748
+ maxDistance?: number;
749
+ color?: string;
750
+ visible?: boolean;
751
+ opacity?: number;
752
+ }
753
+ /**
754
+ * Virtual joystick component for mobile/touch input - Three.js version
755
+ * Shows on pointer down, hides on pointer up
756
+ * Provides normalized direction vector for movement
757
+ * Uses HTML/CSS for UI elements
758
+ */
759
+ declare class VirtualJoystickThree extends Component {
760
+ private options;
761
+ private static isMobileDevice;
762
+ private joystickContainer;
763
+ private joystickBase;
764
+ private joystickKnob;
765
+ private mobileHint;
766
+ private isActive;
767
+ private startPosition;
768
+ private currentPosition;
769
+ private direction;
770
+ private magnitude;
771
+ private joystickPointerId;
772
+ private isDragging;
773
+ private joystickRadius;
774
+ private boundPointerDown;
775
+ private boundPointerMove;
776
+ private boundPointerUp;
777
+ private boundTouchStart;
778
+ private boundTouchMove;
779
+ private boundTouchEnd;
780
+ constructor(options?: VirtualJoystickOptions);
781
+ protected onCreate(): void;
782
+ protected onCleanup(): void;
783
+ /**
784
+ * Create the joystick UI elements using HTML/CSS
785
+ */
786
+ private createJoystickUI;
787
+ /**
788
+ * Create mobile hint for touch controls (only shows on mobile devices)
789
+ */
790
+ private createMobileHint;
791
+ /**
792
+ * Setup input handlers for pointer and touch events
793
+ */
794
+ private setupInputHandlers;
795
+ /**
796
+ * Remove input handlers
797
+ */
798
+ private removeInputHandlers;
799
+ /**
800
+ * Handle pointer down event
801
+ */
802
+ private onPointerDown;
803
+ /**
804
+ * Handle touch start event (fallback)
805
+ */
806
+ private onTouchStart;
807
+ /**
808
+ * Start the joystick at the given position
809
+ */
810
+ private startJoystick;
811
+ /**
812
+ * Handle pointer move event
813
+ */
814
+ private onPointerMove;
815
+ /**
816
+ * Handle touch move event (fallback)
817
+ */
818
+ private onTouchMove;
819
+ /**
820
+ * Update joystick position and direction
821
+ */
822
+ private updateJoystick;
823
+ /**
824
+ * Handle pointer up event
825
+ */
826
+ private onPointerUp;
827
+ /**
828
+ * Handle touch end event (fallback)
829
+ */
830
+ private onTouchEnd;
831
+ /**
832
+ * End the joystick interaction
833
+ */
834
+ private endJoystick;
835
+ /**
836
+ * Update knob position based on current pointer position
837
+ */
838
+ private updateKnobPosition;
839
+ /**
840
+ * Update direction vector based on knob position
841
+ */
842
+ private updateDirection;
843
+ /**
844
+ * Get the current input direction as a Vector3 (Y=0 for movement)
845
+ */
846
+ getDirection(): THREE.Vector3 | null;
847
+ /**
848
+ * Get the current input magnitude (0-1)
849
+ */
850
+ getMagnitude(): number;
851
+ /**
852
+ * Check if the joystick is currently active
853
+ */
854
+ isActiveJoystick(): boolean;
855
+ /**
856
+ * Toggle joystick visual visibility (joystick remains functional)
857
+ */
858
+ setVisible(visible: boolean): void;
859
+ /**
860
+ * Get current visibility state
861
+ */
862
+ isVisible(): boolean;
863
+ /**
864
+ * Set joystick opacity (0-1)
865
+ */
866
+ setOpacity(opacity: number): void;
867
+ /**
868
+ * Get current opacity
869
+ */
870
+ getOpacity(): number;
871
+ /**
872
+ * Clean up UI resources
873
+ */
874
+ private cleanupUI;
875
+ }
876
+
877
+ /**
878
+ * Three.js Movement controller component that handles physics-based movement and rotation
879
+ * Uses Rapier physics with rotation locking for smooth, controlled movement
880
+ * Can be used for player input, AI navigation, or any entity that needs to move
881
+ */
882
+ declare class MovementController extends Component {
883
+ maxMoveSpeed: number;
884
+ acceleration: number;
885
+ turnSpeed: number;
886
+ private rigidBodyComponent;
887
+ private targetRotationY;
888
+ private currentRotationY;
889
+ private _currentVelocity;
890
+ /**
891
+ * Called when the component is created and attached to a GameObject
892
+ */
893
+ protected onCreate(): void;
894
+ /**
895
+ * Find the rigid body component on this GameObject
896
+ */
897
+ private findRigidBodyComponentThree;
898
+ /**
899
+ * Set the rigid body component this controller should manage
900
+ */
901
+ setRigidBodyComponentThree(rigidBodyComponent: RigidBodyComponentThree): void;
902
+ /**
903
+ * Move the entity based on input direction
904
+ * @param inputDirection Normalized direction vector (or null for no movement)
905
+ * @param deltaTime Time since last frame in seconds
906
+ */
907
+ move(inputDirection: THREE.Vector3 | null, deltaTime: number): void;
908
+ /**
909
+ * Calculate target velocity based on input direction
910
+ */
911
+ private calculateTargetVelocity;
912
+ /**
913
+ * Smooth velocity towards target using acceleration
914
+ */
915
+ private smoothVelocity;
916
+ /**
917
+ * Update rotation smoothly towards movement direction using quaternion slerp
918
+ */
919
+ private updateRotation;
920
+ /**
921
+ * Utility function to move a value towards a target at a given rate
922
+ */
923
+ private moveTowards;
924
+ /**
925
+ * Get current movement state for debugging
926
+ */
927
+ getMovementState(): any;
928
+ /**
929
+ * Clean up resources when the component is removed
930
+ */
931
+ protected onCleanup(): void;
932
+ }
933
+
934
+ /**
935
+ * Three.js Player Controller Component
936
+ * Handles WASD movement, mouse look, and basic interactions
937
+ */
938
+ declare class PlayerControllerThree extends Component {
939
+ moveSpeed: number;
940
+ runSpeed: number;
941
+ rotationSpeed: number;
942
+ private controls;
943
+ private keys;
944
+ private mouseX;
945
+ private mouseY;
946
+ private mouseSensitivity;
947
+ private isPointerLocked;
948
+ private camera;
949
+ private cameraHeight;
950
+ private velocity;
951
+ private direction;
952
+ constructor(camera: THREE.PerspectiveCamera);
953
+ protected onCreate(): void;
954
+ /**
955
+ * Set up keyboard and mouse event listeners
956
+ */
957
+ private setupEventListeners;
958
+ /**
959
+ * Set up pointer lock for mouse look
960
+ */
961
+ private setupPointerLock;
962
+ /**
963
+ * Handle key down events
964
+ */
965
+ private onKeyDown;
966
+ /**
967
+ * Handle key up events
968
+ */
969
+ private onKeyUp;
970
+ /**
971
+ * Handle mouse movement for looking around
972
+ */
973
+ private onMouseMove;
974
+ /**
975
+ * Handle canvas clicks for pointer lock
976
+ */
977
+ private onClick;
978
+ /**
979
+ * Handle pointer lock state changes
980
+ */
981
+ private onPointerLockChange;
982
+ /**
983
+ * Handle interaction key press
984
+ */
985
+ private onInteract;
986
+ /**
987
+ * Update method - called every frame
988
+ */
989
+ update(deltaTime: number): void;
990
+ /**
991
+ * Update player movement based on input
992
+ */
993
+ private updateMovement;
994
+ /**
995
+ * Update camera position to follow player
996
+ */
997
+ private updateCameraPosition;
998
+ /**
999
+ * Get current movement state for debugging
1000
+ */
1001
+ getMovementState(): {
1002
+ position: THREE.Vector3;
1003
+ isMoving: boolean;
1004
+ isRunning: boolean;
1005
+ lookDirection: THREE.Vector3;
1006
+ };
1007
+ /**
1008
+ * Set player position
1009
+ */
1010
+ setPosition(position: THREE.Vector3): void;
1011
+ /**
1012
+ * Clean up event listeners
1013
+ */
1014
+ protected onCleanup(): void;
1015
+ }
1016
+
1017
+ /**
1018
+ * Three.js Skeletal renderer for animated FBX models
1019
+ * - Uses AssetManager for preloading coordination
1020
+ * - Uses SkeletonCache for proper skeletal cloning
1021
+ * - Specifically designed for animated characters
1022
+ * - Always cloned, always has shadows, never static
1023
+ */
1024
+ declare class SkeletalRenderer extends Component {
1025
+ private _group;
1026
+ private _assetPath;
1027
+ private _material;
1028
+ private _skeletalModel;
1029
+ constructor(assetPath: string, material?: THREE.Material);
1030
+ protected onCreate(): void;
1031
+ private createSkeletalMesh;
1032
+ private applyShadowsToGroup;
1033
+ /**
1034
+ * Get the wrapper group (attached to GameObject)
1035
+ */
1036
+ getGroup(): THREE.Group | null;
1037
+ /**
1038
+ * Get the skeletal model (for animation setup)
1039
+ */
1040
+ getSkeletalModel(): THREE.Object3D | null;
1041
+ /**
1042
+ * Get the asset path being rendered
1043
+ */
1044
+ getAssetPath(): string;
1045
+ /**
1046
+ * Enable or disable visibility
1047
+ */
1048
+ setVisible(visible: boolean): void;
1049
+ /**
1050
+ * Get visibility state
1051
+ */
1052
+ isVisible(): boolean;
1053
+ protected onCleanup(): void;
1054
+ onEnabled(): void;
1055
+ onDisabled(): void;
1056
+ }
1057
+
1058
+ /**
1059
+ * Per-instance data stored in a batch
1060
+ */
1061
+ interface InstanceData {
1062
+ id: string;
1063
+ gameObject: GameObject;
1064
+ matrix: THREE.Matrix4;
1065
+ isActive: boolean;
1066
+ isDynamic: boolean;
1067
+ isDirty: boolean;
1068
+ }
1069
+ /**
1070
+ * A batch of instances sharing the same geometry and material
1071
+ */
1072
+ interface InstanceBatch {
1073
+ batchKey: string;
1074
+ instancedMesh: THREE.InstancedMesh;
1075
+ dynamicInstances: InstanceData[];
1076
+ staticInstances: InstanceData[];
1077
+ instanceMap: Map<string, InstanceData>;
1078
+ maxInstances: number;
1079
+ geometry: THREE.BufferGeometry;
1080
+ material: THREE.Material;
1081
+ needsRebuild: boolean;
1082
+ hasStaticDirty: boolean;
1083
+ }
1084
+ /**
1085
+ * Statistics for debugging
1086
+ */
1087
+ interface InstanceStats {
1088
+ batchKeys: string[];
1089
+ totalInstances: number;
1090
+ batchCount: number;
1091
+ instancesPerBatch: Map<string, number>;
1092
+ }
1093
+ /**
1094
+ * Singleton manager for GPU-instanced meshes.
1095
+ *
1096
+ * This is a generic instancing system that works with any geometry + material combination.
1097
+ * Games provide the geometry and material when creating a batch, and the manager handles
1098
+ * the THREE.InstancedMesh creation and per-frame matrix updates.
1099
+ *
1100
+ * Performance optimizations:
1101
+ * - Reuses temporary Vector3/Quaternion/Matrix4 objects (no per-frame allocations)
1102
+ * - Uses Map for O(1) instance lookups
1103
+ * - Only updates GPU when batch is marked dirty
1104
+ * - Uses instancedMesh.count instead of writing zero-matrices
1105
+ *
1106
+ * Usage pattern:
1107
+ * ```typescript
1108
+ * // 1. Initialize (once, during game setup)
1109
+ * InstancedMeshManager.getInstance().initialize(scene)
1110
+ *
1111
+ * // 2. Register a batch (once per unique mesh type)
1112
+ * manager.getOrCreateBatch("burger", burgerGeometry, burgerMaterial)
1113
+ *
1114
+ * // 3. Add instances (via InstancedRenderer component or directly)
1115
+ * const instanceId = manager.addInstance("burger", gameObject)
1116
+ *
1117
+ * // 4. Update every frame
1118
+ * manager.updateAllBatches()
1119
+ * ```
1120
+ */
1121
+ declare class InstancedMeshManager {
1122
+ private static _instance;
1123
+ private scene;
1124
+ private batches;
1125
+ private isInitialized;
1126
+ private static readonly INITIAL_CAPACITY;
1127
+ private static readonly GROWTH_FACTOR;
1128
+ private readonly _tempPosition;
1129
+ private readonly _tempQuaternion;
1130
+ private readonly _tempScale;
1131
+ private constructor();
1132
+ /**
1133
+ * Get the singleton instance
1134
+ */
1135
+ static getInstance(): InstancedMeshManager;
1136
+ /**
1137
+ * Initialize the manager with a scene reference.
1138
+ * Must be called before creating batches.
1139
+ * @param scene The THREE.Scene to add InstancedMesh objects to
1140
+ */
1141
+ initialize(scene: THREE.Scene): void;
1142
+ /**
1143
+ * Check if the manager is initialized
1144
+ */
1145
+ isReady(): boolean;
1146
+ /**
1147
+ * Get or create a batch for a given key.
1148
+ * If the batch already exists, returns it (geometry/material params are ignored).
1149
+ * If not, creates a new batch with the provided geometry and material.
1150
+ *
1151
+ * @param batchKey Unique identifier for this batch (e.g., "burger", "tree_pine")
1152
+ * @param geometry BufferGeometry to use for all instances
1153
+ * @param material Material to use for all instances
1154
+ * @param castShadow Whether instances cast shadows (default: false)
1155
+ * @param receiveShadow Whether instances receive shadows (default: false)
1156
+ * @param initialCapacity Starting capacity (will grow automatically). Default: 16
1157
+ * @returns The batch, or null if manager not initialized
1158
+ */
1159
+ getOrCreateBatch(batchKey: string, geometry: THREE.BufferGeometry, material: THREE.Material, castShadow?: boolean, receiveShadow?: boolean, initialCapacity?: number): InstanceBatch | null;
1160
+ /**
1161
+ * Create a batch automatically from a GameObject's mesh.
1162
+ * Extracts geometry and material from the first Mesh found in the GameObject.
1163
+ */
1164
+ getOrCreateBatchFromGameObject(batchKey: string, gameObject: GameObject, castShadow?: boolean, receiveShadow?: boolean, initialCapacity?: number): InstanceBatch | null;
1165
+ /**
1166
+ * Round up to the next power of 2
1167
+ */
1168
+ private nextPowerOf2;
1169
+ /**
1170
+ * Resize a batch to a new capacity (must be larger than current)
1171
+ */
1172
+ private resizeBatch;
1173
+ /**
1174
+ * Check if a batch exists for the given key
1175
+ */
1176
+ hasBatch(batchKey: string): boolean;
1177
+ /**
1178
+ * Get a batch by key (without creating it)
1179
+ */
1180
+ getBatch(batchKey: string): InstanceBatch | null;
1181
+ /**
1182
+ * Get total instance count for a batch
1183
+ */
1184
+ private getTotalInstanceCount;
1185
+ /**
1186
+ * Options for adding an instance
1187
+ */
1188
+ static readonly AddInstanceOptions: {
1189
+ isDynamic: boolean;
1190
+ castShadow: boolean;
1191
+ receiveShadow: boolean;
1192
+ initialCapacity: number | undefined;
1193
+ };
1194
+ /**
1195
+ * Add an instance to a batch.
1196
+ * If no batch exists, creates one automatically from the GameObject's mesh.
1197
+ * If batch is full, automatically resizes to accommodate more instances.
1198
+ *
1199
+ * @param batchKey The batch to add to
1200
+ * @param gameObject The GameObject whose transform will be used
1201
+ * @param options Configuration options (isDynamic, castShadow, receiveShadow, initialCapacity)
1202
+ * @returns Instance ID, or null if failed
1203
+ */
1204
+ addInstance(batchKey: string, gameObject: GameObject, options?: {
1205
+ isDynamic?: boolean;
1206
+ castShadow?: boolean;
1207
+ receiveShadow?: boolean;
1208
+ initialCapacity?: number;
1209
+ }): string | null;
1210
+ /**
1211
+ * Remove an instance from a batch
1212
+ * @param batchKey The batch to remove from
1213
+ * @param instanceId The instance ID to remove
1214
+ */
1215
+ removeInstance(batchKey: string, instanceId: string): void;
1216
+ /**
1217
+ * Set the visibility of a specific instance
1218
+ * @param batchKey The batch containing the instance
1219
+ * @param instanceId The instance ID
1220
+ * @param visible Whether the instance should be visible
1221
+ */
1222
+ setInstanceVisible(batchKey: string, instanceId: string, visible: boolean): void;
1223
+ /**
1224
+ * Get the visibility of a specific instance
1225
+ */
1226
+ getInstanceVisible(batchKey: string, instanceId: string): boolean;
1227
+ /**
1228
+ * Mark a static instance as dirty (needs matrix update next frame).
1229
+ * Call this when a static instance's transform changes.
1230
+ * No-op for dynamic instances (they update every frame anyway).
1231
+ */
1232
+ markInstanceDirty(batchKey: string, instanceId: string): void;
1233
+ /**
1234
+ * Set whether an instance is dynamic (updates every frame) or static (only when dirty).
1235
+ * Use this when an item transitions between moving and stationary states.
1236
+ */
1237
+ setInstanceDynamic(batchKey: string, instanceId: string, isDynamic: boolean): void;
1238
+ /**
1239
+ * Update the matrix for a single instance from its GameObject.
1240
+ * Uses reusable temp objects to avoid per-frame allocations.
1241
+ */
1242
+ private updateInstanceMatrix;
1243
+ /**
1244
+ * Update a single batch - sync matrices and upload to GPU.
1245
+ * Optimized to only update what's necessary:
1246
+ * - Dynamic instances: always update matrix
1247
+ * - Static instances: only update if marked dirty
1248
+ * - GPU upload: only if anything changed
1249
+ */
1250
+ private updateBatch;
1251
+ /**
1252
+ * Update all batches - call this every frame.
1253
+ * Optimized to skip batches with no changes.
1254
+ */
1255
+ updateAllBatches(): void;
1256
+ /**
1257
+ * Get statistics for debugging
1258
+ */
1259
+ getStats(): InstanceStats;
1260
+ /**
1261
+ * Print a debug report to console
1262
+ */
1263
+ debugReport(): void;
1264
+ /**
1265
+ * Remove a batch entirely
1266
+ */
1267
+ removeBatch(batchKey: string): void;
1268
+ /**
1269
+ * Dispose of all batches and reset the manager
1270
+ */
1271
+ dispose(): void;
1272
+ /**
1273
+ * Reset the singleton (for testing)
1274
+ */
1275
+ static reset(): void;
1276
+ }
1277
+
1278
+ /**
1279
+ * Options for InstancedRenderer
1280
+ */
1281
+ interface InstancedRendererOptions {
1282
+ /** If true (default), matrix updates every frame. If false, only updates when markDirty() is called. */
1283
+ isDynamic?: boolean;
1284
+ /** Whether instances cast shadows (default: false). Only used if batch is auto-created. */
1285
+ castShadow?: boolean;
1286
+ /** Whether instances receive shadows (default: false). Only used if batch is auto-created. */
1287
+ receiveShadow?: boolean;
1288
+ /** Initial batch capacity (default: 16, grows automatically). Only used if batch is auto-created. */
1289
+ initialCapacity?: number;
1290
+ }
1291
+ /**
1292
+ * Component for rendering objects using GPU instancing.
1293
+ *
1294
+ * Transform is controlled by the GameObject - the manager syncs matrices every frame.
1295
+ * If no batch exists for the key, one is created automatically from the GameObject's mesh.
1296
+ *
1297
+ * Performance modes:
1298
+ * - Dynamic (default): Matrix updates every frame. Use for moving objects.
1299
+ * - Static: Matrix only updates when markDirty() is called. Use for stationary objects.
1300
+ *
1301
+ * Usage:
1302
+ * ```typescript
1303
+ * // Simple - batch auto-creates from GameObject's mesh
1304
+ * gameObject.addComponent(new InstancedRenderer("burger"))
1305
+ *
1306
+ * // With options
1307
+ * gameObject.addComponent(new InstancedRenderer("burger", {
1308
+ * isDynamic: false,
1309
+ * castShadow: true
1310
+ * }))
1311
+ *
1312
+ * // For stationary objects, switch to static mode
1313
+ * renderer.setDynamic(false)
1314
+ *
1315
+ * // When a static object moves, mark it dirty
1316
+ * renderer.markDirty()
1317
+ * ```
1318
+ *
1319
+ * Key differences from mesh-based renderers (ObjRenderer, etc.):
1320
+ * - No getMesh() - instances don't have their own THREE.Object3D
1321
+ * - No getBounds() - can query the batch geometry if needed
1322
+ * - All instances share the same geometry and material
1323
+ */
1324
+ declare class InstancedRenderer extends Component {
1325
+ private readonly batchKey;
1326
+ private readonly options;
1327
+ private instanceId;
1328
+ /**
1329
+ * Create an InstancedRenderer
1330
+ * @param batchKey The batch key to register with. If no batch exists, one is auto-created.
1331
+ * @param options Configuration options (or just pass `true`/`false` for isDynamic)
1332
+ */
1333
+ constructor(batchKey: string, options?: InstancedRendererOptions | boolean);
1334
+ /**
1335
+ * Register with the batch when the component is created.
1336
+ * If no batch exists, one will be created automatically from this GameObject's mesh.
1337
+ */
1338
+ protected onCreate(): void;
1339
+ /**
1340
+ * Set the visibility of this instance
1341
+ */
1342
+ setVisible(visible: boolean): void;
1343
+ /**
1344
+ * Get the visibility of this instance
1345
+ */
1346
+ getVisible(): boolean;
1347
+ /**
1348
+ * Show the instance (convenience method)
1349
+ */
1350
+ show(): void;
1351
+ /**
1352
+ * Hide the instance (convenience method)
1353
+ */
1354
+ hide(): void;
1355
+ /**
1356
+ * Get the batch key this renderer is registered with
1357
+ */
1358
+ getBatchKey(): string;
1359
+ /**
1360
+ * Check if this renderer is successfully registered with a batch
1361
+ */
1362
+ isRegistered(): boolean;
1363
+ /**
1364
+ * Get the instance ID (for debugging)
1365
+ */
1366
+ getInstanceId(): string | null;
1367
+ /**
1368
+ * Mark this instance as needing a matrix update.
1369
+ * Only relevant for static instances - dynamic instances update every frame anyway.
1370
+ * Call this when the transform of a static instance changes.
1371
+ */
1372
+ markDirty(): void;
1373
+ /**
1374
+ * Set whether this instance is dynamic (updates every frame) or static (only when marked dirty).
1375
+ * Use this to optimize performance when items transition between moving and stationary states.
1376
+ * @param isDynamic If true, updates every frame. If false, only updates when markDirty() is called.
1377
+ */
1378
+ setDynamic(isDynamic: boolean): void;
1379
+ /**
1380
+ * Called when the GameObject becomes enabled
1381
+ */
1382
+ onEnabled(): void;
1383
+ /**
1384
+ * Called when the GameObject becomes disabled
1385
+ */
1386
+ onDisabled(): void;
1387
+ /**
1388
+ * Unregister from the batch when the component is cleaned up
1389
+ */
1390
+ protected onCleanup(): void;
1391
+ }
1392
+
1393
+ interface StowMeshJSON extends ComponentJSON {
1394
+ type: "stow_mesh";
1395
+ mesh: {
1396
+ pack: string;
1397
+ assetId: string;
1398
+ };
1399
+ castShadow?: boolean;
1400
+ receiveShadow?: boolean;
1401
+ }
1402
+ /**
1403
+ * MeshRenderer - Component for rendering a mesh from StowKitSystem.
1404
+ *
1405
+ * This is a non-instanced renderer - each instance is a separate draw call.
1406
+ * Use InstancedRenderer for many instances of the same mesh (better performance).
1407
+ *
1408
+ * Usage:
1409
+ * ```typescript
1410
+ * const env = new GameObject("Environment")
1411
+ * env.addComponent(new MeshRenderer("restaurant_display_common"))
1412
+ * ```
1413
+ */
1414
+ declare class MeshRenderer extends Component {
1415
+ static fromPrefabJSON(json: StowMeshJSON, _node: PrefabNode): MeshRenderer;
1416
+ private mesh;
1417
+ private readonly meshName;
1418
+ private readonly castShadow;
1419
+ private readonly receiveShadow;
1420
+ private _isStatic;
1421
+ private isMeshLoaded;
1422
+ private materialOverride;
1423
+ /**
1424
+ * @param meshName The name of the mesh in the StowKit pack
1425
+ * @param castShadow Whether meshes should cast shadows (default: true)
1426
+ * @param receiveShadow Whether meshes should receive shadows (default: true)
1427
+ * @param isStatic Whether this mesh is static (default: false). Static meshes have matrixAutoUpdate disabled for better performance.
1428
+ * @param materialOverride Optional material to use instead of the default StowKit material
1429
+ */
1430
+ constructor(meshName: string, castShadow?: boolean, receiveShadow?: boolean, isStatic?: boolean, materialOverride?: THREE.Material | null);
1431
+ protected onCreate(): void;
1432
+ update(_deltaTime: number): void;
1433
+ private addMesh;
1434
+ /**
1435
+ * Apply the material override to all meshes
1436
+ */
1437
+ private applyMaterialOverride;
1438
+ /**
1439
+ * Set a material override for all meshes in this renderer.
1440
+ * Call this after the mesh is loaded, or pass it in the constructor.
1441
+ */
1442
+ setMaterial(material: THREE.Material): void;
1443
+ /**
1444
+ * Check if this mesh is currently static (no automatic matrix updates)
1445
+ */
1446
+ get isStatic(): boolean;
1447
+ /**
1448
+ * Set whether this mesh is static (no automatic matrix updates).
1449
+ * Static meshes save CPU by not recalculating transforms every frame.
1450
+ * Call forceMatrixUpdate() after moving a static mesh.
1451
+ */
1452
+ setStatic(isStatic: boolean): void;
1453
+ /**
1454
+ * Force a one-time matrix update. Call this after moving a static mesh.
1455
+ * Does not change the static/dynamic state.
1456
+ */
1457
+ forceMatrixUpdate(): void;
1458
+ /**
1459
+ * Get the mesh group (null if not yet loaded)
1460
+ */
1461
+ getMesh(): THREE.Group | null;
1462
+ /**
1463
+ * Get the name of the mesh this component is managing
1464
+ */
1465
+ getMeshName(): string;
1466
+ /**
1467
+ * Check if the mesh was successfully loaded
1468
+ */
1469
+ isLoaded(): boolean;
1470
+ /**
1471
+ * Set the visibility of the mesh
1472
+ */
1473
+ setVisible(visible: boolean): void;
1474
+ /**
1475
+ * Get bounds of the mesh (useful for physics)
1476
+ */
1477
+ getBounds(): THREE.Vector3 | null;
1478
+ /**
1479
+ * Cleanup - remove mesh from scene and dispose of resources
1480
+ */
1481
+ protected onCleanup(): void;
1482
+ }
1483
+
1484
+ export { AssetManager, Component, ComponentUpdater, GameObject, InstancedMeshManager, InstancedRenderer, type InstancedRendererOptions, InteractionZone, type InteractionZoneOptions, MeshRenderer, MovementController, PlayerControllerThree, SkeletalRenderer, SkeletonCache, VenusGame, type VenusGameConfig, type VirtualJoystickOptions, VirtualJoystickThree };