@zylem/game-lib 0.6.3 → 0.6.4

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 (74) hide show
  1. package/dist/actions.d.ts +5 -5
  2. package/dist/actions.js +196 -32
  3. package/dist/actions.js.map +1 -1
  4. package/dist/behavior/jumper-2d.d.ts +114 -0
  5. package/dist/behavior/jumper-2d.js +711 -0
  6. package/dist/behavior/jumper-2d.js.map +1 -0
  7. package/dist/behavior/platformer-3d.d.ts +14 -14
  8. package/dist/behavior/platformer-3d.js +347 -104
  9. package/dist/behavior/platformer-3d.js.map +1 -1
  10. package/dist/behavior/ricochet-2d.d.ts +4 -3
  11. package/dist/behavior/ricochet-2d.js +53 -22
  12. package/dist/behavior/ricochet-2d.js.map +1 -1
  13. package/dist/behavior/ricochet-3d.d.ts +117 -0
  14. package/dist/behavior/ricochet-3d.js +443 -0
  15. package/dist/behavior/ricochet-3d.js.map +1 -0
  16. package/dist/behavior/screen-visibility.d.ts +79 -0
  17. package/dist/behavior/screen-visibility.js +358 -0
  18. package/dist/behavior/screen-visibility.js.map +1 -0
  19. package/dist/behavior/screen-wrap.d.ts +4 -3
  20. package/dist/behavior/screen-wrap.js +100 -49
  21. package/dist/behavior/screen-wrap.js.map +1 -1
  22. package/dist/behavior/shooter-2d.d.ts +79 -0
  23. package/dist/behavior/shooter-2d.js +180 -0
  24. package/dist/behavior/shooter-2d.js.map +1 -0
  25. package/dist/behavior/thruster.d.ts +5 -4
  26. package/dist/behavior/thruster.js +133 -75
  27. package/dist/behavior/thruster.js.map +1 -1
  28. package/dist/behavior/top-down-movement.d.ts +56 -0
  29. package/dist/behavior/top-down-movement.js +125 -0
  30. package/dist/behavior/top-down-movement.js.map +1 -0
  31. package/dist/behavior/world-boundary-2d.d.ts +4 -3
  32. package/dist/behavior/world-boundary-2d.js +90 -36
  33. package/dist/behavior/world-boundary-2d.js.map +1 -1
  34. package/dist/behavior/world-boundary-3d.d.ts +76 -0
  35. package/dist/behavior/world-boundary-3d.js +274 -0
  36. package/dist/behavior/world-boundary-3d.js.map +1 -0
  37. package/dist/{behavior-descriptor-BWNWmIjv.d.ts → behavior-descriptor-BXnVR8Ki.d.ts} +22 -5
  38. package/dist/{blueprints-BWGz8fII.d.ts → blueprints-DmbK2dki.d.ts} +2 -2
  39. package/dist/camera-4XO5gbQH.d.ts +905 -0
  40. package/dist/camera.d.ts +1 -1
  41. package/dist/camera.js +876 -289
  42. package/dist/camera.js.map +1 -1
  43. package/dist/{composition-DrzFrbqI.d.ts → composition-BASvMKrW.d.ts} +1 -1
  44. package/dist/{core-DAkskq6Y.d.ts → core-CARRaS55.d.ts} +57 -14
  45. package/dist/core.d.ts +9 -8
  46. package/dist/core.js +4519 -1255
  47. package/dist/core.js.map +1 -1
  48. package/dist/{entities-DC9ce_vx.d.ts → entities-ChFirVL9.d.ts} +22 -28
  49. package/dist/entities.d.ts +4 -4
  50. package/dist/entities.js +1231 -314
  51. package/dist/entities.js.map +1 -1
  52. package/dist/{entity-BpbZqg19.d.ts → entity-vj-HTjzU.d.ts} +80 -11
  53. package/dist/{global-change-Dc8uCKi2.d.ts → global-change-2JvMaz44.d.ts} +1 -1
  54. package/dist/main.d.ts +718 -19
  55. package/dist/main.js +12129 -5959
  56. package/dist/main.js.map +1 -1
  57. package/dist/physics-pose-DCc4oE44.d.ts +25 -0
  58. package/dist/physics-protocol-BDD3P5W2.d.ts +200 -0
  59. package/dist/physics-worker.d.ts +21 -0
  60. package/dist/physics-worker.js +306 -0
  61. package/dist/physics-worker.js.map +1 -0
  62. package/dist/physics.d.ts +205 -0
  63. package/dist/physics.js +577 -0
  64. package/dist/physics.js.map +1 -0
  65. package/dist/{stage-types-BFsm3qsZ.d.ts → stage-types-C19IhuzA.d.ts} +253 -89
  66. package/dist/stage.d.ts +9 -8
  67. package/dist/stage.js +3782 -1041
  68. package/dist/stage.js.map +1 -1
  69. package/dist/sync-state-machine-CZyspBpj.d.ts +16 -0
  70. package/dist/{thruster-DhRaJnoL.d.ts → thruster-23lzoPZd.d.ts} +16 -8
  71. package/dist/world-DfgxoNMt.d.ts +105 -0
  72. package/package.json +25 -1
  73. package/dist/camera-B5e4c78l.d.ts +0 -468
  74. package/dist/world-Be5m1XC1.d.ts +0 -31
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/camera/camera.ts","../src/lib/camera/zylem-camera.ts","../src/lib/camera/perspective.ts","../src/lib/camera/third-person.ts","../src/lib/camera/fixed-2d.ts","../src/lib/camera/camera-debug-delegate.ts","../src/lib/camera/renderer-manager.ts","../src/lib/graphics/render-pass.ts","../src/lib/graphics/shaders/vertex/object.shader.ts","../src/lib/graphics/shaders/standard.shader.ts","../src/lib/camera/camera-manager.ts"],"sourcesContent":["import { Vector2, Vector3 } from \"three\";\nimport { PerspectiveType } from \"./perspective\";\nimport { ZylemCamera } from \"./zylem-camera\";\nimport { RendererType, Viewport, DEFAULT_VIEWPORT } from \"./renderer-manager\";\nimport { StageEntity } from \"../interfaces/entity\";\n\nexport interface CameraOptions {\n\tperspective?: PerspectiveType;\n\tposition?: Vector3 | { x: number; y: number; z: number };\n\ttarget?: Vector3 | { x: number; y: number; z: number } | any;\n\tzoom?: number;\n\tscreenResolution?: Vector2;\n\t/**\n\t * Renderer type: 'auto' | 'webgpu' | 'webgl'\n\t * Use 'webgpu' for TSL shaders\n\t * @default 'webgl'\n\t */\n\trendererType?: RendererType;\n\t/**\n\t * Enable orbital controls for this camera.\n\t * Can be toggled at runtime via enableOrbitalControls() / disableOrbitalControls().\n\t * @default false\n\t */\n\tuseOrbitalControls?: boolean;\n\t/**\n\t * Viewport in normalized coordinates (0-1).\n\t * Defines where this camera renders on the canvas.\n\t * @default { x: 0, y: 0, width: 1, height: 1 } (fullscreen)\n\t */\n\tviewport?: Viewport;\n\t/**\n\t * Optional name for camera manager lookup.\n\t */\n\tname?: string;\n}\n\n/**\n * CameraWrapper is the user-facing camera handle returned by createCamera().\n * It provides convenience methods for target management, orbital controls, and viewport configuration.\n */\nexport class CameraWrapper {\n\tcameraRef: ZylemCamera;\n\n\tconstructor(camera: ZylemCamera) {\n\t\tthis.cameraRef = camera;\n\t}\n\n\t// ─── Target management ──────────────────────────────────────────────────\n\n\t/**\n\t * Add a target entity for the camera to follow/frame.\n\t * With multiple targets, the camera auto-frames to include all of them.\n\t */\n\taddTarget(entity: StageEntity): void {\n\t\tthis.cameraRef.addTarget(entity);\n\t}\n\n\t/**\n\t * Remove a target entity from the camera.\n\t */\n\tremoveTarget(entity: StageEntity): void {\n\t\tthis.cameraRef.removeTarget(entity);\n\t}\n\n\t/**\n\t * Clear all targets. Camera will look at world origin.\n\t */\n\tclearTargets(): void {\n\t\tthis.cameraRef.clearTargets();\n\t}\n\n\t// ─── Orbital controls ───────────────────────────────────────────────────\n\n\t/**\n\t * Enable orbital controls for this camera.\n\t * Allows the user to orbit, pan, and zoom the camera.\n\t */\n\tenableOrbitalControls(): void {\n\t\tthis.cameraRef.enableOrbitalControls();\n\t}\n\n\t/**\n\t * Disable orbital controls for this camera.\n\t */\n\tdisableOrbitalControls(): void {\n\t\tthis.cameraRef.disableOrbitalControls();\n\t}\n\n\t// ─── Viewport ───────────────────────────────────────────────────────────\n\n\t/**\n\t * Set the viewport for this camera (normalized 0-1 coordinates).\n\t * @param x Left edge (0 = left of canvas)\n\t * @param y Bottom edge (0 = bottom of canvas)\n\t * @param width Width as fraction of canvas\n\t * @param height Height as fraction of canvas\n\t */\n\tsetViewport(x: number, y: number, width: number, height: number): void {\n\t\tthis.cameraRef.setViewport(x, y, width, height);\n\t}\n}\n\n/**\n * Create a camera with the given options.\n * Returns a CameraWrapper for convenient access to camera features.\n */\nexport function createCamera(options: CameraOptions): CameraWrapper {\n\tconst screenResolution = options.screenResolution || new Vector2(window.innerWidth, window.innerHeight);\n\tlet frustumSize = 10;\n\tif (options.perspective === 'fixed-2d') {\n\t\tfrustumSize = options.zoom || 10;\n\t}\n\tconst zylemCamera = new ZylemCamera(\n\t\toptions.perspective || 'third-person',\n\t\tscreenResolution,\n\t\tfrustumSize,\n\t\toptions.rendererType || 'webgl'\n\t);\n\n\t// Set camera name if provided\n\tif (options.name) {\n\t\tzylemCamera.name = options.name;\n\t}\n\n\t// Set initial position and target\n\tconst position = options.position \n\t\t? (options.position instanceof Vector3 ? options.position : new Vector3(options.position.x, options.position.y, options.position.z))\n\t\t: new Vector3(0, 0, 0);\n\t\n\tconst target = options.target\n\t\t? (options.target instanceof Vector3 ? options.target : new Vector3(options.target.x, options.target.y, options.target.z))\n\t\t: new Vector3(0, 0, 0);\n\t\n\tzylemCamera.move(position);\n\tzylemCamera.camera.lookAt(target);\n\n\t// Set viewport if provided\n\tif (options.viewport) {\n\t\tzylemCamera.viewport = { ...options.viewport };\n\t}\n\n\t// Configure orbital controls\n\tif (options.useOrbitalControls) {\n\t\t// Mark for enablement -- actual OrbitControls are created during setup()\n\t\t// when the renderer DOM element is available\n\t\t(zylemCamera as any)._useOrbitalControls = true;\n\t}\n\n\treturn new CameraWrapper(zylemCamera);\n}\n","import { Vector2, Camera, PerspectiveCamera, Vector3, Object3D, OrthographicCamera, Scene } from 'three';\nimport { PerspectiveType, Perspectives } from './perspective';\nimport { ThirdPersonCamera } from './third-person';\nimport { Fixed2DCamera } from './fixed-2d';\nimport { StageEntity } from '../interfaces/entity';\nimport { CameraOrbitController, CameraDebugDelegate } from './camera-debug-delegate';\nimport { RendererManager, DEFAULT_VIEWPORT } from './renderer-manager';\nimport type { ZylemRenderer, RendererType, Viewport } from './renderer-manager';\n\n// Re-export for backwards compatibility\nexport type { CameraDebugState, CameraDebugDelegate } from './camera-debug-delegate';\nexport type { RendererType, ZylemRenderer } from './renderer-manager';\nexport { isWebGPUSupported } from './renderer-manager';\n\n/**\n * Interface for perspective-specific camera controllers\n */\nexport interface PerspectiveController {\n\tsetup(params: { screenResolution: Vector2; renderer: ZylemRenderer; scene: Scene; camera: ZylemCamera }): void;\n\tupdate(delta: number): void;\n\tresize(width: number, height: number): void;\n}\n\n/**\n * ZylemCamera is a lightweight camera wrapper that manages the Three.js camera,\n * perspective controller, and viewport configuration. It no longer owns a renderer;\n * rendering is handled by RendererManager.\n */\nexport class ZylemCamera {\n\tcameraRig: Object3D | null = null;\n\tcamera: Camera;\n\tscreenResolution: Vector2;\n\t_perspective: PerspectiveType;\n\tfrustumSize = 10;\n\trendererType: RendererType;\n\tsceneRef: Scene | null = null;\n\n\t/** Name for camera manager lookup */\n\tname: string = '';\n\n\t/**\n\t * Viewport in normalized coordinates (0-1).\n\t * Default is fullscreen: { x: 0, y: 0, width: 1, height: 1 }\n\t */\n\tviewport: Viewport = { ...DEFAULT_VIEWPORT };\n\n\t/**\n\t * Multiple targets for the camera to follow/frame.\n\t * Replaces the old single `target` property.\n\t */\n\ttargets: StageEntity[] = [];\n\n\t/**\n\t * @deprecated Use `targets` array instead. This getter/setter is kept for backward compatibility.\n\t */\n\tget target(): StageEntity | null {\n\t\treturn this.targets.length > 0 ? this.targets[0] : null;\n\t}\n\n\tset target(entity: StageEntity | null) {\n\t\tif (entity) {\n\t\t\tif (this.targets.length === 0) {\n\t\t\t\tthis.targets.push(entity);\n\t\t\t} else {\n\t\t\t\tthis.targets[0] = entity;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.targets = [];\n\t\t}\n\t}\n\n\t// Perspective controller delegation\n\tperspectiveController: PerspectiveController | null = null;\n\n\t// Orbit controls\n\tprivate orbitController: CameraOrbitController | null = null;\n\tprivate _useOrbitalControls = false;\n\n\t/** Reference to the shared renderer manager (set during setup) */\n\tprivate _rendererManager: RendererManager | null = null;\n\n\tconstructor(perspective: PerspectiveType, screenResolution: Vector2, frustumSize: number = 10, rendererType: RendererType = 'webgl') {\n\t\tthis._perspective = perspective;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.frustumSize = frustumSize;\n\t\tthis.rendererType = rendererType;\n\n\t\t// Create camera based on perspective\n\t\tconst aspectRatio = screenResolution.x / screenResolution.y;\n\t\tthis.camera = this.createCameraForPerspective(aspectRatio);\n\n\t\t// Setup camera rig only for perspectives that need it (e.g., third-person following)\n\t\tif (this.needsRig()) {\n\t\t\tthis.cameraRig = new Object3D();\n\t\t\tthis.cameraRig.position.set(0, 3, 10);\n\t\t\tthis.cameraRig.add(this.camera);\n\t\t\tthis.camera.lookAt(new Vector3(0, 2, 0));\n\t\t} else {\n\t\t\t// Position camera directly for non-rig perspectives\n\t\t\tthis.camera.position.set(0, 0, 10);\n\t\t\tthis.camera.lookAt(new Vector3(0, 0, 0));\n\t\t}\n\n\t\t// Initialize perspective controller\n\t\tthis.initializePerspectiveController();\n\t}\n\n\t/**\n\t * Setup the camera with a scene and renderer manager.\n\t * The renderer manager provides shared rendering infrastructure.\n\t */\n\tasync setup(scene: Scene, rendererManager?: RendererManager): Promise<void> {\n\t\tthis.sceneRef = scene;\n\n\t\tif (rendererManager) {\n\t\t\tthis._rendererManager = rendererManager;\n\t\t}\n\n\t\t// Ensure renderer manager is initialized\n\t\tif (this._rendererManager && !this._rendererManager.initialized) {\n\t\t\tawait this._rendererManager.initRenderer();\n\t\t}\n\n\t\t// Setup perspective controller\n\t\tif (this.perspectiveController && this._rendererManager) {\n\t\t\tthis.perspectiveController.setup({\n\t\t\t\tscreenResolution: this.screenResolution,\n\t\t\t\trenderer: this._rendererManager.renderer,\n\t\t\t\tscene: scene,\n\t\t\t\tcamera: this\n\t\t\t});\n\t\t}\n\n\t\t// Initialize orbit controller if renderer is available\n\t\tif (this._rendererManager) {\n\t\t\tthis.orbitController = new CameraOrbitController(\n\t\t\t\tthis.camera,\n\t\t\t\tthis._rendererManager.renderer.domElement,\n\t\t\t\tthis.cameraRig\n\t\t\t);\n\t\t\tthis.orbitController.setScene(scene);\n\n\t\t\t// If orbital controls were requested, enable them\n\t\t\tif (this._useOrbitalControls) {\n\t\t\t\tthis.orbitController.enableUserOrbitControls();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Legacy setup method for backward compatibility.\n\t * Creates a temporary RendererManager internally.\n\t * @deprecated Use setup(scene, rendererManager) instead.\n\t */\n\tasync setupLegacy(scene: Scene): Promise<void> {\n\t\tif (!this._rendererManager) {\n\t\t\tthis._rendererManager = new RendererManager(this.screenResolution, this.rendererType);\n\t\t\tawait this._rendererManager.initRenderer();\n\n\t\t\t// Setup render pass for WebGL\n\t\t\tthis._rendererManager.setupRenderPass(scene, this.camera);\n\n\t\t\t// Start render loop\n\t\t\tthis._rendererManager.startRenderLoop((delta) => {\n\t\t\t\tthis.update(delta);\n\t\t\t\tif (this._rendererManager && this.sceneRef) {\n\t\t\t\t\tthis._rendererManager.render(this.sceneRef, this.camera);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tawait this.setup(scene, this._rendererManager);\n\t}\n\n\t/**\n\t * Update camera controllers (called each frame).\n\t * Does NOT render -- rendering is handled by RendererManager.\n\t */\n\tupdate(delta: number): void {\n\t\t// Update orbit controls (if debug mode or user orbital controls enabled)\n\t\tthis.orbitController?.update();\n\n\t\t// Skip perspective controller updates when orbit controls are active\n\t\tif (this.perspectiveController && !this.isDebugModeActive() && !this._useOrbitalControls) {\n\t\t\tthis.perspectiveController.update(delta);\n\t\t}\n\t}\n\n\t/**\n\t * Check if debug mode is active (orbit controls taking over camera)\n\t */\n\tisDebugModeActive(): boolean {\n\t\treturn this.orbitController?.isActive ?? false;\n\t}\n\n\t/**\n\t * Enable user-configured orbital controls (not debug mode).\n\t */\n\tenableOrbitalControls(): void {\n\t\tthis._useOrbitalControls = true;\n\t\tthis.orbitController?.enableUserOrbitControls();\n\t}\n\n\t/**\n\t * Disable user-configured orbital controls.\n\t */\n\tdisableOrbitalControls(): void {\n\t\tthis._useOrbitalControls = false;\n\t\tthis.orbitController?.disableUserOrbitControls();\n\t}\n\n\t/**\n\t * Whether user orbital controls are enabled.\n\t */\n\tget useOrbitalControls(): boolean {\n\t\treturn this._useOrbitalControls;\n\t}\n\n\t/**\n\t * Add a target entity for the camera to follow/frame.\n\t */\n\taddTarget(entity: StageEntity): void {\n\t\tif (!this.targets.includes(entity)) {\n\t\t\tthis.targets.push(entity);\n\t\t}\n\t}\n\n\t/**\n\t * Remove a target entity.\n\t */\n\tremoveTarget(entity: StageEntity): void {\n\t\tconst index = this.targets.indexOf(entity);\n\t\tif (index !== -1) {\n\t\t\tthis.targets.splice(index, 1);\n\t\t}\n\t}\n\n\t/**\n\t * Clear all targets.\n\t */\n\tclearTargets(): void {\n\t\tthis.targets = [];\n\t}\n\n\t/**\n\t * Dispose camera resources (not the renderer -- that's managed by RendererManager).\n\t */\n\tdestroy(): void {\n\t\ttry {\n\t\t\tthis.orbitController?.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis.sceneRef = null;\n\t\tthis.targets = [];\n\t\tthis._rendererManager = null;\n\t}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null): void {\n\t\tthis.orbitController?.setDebugDelegate(delegate);\n\t}\n\n\t/**\n\t * Resize camera projection.\n\t */\n\tresize(width: number, height: number): void {\n\t\tthis.screenResolution.set(width, height);\n\n\t\tif (this.camera instanceof PerspectiveCamera) {\n\t\t\tthis.camera.aspect = width / height;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\n\t\tif (this.perspectiveController) {\n\t\t\tthis.perspectiveController.resize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Set the viewport for this camera (normalized 0-1 coordinates).\n\t */\n\tsetViewport(x: number, y: number, width: number, height: number): void {\n\t\tthis.viewport = { x, y, width, height };\n\t}\n\n\t/**\n\t * Create camera based on perspective type\n\t */\n\tprivate createCameraForPerspective(aspectRatio: number): Camera {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\treturn this.createThirdPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.FirstPerson:\n\t\t\t\treturn this.createFirstPersonCamera(aspectRatio);\n\t\t\tcase Perspectives.Isometric:\n\t\t\t\treturn this.createIsometricCamera(aspectRatio);\n\t\t\tcase Perspectives.Flat2D:\n\t\t\t\treturn this.createFlat2DCamera(aspectRatio);\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\treturn this.createFixed2DCamera(aspectRatio);\n\t\t\tdefault:\n\t\t\t\treturn this.createThirdPersonCamera(aspectRatio);\n\t\t}\n\t}\n\n\t/**\n\t * Initialize perspective-specific controller\n\t */\n\tprivate initializePerspectiveController(): void {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t\t\tbreak;\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\tthis.perspectiveController = new Fixed2DCamera();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthis.perspectiveController = new ThirdPersonCamera();\n\t\t}\n\t}\n\n\tprivate createThirdPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createFirstPersonCamera(aspectRatio: number): PerspectiveCamera {\n\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t}\n\n\tprivate createIsometricCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFlat2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn new OrthographicCamera(\n\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\tthis.frustumSize / 2,\n\t\t\tthis.frustumSize / -2,\n\t\t\t1,\n\t\t\t1000\n\t\t);\n\t}\n\n\tprivate createFixed2DCamera(aspectRatio: number): OrthographicCamera {\n\t\treturn this.createFlat2DCamera(aspectRatio);\n\t}\n\n\t// Movement methods\n\tprivate moveCamera(position: Vector3): void {\n\t\tif (this._perspective === Perspectives.Flat2D || this._perspective === Perspectives.Fixed2D) {\n\t\t\tthis.frustumSize = position.z;\n\t\t}\n\t\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.position.set(position.x, position.y, position.z);\n\t\t} else {\n\t\t\tthis.camera.position.set(position.x, position.y, position.z);\n\t\t}\n\t}\n\n\tmove(position: Vector3): void {\n\t\tthis.moveCamera(position);\n\t}\n\n\trotate(pitch: number, yaw: number, roll: number): void {\n\t\tif (this.cameraRig) {\n\t\t\tthis.cameraRig.rotateX(pitch);\n\t\t\tthis.cameraRig.rotateY(yaw);\n\t\t\tthis.cameraRig.rotateZ(roll);\n\t\t} else {\n\t\t\t(this.camera as Object3D).rotateX(pitch);\n\t\t\t(this.camera as Object3D).rotateY(yaw);\n\t\t\t(this.camera as Object3D).rotateZ(roll);\n\t\t}\n\t}\n\n\t/**\n\t * Check if this perspective type needs a camera rig\n\t */\n\tprivate needsRig(): boolean {\n\t\treturn this._perspective === Perspectives.ThirdPerson;\n\t}\n\n\t/**\n\t * Get the DOM element for the renderer.\n\t * @deprecated Access via RendererManager instead.\n\t */\n\tgetDomElement(): HTMLCanvasElement {\n\t\tif (this._rendererManager) {\n\t\t\treturn this._rendererManager.getDomElement();\n\t\t}\n\t\tthrow new Error('ZylemCamera: No renderer manager available. Call setup() first.');\n\t}\n\n\t/**\n\t * Get the renderer manager reference.\n\t */\n\tgetRendererManager(): RendererManager | null {\n\t\treturn this._rendererManager;\n\t}\n\n\t/**\n\t * Set the renderer manager reference (used by CameraManager during setup).\n\t */\n\tsetRendererManager(manager: RendererManager): void {\n\t\tthis._rendererManager = manager;\n\t}\n\n\t// ─── Legacy compatibility methods ────────────────────────────────────────\n\n\t/**\n\t * @deprecated Renderer is now owned by RendererManager\n\t */\n\tget renderer(): any {\n\t\treturn this._rendererManager?.renderer;\n\t}\n\n\t/**\n\t * @deprecated Composer is now owned by RendererManager\n\t */\n\tget composer(): any {\n\t\treturn this._rendererManager?.composer;\n\t}\n\n\t/**\n\t * @deprecated Use RendererManager.setPixelRatio() instead\n\t */\n\tsetPixelRatio(dpr: number): void {\n\t\tthis._rendererManager?.setPixelRatio(dpr);\n\t}\n}\n","export const Perspectives = {\n\tFirstPerson: 'first-person',\n\tThirdPerson: 'third-person',\n\tIsometric: 'isometric',\n\tFlat2D: 'flat-2d',\n\tFixed2D: 'fixed-2d',\n} as const;\n\nexport type PerspectiveType = (typeof Perspectives)[keyof typeof Perspectives];","import { Scene, Vector2, Vector3 } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\nimport { ZylemRenderer } from './renderer-manager';\n\n/**\n * Third-person camera controller that supports multiple targets.\n *\n * - 0 targets: stays at configured position, looks at world origin\n * - 1 target: classic third-person follow (lerp to target + offset)\n * - 2+ targets: weighted-center framing -- computes centroid of all targets,\n * zooms out based on max distance between them, and looks at centroid\n */\nexport class ThirdPersonCamera implements PerspectiveController {\n\tdistance: Vector3;\n\tscreenResolution: Vector2 | null = null;\n\trenderer: ZylemRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\t/** Padding multiplier when framing multiple targets. Higher = more zoom out. */\n\tpaddingFactor = 1.5;\n\n\t/** Minimum camera distance when multi-framing (prevents extreme zoom-in). */\n\tminDistance = 5;\n\n\t/** Lerp factor for camera position smoothing. */\n\tlerpFactor = 0.1;\n\n\tconstructor() {\n\t\tthis.distance = new Vector3(0, 5, 8);\n\t}\n\n\t/**\n\t * Setup the third person camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: ZylemRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\t}\n\n\t/**\n\t * Update the third person camera.\n\t * Handles 0, 1, and multi-target scenarios.\n\t */\n\tupdate(delta: number) {\n\t\tif (!this.cameraRef) return;\n\n\t\tconst targets = this.cameraRef.targets;\n\n\t\tif (targets.length === 0) {\n\t\t\t// No targets: look at world origin, stay at current position\n\t\t\tthis.cameraRef.camera.lookAt(new Vector3(0, 0, 0));\n\t\t\treturn;\n\t\t}\n\n\t\tif (targets.length === 1) {\n\t\t\t// Single target: classic third-person follow\n\t\t\tthis.updateSingleTarget(targets[0]);\n\t\t\treturn;\n\t\t}\n\n\t\t// Multiple targets: weighted-center framing\n\t\tthis.updateMultiTarget(targets);\n\t}\n\n\t/**\n\t * Classic single-target follow: lerp to target position + offset, lookAt target.\n\t */\n\tprivate updateSingleTarget(target: { group: { position: Vector3 } }) {\n\t\tconst useTarget = target.group?.position || new Vector3(0, 0, 0);\n\t\tconst desiredCameraPosition = useTarget.clone().add(this.distance);\n\t\tthis.cameraRef!.camera.position.lerp(desiredCameraPosition, this.lerpFactor);\n\t\tthis.cameraRef!.camera.lookAt(useTarget);\n\t}\n\n\t/**\n\t * Multi-target framing: compute centroid, measure spread, zoom out to fit all.\n\t */\n\tprivate updateMultiTarget(targets: Array<{ group: { position: Vector3 } }>) {\n\t\t// Compute centroid (average position of all targets)\n\t\tconst centroid = new Vector3();\n\t\tfor (const t of targets) {\n\t\t\tcentroid.add(t.group.position);\n\t\t}\n\t\tcentroid.divideScalar(targets.length);\n\n\t\t// Compute max distance from centroid to any target\n\t\tlet maxDistFromCentroid = 0;\n\t\tfor (const t of targets) {\n\t\t\tconst dist = centroid.distanceTo(t.group.position);\n\t\t\tif (dist > maxDistFromCentroid) {\n\t\t\t\tmaxDistFromCentroid = dist;\n\t\t\t}\n\t\t}\n\n\t\t// Scale the camera distance based on the spread of targets\n\t\tconst dynamicDistance = Math.max(maxDistFromCentroid * this.paddingFactor, this.minDistance);\n\n\t\t// Compute desired camera position: centroid + offset direction scaled by dynamic distance\n\t\tconst offsetDirection = this.distance.clone().normalize();\n\t\tconst desiredCameraPosition = centroid.clone().add(\n\t\t\toffsetDirection.multiplyScalar(dynamicDistance)\n\t\t);\n\n\t\t// Preserve the vertical offset proportionally\n\t\tconst baseLen = this.distance.length();\n\t\tif (baseLen > 0) {\n\t\t\tconst heightRatio = this.distance.y / baseLen;\n\t\t\tdesiredCameraPosition.y = centroid.y + dynamicDistance * heightRatio;\n\t\t}\n\n\t\t// Smooth camera movement\n\t\tthis.cameraRef!.camera.position.lerp(desiredCameraPosition, this.lerpFactor);\n\t\tthis.cameraRef!.camera.lookAt(centroid);\n\t}\n\n\t/**\n\t * Handle resize events\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Set the distance offset from the target\n\t */\n\tsetDistance(distance: Vector3) {\n\t\tthis.distance = distance;\n\t}\n}\n","import { Scene, Vector2 } from 'three';\nimport { PerspectiveController, ZylemCamera } from './zylem-camera';\nimport { ZylemRenderer } from './renderer-manager';\n\n/**\n * Fixed 2D Camera Controller\n * Maintains a static 2D camera view with no automatic following or movement\n */\nexport class Fixed2DCamera implements PerspectiveController {\n\tscreenResolution: Vector2 | null = null;\n\trenderer: ZylemRenderer | null = null;\n\tscene: Scene | null = null;\n\tcameraRef: ZylemCamera | null = null;\n\n\tconstructor() {\n\t\t// Fixed 2D camera doesn't need any initial setup parameters\n\t}\n\n\t/**\n\t * Setup the fixed 2D camera controller\n\t */\n\tsetup(params: { screenResolution: Vector2; renderer: ZylemRenderer; scene: Scene; camera: ZylemCamera }) {\n\t\tconst { screenResolution, renderer, scene, camera } = params;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.renderer = renderer;\n\t\tthis.scene = scene;\n\t\tthis.cameraRef = camera;\n\n\t\t// Position camera for 2D view (looking down the Z-axis)\n\t\tthis.cameraRef.camera.position.set(0, 0, 10);\n\t\tthis.cameraRef.camera.lookAt(0, 0, 0);\n\t}\n\n\t/**\n\t * Update the fixed 2D camera\n\t * Fixed cameras don't need to update position/rotation automatically\n\t */\n\tupdate(delta: number) {\n\t\t// Fixed 2D camera maintains its position and orientation\n\t\t// No automatic updates needed for a truly fixed camera\n\t}\n\n\t/**\n\t * Handle resize events for 2D camera\n\t */\n\tresize(width: number, height: number) {\n\t\tif (this.screenResolution) {\n\t\t\tthis.screenResolution.set(width, height);\n\t\t}\n\n\t\t// For orthographic cameras, we might need to adjust the frustum\n\t\t// This is handled in the main ZylemCamera resize method\n\t}\n}\n","import { Object3D, Vector3, Quaternion, Camera, Scene } from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\n\nexport interface CameraDebugState {\n\tenabled: boolean;\n\tselected: string[];\n}\n\nexport interface CameraDebugDelegate {\n\tsubscribe(listener: (state: CameraDebugState) => void): () => void;\n\tresolveTarget(uuid: string): Object3D | null;\n}\n\n/**\n * Manages orbit controls for a camera.\n * Supports two modes:\n * 1. **Debug mode**: orbit controls activated by the debug system, with save/restore of camera state\n * 2. **User mode**: orbit controls enabled by the user via `useOrbitalControls` camera option\n *\n * These modes are independent -- debug mode takes precedence but user mode\n * keeps orbit controls active even outside debug.\n */\nexport class CameraOrbitController {\n\tprivate camera: Camera;\n\tprivate domElement: HTMLElement;\n\tprivate cameraRig: Object3D | null = null;\n\tprivate sceneRef: Scene | null = null;\n\t\n\tprivate orbitControls: OrbitControls | null = null;\n\tprivate orbitTarget: Object3D | null = null;\n\tprivate orbitTargetWorldPos: Vector3 = new Vector3();\n\n\tprivate debugDelegate: CameraDebugDelegate | null = null;\n\tprivate debugUnsubscribe: (() => void) | null = null;\n\tprivate debugStateSnapshot: CameraDebugState = { enabled: false, selected: [] };\n\n\t// Saved camera state for restoration when exiting debug mode\n\tprivate savedCameraPosition: Vector3 | null = null;\n\tprivate savedCameraQuaternion: Quaternion | null = null;\n\tprivate savedCameraZoom: number | null = null;\n\tprivate savedCameraLocalPosition: Vector3 | null = null;\n\n\t// Saved debug camera state for restoration when re-entering debug mode\n\tprivate savedDebugCameraPosition: Vector3 | null = null;\n\tprivate savedDebugCameraQuaternion: Quaternion | null = null;\n\tprivate savedDebugCameraZoom: number | null = null;\n\tprivate savedDebugOrbitTarget: Vector3 | null = null;\n\n\t/** Whether user-configured orbital controls are enabled (independent of debug) */\n\tprivate _userOrbitEnabled = false;\n\n\tconstructor(camera: Camera, domElement: HTMLElement, cameraRig?: Object3D | null) {\n\t\tthis.camera = camera;\n\t\tthis.domElement = domElement;\n\t\tthis.cameraRig = cameraRig ?? null;\n\t}\n\n\t/**\n\t * Set the scene reference for adding/removing camera when detaching from rig.\n\t */\n\tsetScene(scene: Scene | null): void {\n\t\tthis.sceneRef = scene;\n\t}\n\n\t/**\n\t * Check if debug mode is currently active (orbit controls enabled via debug system).\n\t */\n\tget isActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled;\n\t}\n\n\t/**\n\t * Check if any orbit controls are currently active (debug or user).\n\t */\n\tget isOrbitActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled || this._userOrbitEnabled;\n\t}\n\n\t/**\n\t * Update orbit controls each frame.\n\t * Should be called from the camera's update loop.\n\t */\n\tupdate() {\n\t\tif (this.orbitControls && this.orbitTarget) {\n\t\t\tthis.orbitTarget.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t}\n\t\tthis.orbitControls?.update();\n\t}\n\n\t/**\n\t * Enable user-configured orbital controls (not debug mode).\n\t * These orbit controls persist until explicitly disabled.\n\t */\n\tenableUserOrbitControls(): void {\n\t\tthis._userOrbitEnabled = true;\n\t\tif (!this.orbitControls) {\n\t\t\tthis.enableOrbitControls();\n\t\t}\n\t}\n\n\t/**\n\t * Disable user-configured orbital controls.\n\t * Will not disable orbit controls if debug mode is active.\n\t */\n\tdisableUserOrbitControls(): void {\n\t\tthis._userOrbitEnabled = false;\n\t\t// Only disable orbit controls if debug mode isn't also using them\n\t\tif (!this.debugStateSnapshot.enabled) {\n\t\t\tthis.disableOrbitControls();\n\t\t}\n\t}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null) {\n\t\tif (this.debugDelegate === delegate) {\n\t\t\treturn;\n\t\t}\n\t\tthis.detachDebugDelegate();\n\t\tthis.debugDelegate = delegate;\n\t\tif (!delegate) {\n\t\t\tthis.applyDebugState({ enabled: false, selected: [] });\n\t\t\treturn;\n\t\t}\n\t\tconst unsubscribe = delegate.subscribe((state) => {\n\t\t\tthis.applyDebugState(state);\n\t\t});\n\t\tthis.debugUnsubscribe = () => {\n\t\t\tunsubscribe?.();\n\t\t};\n\t}\n\n\t/**\n\t * Clean up resources.\n\t */\n\tdispose() {\n\t\tthis.disableOrbitControls();\n\t\tthis.detachDebugDelegate();\n\t}\n\n\t/**\n\t * Get the current debug state snapshot.\n\t */\n\tget debugState(): CameraDebugState {\n\t\treturn this.debugStateSnapshot;\n\t}\n\n\tprivate applyDebugState(state: CameraDebugState) {\n\t\tconst wasEnabled = this.debugStateSnapshot.enabled;\n\t\tthis.debugStateSnapshot = {\n\t\t\tenabled: state.enabled,\n\t\t\tselected: [...state.selected],\n\t\t};\n\t\tif (state.enabled && !wasEnabled) {\n\t\t\t// Entering debug mode: save game camera state, detach from rig, restore debug camera state if available\n\t\t\tthis.saveCameraState();\n\t\t\tthis.detachCameraFromRig();\n\t\t\tthis.enableOrbitControls();\n\t\t\tthis.restoreDebugCameraState();\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t} else if (!state.enabled && wasEnabled) {\n\t\t\t// Exiting debug mode: save debug camera state, then restore game camera state\n\t\t\tthis.saveDebugCameraState();\n\t\t\tthis.orbitTarget = null;\n\t\t\t// Only disable orbit controls if user mode isn't keeping them on\n\t\t\tif (!this._userOrbitEnabled) {\n\t\t\t\tthis.disableOrbitControls();\n\t\t\t}\n\t\t\tthis.reattachCameraToRig();\n\t\t\tthis.restoreCameraState();\n\t\t} else if (state.enabled) {\n\t\t\t// Still in debug mode, just update target\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t}\n\t}\n\n\tprivate enableOrbitControls() {\n\t\tif (this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls = new OrbitControls(this.camera, this.domElement);\n\t\tthis.orbitControls.enableDamping = true;\n\t\tthis.orbitControls.dampingFactor = 0.05;\n\t\tthis.orbitControls.screenSpacePanning = false;\n\t\tthis.orbitControls.minDistance = 1;\n\t\tthis.orbitControls.maxDistance = 500;\n\t\tthis.orbitControls.maxPolarAngle = Math.PI / 2;\n\t\t// Default target to origin\n\t\tthis.orbitControls.target.set(0, 0, 0);\n\t}\n\n\tprivate disableOrbitControls() {\n\t\tif (!this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls.dispose();\n\t\tthis.orbitControls = null;\n\t}\n\n\tprivate updateOrbitTargetFromSelection(selected: string[]) {\n\t\t// Default to origin when no entity is selected\n\t\tif (!this.debugDelegate || selected.length === 0) {\n\t\t\tthis.orbitTarget = null;\n\t\t\tif (this.orbitControls) {\n\t\t\t\tthis.orbitControls.target.set(0, 0, 0);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tfor (let i = selected.length - 1; i >= 0; i -= 1) {\n\t\t\tconst uuid = selected[i];\n\t\t\tconst targetObject = this.debugDelegate.resolveTarget(uuid);\n\t\t\tif (targetObject) {\n\t\t\t\tthis.orbitTarget = targetObject;\n\t\t\t\tif (this.orbitControls) {\n\t\t\t\t\ttargetObject.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.orbitTarget = null;\n\t}\n\n\tprivate detachDebugDelegate() {\n\t\tif (this.debugUnsubscribe) {\n\t\t\ttry {\n\t\t\t\tthis.debugUnsubscribe();\n\t\t\t} catch { /* noop */ }\n\t\t}\n\t\tthis.debugUnsubscribe = null;\n\t\tthis.debugDelegate = null;\n\t}\n\n\t/**\n\t * Save camera position, rotation, and zoom before entering debug mode.\n\t */\n\tprivate saveCameraState() {\n\t\tthis.savedCameraPosition = this.camera.position.clone();\n\t\tthis.savedCameraQuaternion = this.camera.quaternion.clone();\n\t\t// Save zoom for orthographic/perspective cameras\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t}\n\n\t/**\n\t * Restore camera position, rotation, and zoom when exiting debug mode.\n\t */\n\tprivate restoreCameraState() {\n\t\tif (this.savedCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraPosition);\n\t\t\tthis.savedCameraPosition = null;\n\t\t}\n\t\tif (this.savedCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedCameraQuaternion);\n\t\t\tthis.savedCameraQuaternion = null;\n\t\t}\n\t\tif (this.savedCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t\tthis.savedCameraZoom = null;\n\t\t}\n\t}\n\n\t/**\n\t * Save debug camera state when exiting debug mode.\n\t */\n\tprivate saveDebugCameraState() {\n\t\tthis.savedDebugCameraPosition = this.camera.position.clone();\n\t\tthis.savedDebugCameraQuaternion = this.camera.quaternion.clone();\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedDebugCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t\tif (this.orbitControls) {\n\t\t\tthis.savedDebugOrbitTarget = this.orbitControls.target.clone();\n\t\t}\n\t}\n\n\t/**\n\t * Restore debug camera state when re-entering debug mode.\n\t */\n\tprivate restoreDebugCameraState() {\n\t\tif (this.savedDebugCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedDebugCameraPosition);\n\t\t}\n\t\tif (this.savedDebugCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedDebugCameraQuaternion);\n\t\t}\n\t\tif (this.savedDebugCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedDebugCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t}\n\t\tif (this.savedDebugOrbitTarget && this.orbitControls) {\n\t\t\tthis.orbitControls.target.copy(this.savedDebugOrbitTarget);\n\t\t}\n\t}\n\n\t/**\n\t * Detach camera from its rig to allow free orbit movement in debug mode.\n\t * Preserves the camera's world position.\n\t */\n\tprivate detachCameraFromRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent !== this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Save the camera's local position for later restoration\n\t\tthis.savedCameraLocalPosition = this.camera.position.clone();\n\n\t\t// Get camera's world position before detaching\n\t\tconst worldPos = new Vector3();\n\t\tthis.camera.getWorldPosition(worldPos);\n\n\t\t// Remove camera from rig\n\t\tthis.cameraRig.remove(this.camera);\n\n\t\t// Add camera directly to scene if scene ref is available\n\t\tif (this.sceneRef) {\n\t\t\tthis.sceneRef.add(this.camera);\n\t\t}\n\n\t\t// Set camera's position to its previous world position\n\t\tthis.camera.position.copy(worldPos);\n\t}\n\n\t/**\n\t * Reattach camera to its rig when exiting debug mode.\n\t * Restores the camera's local position relative to the rig.\n\t */\n\tprivate reattachCameraToRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent === this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove camera from scene if it's there\n\t\tif (this.sceneRef && this.camera.parent === this.sceneRef) {\n\t\t\tthis.sceneRef.remove(this.camera);\n\t\t}\n\n\t\t// Add camera back to rig\n\t\tthis.cameraRig.add(this.camera);\n\n\t\t// Restore camera's local position\n\t\tif (this.savedCameraLocalPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraLocalPosition);\n\t\t\tthis.savedCameraLocalPosition = null;\n\t\t}\n\t}\n}\n","import { Vector2, WebGLRenderer, Scene, Camera, PerspectiveCamera } from 'three';\nimport { WebGPURenderer } from 'three/webgpu';\nimport { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';\nimport RenderPass from '../graphics/render-pass';\nimport type { ZylemCamera } from './zylem-camera';\n\n/**\n * Renderer type option for choosing rendering backend\n * - 'auto': Try WebGPU first, fall back to WebGL\n * - 'webgpu': Force WebGPU (error if not supported)\n * - 'webgl': Force WebGL\n */\nexport type RendererType = 'auto' | 'webgpu' | 'webgl';\n\n/**\n * Union type for renderer instances\n */\nexport type ZylemRenderer = WebGLRenderer | WebGPURenderer;\n\n/**\n * Viewport definition in normalized coordinates (0-1).\n * Represents a rectangular region of the canvas for camera rendering.\n */\nexport interface Viewport {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\n/** Default fullscreen viewport */\nexport const DEFAULT_VIEWPORT: Viewport = { x: 0, y: 0, width: 1, height: 1 };\n\n/**\n * Check if WebGPU is supported in the current browser\n */\nexport async function isWebGPUSupported(): Promise<boolean> {\n\tif (!('gpu' in navigator)) return false;\n\ttry {\n\t\tconst adapter = await (navigator as any).gpu.requestAdapter();\n\t\treturn adapter !== null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * RendererManager owns the shared WebGL/WebGPU renderer, canvas element,\n * effect composer, and render loop. There is one RendererManager per game.\n *\n * It iterates active cameras and renders each with its configured viewport.\n */\nexport class RendererManager {\n\trenderer!: ZylemRenderer;\n\tcomposer!: EffectComposer;\n\tscreenResolution: Vector2;\n\trendererType: RendererType;\n\tprivate _isWebGPU = false;\n\tprivate _initialized = false;\n\tprivate _sceneRef: Scene | null = null;\n\n\tconstructor(screenResolution?: Vector2, rendererType: RendererType = 'webgl') {\n\t\tthis.screenResolution = screenResolution || new Vector2(window.innerWidth, window.innerHeight);\n\t\tthis.rendererType = rendererType;\n\t}\n\n\t/**\n\t * Check if the renderer has been initialized\n\t */\n\tget initialized(): boolean {\n\t\treturn this._initialized;\n\t}\n\n\t/**\n\t * Check if using WebGPU renderer\n\t */\n\tget isWebGPU(): boolean {\n\t\treturn this._isWebGPU;\n\t}\n\n\t/**\n\t * Initialize the renderer (must be called before rendering).\n\t * Async because WebGPU requires async initialization.\n\t */\n\tasync initRenderer(): Promise<void> {\n\t\tif (this._initialized) return;\n\n\t\tlet useWebGPU = false;\n\n\t\tif (this.rendererType === 'webgpu') {\n\t\t\tuseWebGPU = true;\n\t\t} else if (this.rendererType === 'auto') {\n\t\t\tuseWebGPU = await isWebGPUSupported();\n\t\t}\n\n\t\tif (useWebGPU) {\n\t\t\ttry {\n\t\t\t\tthis.renderer = new WebGPURenderer({ antialias: true });\n\t\t\t\tawait this.renderer.init();\n\t\t\t\tthis._isWebGPU = true;\n\t\t\t\tconsole.log('RendererManager: Using WebGPU renderer');\n\t\t\t} catch (e) {\n\t\t\t\tconsole.warn('RendererManager: WebGPU init failed, falling back to WebGL', e);\n\t\t\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\t\t\tthis._isWebGPU = false;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\t\tthis._isWebGPU = false;\n\t\t\tconsole.log('RendererManager: Using WebGL renderer');\n\t\t}\n\n\t\tthis.renderer.setSize(this.screenResolution.x, this.screenResolution.y);\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.shadowMap.enabled = true;\n\t\t}\n\n\t\t// Initialize composer (WebGPU uses different post-processing)\n\t\tif (!this._isWebGPU) {\n\t\t\tthis.composer = new EffectComposer(this.renderer as WebGLRenderer);\n\t\t}\n\n\t\tthis._initialized = true;\n\t}\n\n\t/**\n\t * Set the current scene reference for rendering.\n\t */\n\tsetScene(scene: Scene): void {\n\t\tthis._sceneRef = scene;\n\t}\n\n\t/**\n\t * Setup post-processing render pass for a camera (WebGL only).\n\t */\n\tsetupRenderPass(scene: Scene, camera: Camera): void {\n\t\tif (this._isWebGPU || !this.composer) return;\n\n\t\t// Dispose old passes before adding new ones (prevents GPU leak on stage transitions)\n\t\tif (this.composer.passes.length > 0) {\n\t\t\tthis.composer.passes.forEach((p: any) => { try { p.dispose?.(); } catch { /* noop */ } });\n\t\t\tthis.composer.passes.length = 0;\n\t\t}\n\n\t\tconst renderResolution = this.screenResolution.clone().divideScalar(2);\n\t\trenderResolution.x |= 0;\n\t\trenderResolution.y |= 0;\n\t\tconst pass = new RenderPass(renderResolution, scene, camera);\n\t\tthis.composer.addPass(pass);\n\t}\n\n\t/**\n\t * Start the render loop. Calls the provided callback each frame.\n\t */\n\tstartRenderLoop(onFrame: (delta: number) => void): void {\n\t\tthis.renderer.setAnimationLoop((delta: number) => {\n\t\t\tonFrame(delta || 0);\n\t\t});\n\t}\n\n\t/**\n\t * Stop the render loop.\n\t */\n\tstopRenderLoop(): void {\n\t\ttry {\n\t\t\tthis.renderer.setAnimationLoop(null as any);\n\t\t} catch { /* noop */ }\n\t}\n\n\t/**\n\t * Render a scene from a single camera's perspective.\n\t * Sets the viewport based on the camera's viewport config.\n\t */\n\trenderCamera(scene: Scene, camera: ZylemCamera): void {\n\t\tconst vp = camera.viewport;\n\t\tconst w = this.screenResolution.x;\n\t\tconst h = this.screenResolution.y;\n\n\t\t// Set scissor and viewport for this camera\n\t\tconst pixelX = Math.floor(vp.x * w);\n\t\tconst pixelY = Math.floor(vp.y * h);\n\t\tconst pixelW = Math.floor(vp.width * w);\n\t\tconst pixelH = Math.floor(vp.height * h);\n\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setViewport(pixelX, pixelY, pixelW, pixelH);\n\t\t\tthis.renderer.setScissor(pixelX, pixelY, pixelW, pixelH);\n\t\t\tthis.renderer.setScissorTest(true);\n\t\t}\n\n\t\tif (this._isWebGPU) {\n\t\t\tthis.renderer.render(scene, camera.camera);\n\t\t} else if (this.composer) {\n\t\t\tthis.composer.render(0);\n\t\t}\n\t}\n\n\t/**\n\t * Render a scene from multiple cameras, each with their own viewport.\n\t * Cameras are rendered in order (first = bottom layer, last = top layer).\n\t */\n\trenderCameras(scene: Scene, cameras: ZylemCamera[]): void {\n\t\tif (!scene || cameras.length === 0) return;\n\n\t\t// Clear the full canvas first\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setScissorTest(false);\n\t\t\tthis.renderer.clear();\n\t\t}\n\n\t\tfor (const cam of cameras) {\n\t\t\tthis.renderCamera(scene, cam);\n\t\t}\n\n\t\t// Restore scissor test state\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setScissorTest(false);\n\t\t}\n\t}\n\n\t/**\n\t * Simple single-camera render (backwards compatible).\n\t * Uses the full viewport for a single camera.\n\t */\n\trender(scene: Scene, camera: Camera): void {\n\t\tif (this._isWebGPU) {\n\t\t\tthis.renderer.render(scene, camera);\n\t\t} else if (this.composer) {\n\t\t\tthis.composer.render(0);\n\t\t}\n\t}\n\n\t/**\n\t * Resize the renderer and update resolution.\n\t */\n\tresize(width: number, height: number): void {\n\t\tthis.screenResolution.set(width, height);\n\t\tthis.renderer.setSize(width, height, false);\n\t\tif (this.composer) {\n\t\t\tthis.composer.setSize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Update renderer pixel ratio (DPR).\n\t */\n\tsetPixelRatio(dpr: number): void {\n\t\tconst safe = Math.max(1, Number.isFinite(dpr) ? dpr : 1);\n\t\tthis.renderer.setPixelRatio(safe);\n\t}\n\n\t/**\n\t * Get the DOM element for the renderer.\n\t */\n\tgetDomElement(): HTMLCanvasElement {\n\t\treturn this.renderer.domElement;\n\t}\n\n\t/**\n\t * Dispose renderer, composer, and related resources.\n\t */\n\tdispose(): void {\n\t\tthis.stopRenderLoop();\n\t\ttry {\n\t\t\tthis.composer?.passes?.forEach((p: any) => p.dispose?.());\n\t\t\t(this.composer as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.renderer.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis._sceneRef = null;\n\t\tthis._initialized = false;\n\t}\n}\n","import * as THREE from 'three';\nimport { standardShader } from './shaders/standard.shader';\nimport { WebGLRenderer, WebGLRenderTarget } from 'three';\nimport { Pass, FullScreenQuad } from 'three/addons/postprocessing/Pass.js';\n\nexport default class RenderPass extends Pass {\n\tfsQuad: FullScreenQuad;\n\tresolution: THREE.Vector2;\n\tscene: THREE.Scene;\n\tcamera: THREE.Camera;\n\trgbRenderTarget: WebGLRenderTarget;\n\tnormalRenderTarget: WebGLRenderTarget;\n\tnormalMaterial: THREE.Material;\n\n\tconstructor(resolution: THREE.Vector2, scene: THREE.Scene, camera: THREE.Camera) {\n\t\tsuper();\n\t\tthis.resolution = resolution;\n\t\tthis.fsQuad = new FullScreenQuad(this.material());\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\n\t\tthis.rgbRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\t\tthis.normalRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\n\t\tthis.normalMaterial = new THREE.MeshNormalMaterial();\n\t}\n\n\trender(\n\t\trenderer: WebGLRenderer,\n\t\twriteBuffer: WebGLRenderTarget\n\t) {\n\t\trenderer.setRenderTarget(this.rgbRenderTarget);\n\t\trenderer.render(this.scene, this.camera);\n\n\t\tconst overrideMaterial_old = this.scene.overrideMaterial;\n\t\trenderer.setRenderTarget(this.normalRenderTarget);\n\t\tthis.scene.overrideMaterial = this.normalMaterial;\n\t\trenderer.render(this.scene, this.camera);\n\t\tthis.scene.overrideMaterial = overrideMaterial_old;\n\n\t\t// @ts-ignore\n\t\tconst uniforms = this.fsQuad.material.uniforms;\n\t\tuniforms.tDiffuse.value = this.rgbRenderTarget.texture;\n\t\tuniforms.tDepth.value = this.rgbRenderTarget.depthTexture;\n\t\tuniforms.tNormal.value = this.normalRenderTarget.texture;\n\t\tuniforms.iTime.value += 0.01;\n\n\t\tif (this.renderToScreen) {\n\t\t\trenderer.setRenderTarget(null);\n\t\t} else {\n\t\t\trenderer.setRenderTarget(writeBuffer);\n\t\t}\n\t\tthis.fsQuad.render(renderer);\n\t}\n\n\tmaterial() {\n\t\treturn new THREE.ShaderMaterial({\n\t\t\tuniforms: {\n\t\t\t\tiTime: { value: 0 },\n\t\t\t\ttDiffuse: { value: null },\n\t\t\t\ttDepth: { value: null },\n\t\t\t\ttNormal: { value: null },\n\t\t\t\tresolution: {\n\t\t\t\t\tvalue: new THREE.Vector4(\n\t\t\t\t\t\tthis.resolution.x,\n\t\t\t\t\t\tthis.resolution.y,\n\t\t\t\t\t\t1 / this.resolution.x,\n\t\t\t\t\t\t1 / this.resolution.y,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t},\n\t\t\tvertexShader: standardShader.vertex,\n\t\t\tfragmentShader: standardShader.fragment\n\t\t});\n\t}\n\n\tdispose() {\n\t\ttry {\n\t\t\tthis.fsQuad?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.rgbRenderTarget as any)?.dispose?.();\n\t\t\t(this.normalRenderTarget as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.normalMaterial as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t}\n}\n","export const objectVertexShader = `\nuniform vec2 uvScale;\nvarying vec2 vUv;\n\nvoid main() {\n\tvUv = uv;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n}\n`;\n","import { objectVertexShader } from './vertex/object.shader';\n\nconst fragment = `\nuniform sampler2D tDiffuse;\nvarying vec2 vUv;\n\nvoid main() {\n\tvec4 texel = texture2D( tDiffuse, vUv );\n\n\tgl_FragColor = texel;\n}\n`;\n\nexport const standardShader = {\n vertex: objectVertexShader,\n fragment\n};\n","import { Vector2, Scene } from 'three';\nimport { ZylemCamera } from './zylem-camera';\nimport { RendererManager } from './renderer-manager';\nimport { Perspectives } from './perspective';\nimport { nanoid } from 'nanoid';\n\n/**\n * CameraManager orchestrates multiple cameras per stage.\n *\n * Responsibilities:\n * - Named camera registry (add/remove/get by name or reference)\n * - Active camera list management (determines which cameras render)\n * - Always-available debug camera with orbit controls\n * - Per-frame update of all active cameras' perspective controllers\n * - Coordinating rendering via RendererManager for all active viewports\n */\nexport class CameraManager {\n\t/** Named camera registry */\n\tprivate cameras: Map<string, ZylemCamera> = new Map();\n\n\t/** Currently active cameras, ordered by render layer (first = bottom) */\n\tprivate _activeCameras: ZylemCamera[] = [];\n\n\t/** Auto-created debug camera with orbit controls */\n\tprivate _debugCamera: ZylemCamera | null = null;\n\n\t/** Reference to the shared renderer manager */\n\tprivate _rendererManager: RendererManager | null = null;\n\n\t/** Scene reference */\n\tprivate _sceneRef: Scene | null = null;\n\n\t/** Counter for auto-generated camera names */\n\tprivate _autoNameCounter = 0;\n\n\tconstructor() {\n\t\t// Debug camera is created lazily during setup when we have screen resolution\n\t}\n\n\t/**\n\t * Get the list of currently active cameras.\n\t */\n\tget activeCameras(): ReadonlyArray<ZylemCamera> {\n\t\treturn this._activeCameras;\n\t}\n\n\t/**\n\t * Get the primary active camera (first in the active list).\n\t */\n\tget primaryCamera(): ZylemCamera | null {\n\t\treturn this._activeCameras.length > 0 ? this._activeCameras[0] : null;\n\t}\n\n\t/**\n\t * Get the debug camera.\n\t */\n\tget debugCamera(): ZylemCamera | null {\n\t\treturn this._debugCamera;\n\t}\n\n\t/**\n\t * Get all registered cameras.\n\t */\n\tget allCameras(): ReadonlyArray<ZylemCamera> {\n\t\treturn Array.from(this.cameras.values());\n\t}\n\n\t/**\n\t * Add a camera to the manager.\n\t * If no name is provided, one is auto-generated.\n\t * The first camera added becomes the active camera.\n\t *\n\t * @param camera The ZylemCamera instance to add\n\t * @param name Optional name for lookup\n\t * @returns The assigned name\n\t */\n\taddCamera(camera: ZylemCamera, name?: string): string {\n\t\tconst resolvedName = name || camera.name || `camera_${this._autoNameCounter++}`;\n\t\tcamera.name = resolvedName;\n\t\tthis.cameras.set(resolvedName, camera);\n\n\t\t// First camera added automatically becomes active\n\t\tif (this._activeCameras.length === 0) {\n\t\t\tthis._activeCameras.push(camera);\n\t\t}\n\n\t\treturn resolvedName;\n\t}\n\n\t/**\n\t * Remove a camera by name or reference.\n\t * Cannot remove the debug camera via this method.\n\t */\n\tremoveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tlet name: string | undefined;\n\n\t\tif (typeof nameOrRef === 'string') {\n\t\t\tname = nameOrRef;\n\t\t} else {\n\t\t\t// Find by reference\n\t\t\tfor (const [key, cam] of this.cameras.entries()) {\n\t\t\t\tif (cam === nameOrRef) {\n\t\t\t\t\tname = key;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!name) return false;\n\n\t\tconst camera = this.cameras.get(name);\n\t\tif (!camera) return false;\n\n\t\t// Prevent removing the debug camera\n\t\tif (camera === this._debugCamera) {\n\t\t\tconsole.warn('CameraManager: Cannot remove the debug camera');\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.cameras.delete(name);\n\n\t\t// Remove from active cameras\n\t\tconst activeIndex = this._activeCameras.indexOf(camera);\n\t\tif (activeIndex !== -1) {\n\t\t\tthis._activeCameras.splice(activeIndex, 1);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Set a camera as the primary active camera (replaces all active cameras\n\t * except additional viewport cameras).\n\t *\n\t * @param nameOrRef Camera name or reference to activate\n\t */\n\tsetActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) {\n\t\t\tconsole.warn(`CameraManager: Camera not found: ${nameOrRef}`);\n\t\t\treturn false;\n\t\t}\n\n\t\t// Set as the sole active camera (keeping PiP cameras if any)\n\t\tconst pipCameras = this._activeCameras.filter(c => {\n\t\t\treturn c !== this._activeCameras[0] && c.viewport.width < 1;\n\t\t});\n\n\t\tthis._activeCameras = [camera, ...pipCameras];\n\t\treturn true;\n\t}\n\n\t/**\n\t * Add a camera as an additional active camera (for split-screen or PiP).\n\t */\n\taddActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) return false;\n\n\t\tif (!this._activeCameras.includes(camera)) {\n\t\t\tthis._activeCameras.push(camera);\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Remove a camera from the active render list (does not remove from registry).\n\t */\n\tdeactivateCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) return false;\n\n\t\tconst index = this._activeCameras.indexOf(camera);\n\t\tif (index !== -1) {\n\t\t\tthis._activeCameras.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get a camera by name.\n\t */\n\tgetCamera(name: string): ZylemCamera | null {\n\t\treturn this.cameras.get(name) ?? null;\n\t}\n\n\t/**\n\t * Setup all cameras with the given scene and renderer manager.\n\t * Also creates the debug camera.\n\t */\n\tasync setup(scene: Scene, rendererManager: RendererManager): Promise<void> {\n\t\tthis._sceneRef = scene;\n\t\tthis._rendererManager = rendererManager;\n\n\t\t// Create the debug camera\n\t\tthis.createDebugCamera(rendererManager.screenResolution);\n\n\t\t// Setup all registered cameras\n\t\tfor (const camera of this.cameras.values()) {\n\t\t\tcamera.setRendererManager(rendererManager);\n\t\t\tawait camera.setup(scene, rendererManager);\n\t\t}\n\n\t\t// Setup the debug camera\n\t\tif (this._debugCamera) {\n\t\t\tthis._debugCamera.setRendererManager(rendererManager);\n\t\t\tawait this._debugCamera.setup(scene, rendererManager);\n\t\t}\n\t}\n\n\t/**\n\t * Update all active cameras' controllers.\n\t */\n\tupdate(delta: number): void {\n\t\tfor (const camera of this._activeCameras) {\n\t\t\tcamera.update(delta);\n\t\t}\n\t}\n\n\t/**\n\t * Render all active cameras through the renderer manager.\n\t */\n\trender(scene: Scene): void {\n\t\tif (!this._rendererManager || this._activeCameras.length === 0) return;\n\t\tthis._rendererManager.renderCameras(scene, this._activeCameras as ZylemCamera[]);\n\t}\n\n\t/**\n\t * Create a default third-person camera if no cameras have been added.\n\t */\n\tensureDefaultCamera(): ZylemCamera {\n\t\tif (this.cameras.size === 0 || this._activeCameras.length === 0) {\n\t\t\tconst screenRes = this._rendererManager?.screenResolution\n\t\t\t\t|| new Vector2(window.innerWidth, window.innerHeight);\n\t\t\tconst defaultCam = new ZylemCamera(Perspectives.ThirdPerson, screenRes);\n\t\t\tthis.addCamera(defaultCam, 'default');\n\t\t\treturn defaultCam;\n\t\t}\n\t\treturn this._activeCameras[0];\n\t}\n\n\t/**\n\t * Dispose all cameras and cleanup.\n\t */\n\tdispose(): void {\n\t\tfor (const camera of this.cameras.values()) {\n\t\t\tcamera.destroy();\n\t\t}\n\t\tthis._debugCamera?.destroy();\n\t\tthis.cameras.clear();\n\t\tthis._activeCameras = [];\n\t\tthis._debugCamera = null;\n\t\tthis._rendererManager = null;\n\t\tthis._sceneRef = null;\n\t}\n\n\t/**\n\t * Create the always-available debug camera with orbit controls.\n\t */\n\tprivate createDebugCamera(screenResolution: Vector2): void {\n\t\tthis._debugCamera = new ZylemCamera(Perspectives.ThirdPerson, screenResolution);\n\t\tthis._debugCamera.name = '__debug__';\n\t\tthis._debugCamera.enableOrbitalControls();\n\t\t// Debug camera is NOT added to the active cameras by default;\n\t\t// it's activated via the debug system\n\t}\n\n\t/**\n\t * Resolve a camera from a name or reference.\n\t */\n\tprivate resolveCamera(nameOrRef: string | ZylemCamera): ZylemCamera | null {\n\t\tif (typeof nameOrRef === 'string') {\n\t\t\treturn this.cameras.get(nameOrRef) ?? null;\n\t\t}\n\t\t// Check if the reference exists in our registry\n\t\tfor (const cam of this.cameras.values()) {\n\t\t\tif (cam === nameOrRef) return cam;\n\t\t}\n\t\treturn null;\n\t}\n}\n"],"mappings":"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","names":["Vector2","Vector3","PerspectiveCamera","Vector3","Object3D","Vector3","Vector2","WebGLRenderer","Vector2","WebGLRenderer","Object3D","Vector3","PerspectiveCamera","Vector2","Vector3","Vector2","Vector2"]}
1
+ {"version":3,"sources":["../src/lib/camera/camera.ts","../src/lib/camera/zylem-camera.ts","../src/lib/camera/perspective.ts","../src/lib/camera/camera-debug-delegate.ts","../src/lib/camera/renderer-manager.ts","../src/lib/graphics/render-pass.ts","../src/lib/graphics/shaders/vertex/object.shader.ts","../src/lib/graphics/shaders/standard.shader.ts","../src/lib/camera/smoothing.ts","../src/lib/camera/camera-pipeline.ts","../src/lib/camera/perspectives/third-person-perspective.ts","../src/lib/camera/perspectives/fixed-2d-perspective.ts","../src/lib/camera/perspectives/first-person-perspective.ts","../src/lib/camera/perspectives/index.ts","../src/lib/camera/camera-manager.ts"],"sourcesContent":["import { Vector2, Vector3, Texture } from \"three\";\nimport { PerspectiveType } from \"./perspective\";\nimport { ZylemCamera } from \"./zylem-camera\";\nimport { RendererType, Viewport, DEFAULT_VIEWPORT } from \"./renderer-manager\";\nimport { StageEntity } from \"../interfaces/entity\";\nimport type { CameraBehavior, CameraAction, CameraPerspective, CameraPipelineState } from \"./types\";\nimport { createPerspective } from \"./perspectives\";\nimport type { PerspectiveOptions } from \"./perspectives\";\n\nexport interface CameraOptions {\n\tperspective?: PerspectiveType;\n\tposition?: Vector3 | { x: number; y: number; z: number };\n\ttarget?: Vector3 | { x: number; y: number; z: number } | any;\n\tzoom?: number;\n\tscreenResolution?: Vector2;\n\t/**\n\t * Renderer type: 'auto' | 'webgpu' | 'webgl'\n\t * Use 'webgpu' for TSL shaders\n\t * @default 'webgl'\n\t */\n\trendererType?: RendererType;\n\t/**\n\t * Enable orbital controls for this camera.\n\t * Can be toggled at runtime via enableOrbitalControls() / disableOrbitalControls().\n\t * @default false\n\t */\n\tuseOrbitalControls?: boolean;\n\t/**\n\t * Viewport in normalized coordinates (0-1).\n\t * Defines where this camera renders on the canvas.\n\t * @default { x: 0, y: 0, width: 1, height: 1 } (fullscreen)\n\t */\n\tviewport?: Viewport;\n\t/**\n\t * Optional name for camera manager lookup.\n\t */\n\tname?: string;\n\t/**\n\t * Initial behaviors to attach to the camera pipeline.\n\t * Keys are used for idempotent add/remove.\n\t */\n\tbehaviors?: Record<string, CameraBehavior>;\n\t/**\n\t * Pipeline smoothing factor (0-1).\n\t * 1 = instant snap, 0 = no movement.\n\t * @default 0.15\n\t */\n\tdamping?: number;\n\t/**\n\t * When set, the camera renders to an offscreen texture instead of a\n\t * screen viewport. Use with setCameraFeed() to display the feed on\n\t * an in-scene mesh (jumbotron, security monitor, portal, etc.).\n\t *\n\t * @default undefined (renders to screen)\n\t */\n\trenderToTexture?: {\n\t\t/** Texture width in pixels. @default 512 */\n\t\twidth?: number;\n\t\t/** Texture height in pixels. @default 512 */\n\t\theight?: number;\n\t};\n\t/**\n\t * When true, this camera will not activate orbital controls in debug mode.\n\t * The pipeline (and its behaviors) will always run for this camera.\n\t * Use for cameras with custom behaviors (e.g. FPS mouse-look) that must\n\t * control the camera through the pipeline rather than debug orbit controls.\n\t * @default false\n\t */\n\tskipDebugOrbit?: boolean;\n}\n\n/**\n * CameraWrapper is the user-facing camera handle returned by createCamera().\n * It provides convenience methods for target management, orbital controls,\n * viewport configuration, and the camera pose pipeline.\n */\nexport class CameraWrapper {\n\tcameraRef: ZylemCamera;\n\n\tconstructor(camera: ZylemCamera) {\n\t\tthis.cameraRef = camera;\n\t}\n\n\t// ─── Target management ──────────────────────────────────────────────────\n\n\t/**\n\t * Add a target entity for the camera to follow/frame.\n\t * With multiple targets, the camera auto-frames to include all of them.\n\t */\n\taddTarget(entity: StageEntity): void {\n\t\tthis.cameraRef.addTarget(entity);\n\t}\n\n\t/**\n\t * Remove a target entity from the camera.\n\t */\n\tremoveTarget(entity: StageEntity): void {\n\t\tthis.cameraRef.removeTarget(entity);\n\t}\n\n\t/**\n\t * Clear all targets. Camera will look at world origin.\n\t */\n\tclearTargets(): void {\n\t\tthis.cameraRef.clearTargets();\n\t}\n\n\t// ─── Orbital controls ───────────────────────────────────────────────────\n\n\t/**\n\t * Enable orbital controls for this camera.\n\t * Allows the user to orbit, pan, and zoom the camera.\n\t */\n\tenableOrbitalControls(): void {\n\t\tthis.cameraRef.enableOrbitalControls();\n\t}\n\n\t/**\n\t * Disable orbital controls for this camera.\n\t */\n\tdisableOrbitalControls(): void {\n\t\tthis.cameraRef.disableOrbitalControls();\n\t}\n\n\t// ─── Viewport ───────────────────────────────────────────────────────────\n\n\t/**\n\t * Set the viewport for this camera (normalized 0-1 coordinates).\n\t * @param x Left edge (0 = left of canvas)\n\t * @param y Bottom edge (0 = bottom of canvas)\n\t * @param width Width as fraction of canvas\n\t * @param height Height as fraction of canvas\n\t */\n\tsetViewport(x: number, y: number, width: number, height: number): void {\n\t\tthis.cameraRef.setViewport(x, y, width, height);\n\t}\n\n\t// ─── Pipeline: Behaviors ────────────────────────────────────────────────\n\n\t/**\n\t * Add or replace a behavior by key (idempotent).\n\t * Behaviors modify the desired camera pose each frame.\n\t *\n\t * @param key Unique key for this behavior (used for replacement/removal).\n\t * @param behavior The CameraBehavior implementation.\n\t */\n\taddBehavior(key: string, behavior: CameraBehavior): void {\n\t\tthis.cameraRef.pipeline.addBehavior(key, behavior);\n\t}\n\n\t/**\n\t * Remove a behavior by key.\n\t */\n\tremoveBehavior(key: string): boolean {\n\t\treturn this.cameraRef.pipeline.removeBehavior(key);\n\t}\n\n\t// ─── Pipeline: Actions ──────────────────────────────────────────────────\n\n\t/**\n\t * Add a transient action (screenshake, recoil, etc.).\n\t * Actions apply additive deltas and self-expire when isDone() returns true.\n\t */\n\taddAction(action: CameraAction): void {\n\t\tthis.cameraRef.pipeline.addAction(action);\n\t}\n\n\t// ─── Pipeline: Perspective ──────────────────────────────────────────────\n\n\t/**\n\t * Switch the camera's active perspective at runtime.\n\t * The first frame after switching snaps to the new pose (no lerp).\n\t *\n\t * @param type Perspective type string (e.g. Perspectives.ThirdPerson).\n\t * @param options Perspective-specific options (distance, height, zoom, etc.).\n\t */\n\tsetPerspective(type: PerspectiveType, options?: PerspectiveOptions): void {\n\t\tthis.cameraRef.pipeline.setPerspective(createPerspective(type, options));\n\t}\n\n\t/**\n\t * Retrieve the active perspective instance, cast to the desired type.\n\t * Useful for calling perspective-specific methods (e.g. FirstPersonPerspective.look()).\n\t *\n\t * @example\n\t * const fps = camera.getPerspective<FirstPersonPerspective>();\n\t * fps.look(dx, dy);\n\t */\n\tgetPerspective<T extends CameraPerspective = CameraPerspective>(): T {\n\t\treturn this.cameraRef.pipeline.perspective as T;\n\t}\n\n\t// ─── Pipeline: Debug state ──────────────────────────────────────────────\n\n\t/**\n\t * Return a debug snapshot of the camera pipeline state.\n\t * Includes: active perspective, desired/final pose, behavior keys, action count.\n\t */\n\tgetState(): CameraPipelineState {\n\t\treturn this.cameraRef.pipeline.getState();\n\t}\n\n\t// ─── Render-to-texture ─────────────────────────────────────────────────\n\n\t/**\n\t * Get the offscreen render texture for this camera.\n\t * Returns null if the camera was not created with renderToTexture.\n\t * Use with setCameraFeed() or apply directly to a mesh material.\n\t */\n\tgetRenderTexture(): Texture | null {\n\t\treturn this.cameraRef.getRenderTexture();\n\t}\n}\n\n/**\n * Create a camera with the given options.\n * Returns a CameraWrapper for convenient access to camera features.\n */\nexport function createCamera(options: CameraOptions): CameraWrapper {\n\tconst screenResolution = options.screenResolution || new Vector2(window.innerWidth, window.innerHeight);\n\tlet frustumSize = 10;\n\tif (options.perspective === 'fixed-2d') {\n\t\tfrustumSize = options.zoom || 10;\n\t}\n\tconst zylemCamera = new ZylemCamera(\n\t\toptions.perspective || 'third-person',\n\t\tscreenResolution,\n\t\tfrustumSize,\n\t\toptions.rendererType || 'webgl'\n\t);\n\n\t// Set camera name if provided\n\tif (options.name) {\n\t\tzylemCamera.name = options.name;\n\t}\n\n\t// Set initial position and target\n\tconst position = options.position \n\t\t? (options.position instanceof Vector3 ? options.position : new Vector3(options.position.x, options.position.y, options.position.z))\n\t\t: new Vector3(0, 0, 0);\n\t\n\tconst target = options.target\n\t\t? (options.target instanceof Vector3 ? options.target : new Vector3(options.target.x, options.target.y, options.target.z))\n\t\t: new Vector3(0, 0, 0);\n\t\n\tzylemCamera.move(position);\n\tzylemCamera.camera.lookAt(target);\n\n\t// Reconfigure the perspective with user-specified options (position, zoom, etc.)\n\t// so the pipeline produces the correct base pose from the first frame.\n\tconst perspType = options.perspective || 'third-person';\n\tif (perspType === 'fixed-2d' || perspType === 'flat-2d') {\n\t\tzylemCamera.pipeline.setPerspective(\n\t\t\tcreatePerspective(perspType, { zoom: frustumSize })\n\t\t);\n\t} else {\n\t\tzylemCamera.pipeline.setPerspective(\n\t\t\tcreatePerspective(perspType, {\n\t\t\t\tinitialPosition: position.clone(),\n\t\t\t\tinitialLookAt: target.clone(),\n\t\t\t})\n\t\t);\n\t}\n\n\t// Set viewport if provided\n\tif (options.viewport) {\n\t\tzylemCamera.viewport = { ...options.viewport };\n\t}\n\n\t// Configure orbital controls\n\tif (options.useOrbitalControls) {\n\t\t(zylemCamera as any)._useOrbitalControls = true;\n\t}\n\n\t// Opt out of debug-mode orbital controls\n\tif (options.skipDebugOrbit) {\n\t\tzylemCamera._skipDebugOrbit = true;\n\t}\n\n\t// Configure pipeline damping\n\tif (options.damping != null) {\n\t\tzylemCamera.pipeline.damping = options.damping;\n\t}\n\n\t// Attach initial behaviors\n\tif (options.behaviors) {\n\t\tfor (const [key, behavior] of Object.entries(options.behaviors)) {\n\t\t\tzylemCamera.pipeline.addBehavior(key, behavior);\n\t\t}\n\t}\n\n\t// Create render target for RTT cameras\n\tif (options.renderToTexture) {\n\t\tconst { width = 512, height = 512 } = options.renderToTexture;\n\t\tzylemCamera.createRenderTarget(width, height);\n\t}\n\n\treturn new CameraWrapper(zylemCamera);\n}\n","import { Vector2, Camera, PerspectiveCamera, Vector3, Object3D, OrthographicCamera, Scene, WebGLRenderTarget, Texture, LinearFilter } from 'three';\nimport { PerspectiveType, Perspectives } from './perspective';\nimport { StageEntity } from '../interfaces/entity';\nimport { CameraOrbitController, CameraDebugDelegate } from './camera-debug-delegate';\nimport { RendererManager, DEFAULT_VIEWPORT } from './renderer-manager';\nimport type { ZylemRenderer, RendererType, Viewport } from './renderer-manager';\nimport { CameraPipeline } from './camera-pipeline';\nimport { createPerspective } from './perspectives';\nimport type { CameraContext, TransformLike, CameraPose } from './types';\n\n// Re-export for backwards compatibility\nexport type { CameraDebugState, CameraDebugDelegate } from './camera-debug-delegate';\nexport type { RendererType, ZylemRenderer } from './renderer-manager';\nexport { isWebGPUSupported } from './renderer-manager';\n\n/**\n * ZylemCamera is a lightweight camera wrapper that manages the Three.js camera,\n * the camera pose pipeline, and viewport configuration. Rendering is handled\n * by RendererManager.\n *\n * The pipeline runs: Perspective -> Behaviors -> Actions -> Smoothing -> Commit.\n * When orbit/debug controls are active, the pipeline is bypassed.\n */\nexport class ZylemCamera {\n\t/**\n\t * @deprecated No longer used. Kept as null for backward compatibility\n\t * with code that checks `camera.cameraRig` (e.g. scene graph insertion).\n\t */\n\tcameraRig: Object3D | null = null;\n\n\tcamera: Camera;\n\tscreenResolution: Vector2;\n\t_perspective: PerspectiveType;\n\tfrustumSize = 10;\n\trendererType: RendererType;\n\tsceneRef: Scene | null = null;\n\n\t/** Name for camera manager lookup. */\n\tname: string = '';\n\n\t/**\n\t * Viewport in normalized coordinates (0-1).\n\t * Default is fullscreen: { x: 0, y: 0, width: 1, height: 1 }\n\t */\n\tviewport: Viewport = { ...DEFAULT_VIEWPORT };\n\n\t/**\n\t * Multiple targets for the camera to follow/frame.\n\t */\n\ttargets: StageEntity[] = [];\n\n\t/**\n\t * The camera pose pipeline.\n\t * Exposed so CameraWrapper can delegate addBehavior/addAction/getState.\n\t */\n\tpipeline: CameraPipeline;\n\n\t/**\n\t * Offscreen render target for render-to-texture (RTT) cameras.\n\t * When set, the camera renders to this target instead of the screen viewport.\n\t * Created via createRenderTarget() or automatically by setCameraFeed().\n\t */\n\trenderTarget: WebGLRenderTarget | null = null;\n\n\t/**\n\t * @deprecated Use `targets` array instead. Kept for backward compatibility.\n\t */\n\tget target(): StageEntity | null {\n\t\treturn this.targets.length > 0 ? this.targets[0] : null;\n\t}\n\n\tset target(entity: StageEntity | null) {\n\t\tif (entity) {\n\t\t\tif (this.targets.length === 0) {\n\t\t\t\tthis.targets.push(entity);\n\t\t\t} else {\n\t\t\t\tthis.targets[0] = entity;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.targets = [];\n\t\t}\n\t}\n\n\t// Orbit controls\n\tprivate orbitController: CameraOrbitController | null = null;\n\tprivate _useOrbitalControls = false;\n\n\t/** When true, debug-mode orbital controls are not attached to this camera. */\n\t_skipDebugOrbit = false;\n\n\t/** Reference to the shared renderer manager (set during setup). */\n\tprivate _rendererManager: RendererManager | null = null;\n\n\t/** Elapsed time tracker for CameraContext. */\n\tprivate _elapsedTime = 0;\n\n\tconstructor(perspective: PerspectiveType, screenResolution: Vector2, frustumSize: number = 10, rendererType: RendererType = 'webgl') {\n\t\tthis._perspective = perspective;\n\t\tthis.screenResolution = screenResolution;\n\t\tthis.frustumSize = frustumSize;\n\t\tthis.rendererType = rendererType;\n\n\t\t// Create Three.js camera based on perspective\n\t\tconst aspectRatio = screenResolution.x / screenResolution.y;\n\t\tthis.camera = this.createCameraForPerspective(aspectRatio);\n\n\t\t// Position camera directly (no rig)\n\t\tthis.camera.position.set(0, 0, 10);\n\t\tthis.camera.lookAt(new Vector3(0, 0, 0));\n\n\t\t// Create pipeline with the appropriate perspective implementation\n\t\tconst perspectiveImpl = createPerspective(perspective);\n\t\tthis.pipeline = new CameraPipeline(perspectiveImpl);\n\t}\n\n\t/**\n\t * Setup the camera with a scene and renderer manager.\n\t */\n\tasync setup(scene: Scene, rendererManager?: RendererManager): Promise<void> {\n\t\tthis.sceneRef = scene;\n\n\t\tif (rendererManager) {\n\t\t\tthis._rendererManager = rendererManager;\n\t\t}\n\n\t\t// Ensure renderer manager is initialized\n\t\tif (this._rendererManager && !this._rendererManager.initialized) {\n\t\t\tawait this._rendererManager.initRenderer();\n\t\t}\n\n\t\t// Initialize orbit controller if renderer is available\n\t\tif (this._rendererManager) {\n\t\t\tthis.orbitController = new CameraOrbitController(\n\t\t\t\tthis.camera,\n\t\t\t\tthis._rendererManager.renderer.domElement,\n\t\t\t\tnull // no camera rig\n\t\t\t);\n\t\t\tthis.orbitController.setScene(scene);\n\n\t\t\t// If orbital controls were requested, enable them\n\t\t\tif (this._useOrbitalControls) {\n\t\t\t\tthis.orbitController.enableUserOrbitControls();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Legacy setup method for backward compatibility.\n\t * Creates a temporary RendererManager internally.\n\t * @deprecated Use setup(scene, rendererManager) instead.\n\t */\n\tasync setupLegacy(scene: Scene): Promise<void> {\n\t\tif (!this._rendererManager) {\n\t\t\tthis._rendererManager = new RendererManager(this.screenResolution, this.rendererType);\n\t\t\tawait this._rendererManager.initRenderer();\n\n\t\t\t// Setup render pass for WebGL\n\t\t\tthis._rendererManager.setupRenderPass(scene, this.camera);\n\n\t\t\t// Start render loop\n\t\t\tthis._rendererManager.startRenderLoop((delta) => {\n\t\t\t\tthis.update(delta);\n\t\t\t\tif (this._rendererManager && this.sceneRef) {\n\t\t\t\t\tthis._rendererManager.render(this.sceneRef, this.camera);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tawait this.setup(scene, this._rendererManager);\n\t}\n\n\t/**\n\t * Update the camera each frame.\n\t *\n\t * When orbit/debug controls are active, the pipeline is skipped and\n\t * orbit controls manage the camera directly. Otherwise, the pipeline\n\t * runs: Perspective -> Behaviors -> Actions -> Smoothing -> Commit.\n\t */\n\tupdate(delta: number): void {\n\t\t// Update orbit controls (if debug mode or user orbital controls enabled)\n\t\tthis.orbitController?.update();\n\n\t\t// Skip pipeline when orbit controls are active\n\t\tif (this.isDebugModeActive() || this._useOrbitalControls) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Accumulate elapsed time\n\t\tthis._elapsedTime += delta;\n\n\t\t// Build context from current state\n\t\tconst ctx = this.buildContext(delta);\n\n\t\t// Run the pipeline\n\t\tconst finalPose = this.pipeline.run(ctx);\n\n\t\t// Commit the result to the Three.js camera\n\t\tthis.commitPose(finalPose);\n\t}\n\n\t/**\n\t * Check if debug mode is active (orbit controls taking over camera).\n\t */\n\tisDebugModeActive(): boolean {\n\t\treturn this.orbitController?.isActive ?? false;\n\t}\n\n\t/**\n\t * Enable user-configured orbital controls (not debug mode).\n\t */\n\tenableOrbitalControls(): void {\n\t\tthis._useOrbitalControls = true;\n\t\tthis.orbitController?.enableUserOrbitControls();\n\t}\n\n\t/**\n\t * Disable user-configured orbital controls.\n\t */\n\tdisableOrbitalControls(): void {\n\t\tthis._useOrbitalControls = false;\n\t\tthis.orbitController?.disableUserOrbitControls();\n\t}\n\n\t/**\n\t * Whether user orbital controls are enabled.\n\t */\n\tget useOrbitalControls(): boolean {\n\t\treturn this._useOrbitalControls;\n\t}\n\n\t// ─── Target management ──────────────────────────────────────────────────\n\n\t/**\n\t * Add a target entity for the camera to follow/frame.\n\t */\n\taddTarget(entity: StageEntity): void {\n\t\tif (!this.targets.includes(entity)) {\n\t\t\tthis.targets.push(entity);\n\t\t}\n\t}\n\n\t/**\n\t * Remove a target entity.\n\t */\n\tremoveTarget(entity: StageEntity): void {\n\t\tconst index = this.targets.indexOf(entity);\n\t\tif (index !== -1) {\n\t\t\tthis.targets.splice(index, 1);\n\t\t}\n\t}\n\n\t/**\n\t * Clear all targets.\n\t */\n\tclearTargets(): void {\n\t\tthis.targets = [];\n\t}\n\n\t// ─── Viewport & resize ──────────────────────────────────────────────────\n\n\t/**\n\t * Set the viewport for this camera (normalized 0-1 coordinates).\n\t */\n\tsetViewport(x: number, y: number, width: number, height: number): void {\n\t\tthis.viewport = { x, y, width, height };\n\t}\n\n\t/**\n\t * Resize camera projection.\n\t */\n\tresize(width: number, height: number): void {\n\t\tthis.screenResolution.set(width, height);\n\n\t\tif (this.camera instanceof PerspectiveCamera) {\n\t\t\tthis.camera.aspect = width / height;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\n\t\tif (this.camera instanceof OrthographicCamera) {\n\t\t\tconst aspect = width / height;\n\t\t\tthis.camera.left = this.frustumSize * aspect / -2;\n\t\t\tthis.camera.right = this.frustumSize * aspect / 2;\n\t\t\tthis.camera.top = this.frustumSize / 2;\n\t\t\tthis.camera.bottom = this.frustumSize / -2;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\t}\n\n\t// ─── Render-to-texture ─────────────────────────────────────────────────\n\n\t/**\n\t * Create an offscreen render target for this camera.\n\t * When a render target is present, CameraManager renders this camera\n\t * to the target instead of the screen viewport.\n\t *\n\t * @param width Texture width in pixels (default 512)\n\t * @param height Texture height in pixels (default 512)\n\t */\n\tcreateRenderTarget(width: number = 512, height: number = 512): WebGLRenderTarget {\n\t\tif (this.renderTarget) {\n\t\t\tthis.renderTarget.dispose();\n\t\t}\n\t\tthis.renderTarget = new WebGLRenderTarget(width, height, {\n\t\t\tminFilter: LinearFilter,\n\t\t\tmagFilter: LinearFilter,\n\t\t});\n\t\treturn this.renderTarget;\n\t}\n\n\t/**\n\t * Get the texture from the render target (for applying to a mesh material).\n\t * Returns null if no render target has been created.\n\t */\n\tgetRenderTexture(): Texture | null {\n\t\treturn this.renderTarget?.texture ?? null;\n\t}\n\n\t// ─── Lifecycle ──────────────────────────────────────────────────────────\n\n\t/**\n\t * Dispose camera resources.\n\t */\n\tdestroy(): void {\n\t\ttry {\n\t\t\tthis.orbitController?.dispose();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.renderTarget?.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis.renderTarget = null;\n\t\tthis.sceneRef = null;\n\t\tthis.targets = [];\n\t\tthis._rendererManager = null;\n\t}\n\n\t// ─── Debug delegate ─────────────────────────────────────────────────────\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t * Skipped when _skipDebugOrbit is true so the pipeline always runs.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null): void {\n\t\tif (this._skipDebugOrbit) return;\n\t\tthis.orbitController?.setDebugDelegate(delegate);\n\t}\n\n\t// ─── Movement helpers (backward compat) ─────────────────────────────────\n\n\t/**\n\t * Directly set the camera position.\n\t */\n\tmove(position: Vector3): void {\n\t\tif (this._perspective === Perspectives.Flat2D || this._perspective === Perspectives.Fixed2D) {\n\t\t\tthis.frustumSize = position.z;\n\t\t}\n\t\tthis.camera.position.set(position.x, position.y, position.z);\n\t}\n\n\t/**\n\t * Apply incremental rotation to the camera.\n\t */\n\trotate(pitch: number, yaw: number, roll: number): void {\n\t\t(this.camera as Object3D).rotateX(pitch);\n\t\t(this.camera as Object3D).rotateY(yaw);\n\t\t(this.camera as Object3D).rotateZ(roll);\n\t}\n\n\t// ─── Renderer manager access ────────────────────────────────────────────\n\n\t/**\n\t * Get the DOM element for the renderer.\n\t * @deprecated Access via RendererManager instead.\n\t */\n\tgetDomElement(): HTMLCanvasElement {\n\t\tif (this._rendererManager) {\n\t\t\treturn this._rendererManager.getDomElement();\n\t\t}\n\t\tthrow new Error('ZylemCamera: No renderer manager available. Call setup() first.');\n\t}\n\n\t/**\n\t * Get the renderer manager reference.\n\t */\n\tgetRendererManager(): RendererManager | null {\n\t\treturn this._rendererManager;\n\t}\n\n\t/**\n\t * Set the renderer manager reference (used by CameraManager during setup).\n\t */\n\tsetRendererManager(manager: RendererManager): void {\n\t\tthis._rendererManager = manager;\n\t}\n\n\t// ─── Legacy compatibility methods ────────────────────────────────────────\n\n\t/** @deprecated Renderer is now owned by RendererManager */\n\tget renderer(): any {\n\t\treturn this._rendererManager?.renderer;\n\t}\n\n\t/** @deprecated Composer is now owned by RendererManager */\n\tget composer(): any {\n\t\treturn this._rendererManager?.composer;\n\t}\n\n\t/** @deprecated Use RendererManager.setPixelRatio() instead */\n\tsetPixelRatio(dpr: number): void {\n\t\tthis._rendererManager?.setPixelRatio(dpr);\n\t}\n\n\t// ─── Private helpers ────────────────────────────────────────────────────\n\n\t/**\n\t * Build a CameraContext from current ZylemCamera state.\n\t * Converts StageEntity[] targets into Record<string, TransformLike>.\n\t */\n\tprivate buildContext(delta: number): CameraContext {\n\t\tconst targets: Record<string, TransformLike> = {};\n\n\t\tfor (let i = 0; i < this.targets.length; i++) {\n\t\t\tconst entity = this.targets[i];\n\t\t\tconst key = i === 0 ? 'primary' : `target_${i}`;\n\t\t\tif (entity.group) {\n\t\t\t\ttargets[key] = {\n\t\t\t\t\tposition: entity.group.position,\n\t\t\t\t\trotation: entity.group.quaternion,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tdt: delta,\n\t\t\ttime: this._elapsedTime,\n\t\t\tviewport: {\n\t\t\t\twidth: this.screenResolution.x,\n\t\t\t\theight: this.screenResolution.y,\n\t\t\t\taspect: this.screenResolution.x / this.screenResolution.y,\n\t\t\t},\n\t\t\ttargets,\n\t\t};\n\t}\n\n\t/**\n\t * Apply the final pipeline pose to the Three.js camera.\n\t */\n\tprivate commitPose(pose: CameraPose): void {\n\t\tthis.camera.position.copy(pose.position);\n\n\t\tif (pose.lookAt) {\n\t\t\tthis.camera.lookAt(pose.lookAt);\n\t\t} else {\n\t\t\tthis.camera.quaternion.copy(pose.rotation);\n\t\t}\n\n\t\tif (this.camera instanceof PerspectiveCamera) {\n\t\t\tif (pose.fov != null) this.camera.fov = pose.fov;\n\t\t\tif (pose.near != null) this.camera.near = pose.near;\n\t\t\tif (pose.far != null) this.camera.far = pose.far;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\n\t\tif (this.camera instanceof OrthographicCamera) {\n\t\t\tif (pose.zoom != null) {\n\t\t\t\tconst aspect = this.screenResolution.x / this.screenResolution.y;\n\t\t\t\tconst size = pose.zoom;\n\t\t\t\tthis.camera.left = -size * aspect / 2;\n\t\t\t\tthis.camera.right = size * aspect / 2;\n\t\t\t\tthis.camera.top = size / 2;\n\t\t\t\tthis.camera.bottom = -size / 2;\n\t\t\t}\n\t\t\tif (pose.near != null) this.camera.near = pose.near;\n\t\t\tif (pose.far != null) this.camera.far = pose.far;\n\t\t\tthis.camera.updateProjectionMatrix();\n\t\t}\n\t}\n\n\t/**\n\t * Create a Three.js camera based on perspective type.\n\t */\n\tprivate createCameraForPerspective(aspectRatio: number): Camera {\n\t\tswitch (this._perspective) {\n\t\t\tcase Perspectives.ThirdPerson:\n\t\t\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t\t\tcase Perspectives.FirstPerson:\n\t\t\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t\t\tcase Perspectives.Isometric:\n\t\t\t\treturn new OrthographicCamera(\n\t\t\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\t\t\tthis.frustumSize / 2,\n\t\t\t\t\tthis.frustumSize / -2,\n\t\t\t\t\t1, 1000\n\t\t\t\t);\n\t\t\tcase Perspectives.Flat2D:\n\t\t\tcase Perspectives.Fixed2D:\n\t\t\t\treturn new OrthographicCamera(\n\t\t\t\t\tthis.frustumSize * aspectRatio / -2,\n\t\t\t\t\tthis.frustumSize * aspectRatio / 2,\n\t\t\t\t\tthis.frustumSize / 2,\n\t\t\t\t\tthis.frustumSize / -2,\n\t\t\t\t\t1, 1000\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn new PerspectiveCamera(75, aspectRatio, 0.1, 1000);\n\t\t}\n\t}\n}\n","export const Perspectives = {\n\tFirstPerson: 'first-person',\n\tThirdPerson: 'third-person',\n\tIsometric: 'isometric',\n\tFlat2D: 'flat-2d',\n\tFixed2D: 'fixed-2d',\n\tTopDown: 'top-down',\n} as const;\n\nexport type PerspectiveType = (typeof Perspectives)[keyof typeof Perspectives];\n","import { Object3D, Vector3, Quaternion, Camera, Scene } from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\n\nexport interface CameraDebugState {\n\tenabled: boolean;\n\tselected: string[];\n}\n\nexport interface CameraDebugDelegate {\n\tsubscribe(listener: (state: CameraDebugState) => void): () => void;\n\tresolveTarget(uuid: string): Object3D | null;\n}\n\n/**\n * Manages orbit controls for a camera.\n * Supports two modes:\n * 1. **Debug mode**: orbit controls activated by the debug system, with save/restore of camera state\n * 2. **User mode**: orbit controls enabled by the user via `useOrbitalControls` camera option\n *\n * These modes are independent -- debug mode takes precedence but user mode\n * keeps orbit controls active even outside debug.\n */\nexport class CameraOrbitController {\n\tprivate camera: Camera;\n\tprivate domElement: HTMLElement;\n\tprivate cameraRig: Object3D | null = null;\n\tprivate sceneRef: Scene | null = null;\n\t\n\tprivate orbitControls: OrbitControls | null = null;\n\tprivate orbitTarget: Object3D | null = null;\n\tprivate orbitTargetWorldPos: Vector3 = new Vector3();\n\n\tprivate debugDelegate: CameraDebugDelegate | null = null;\n\tprivate debugUnsubscribe: (() => void) | null = null;\n\tprivate debugStateSnapshot: CameraDebugState = { enabled: false, selected: [] };\n\n\t// Saved camera state for restoration when exiting debug mode\n\tprivate savedCameraPosition: Vector3 | null = null;\n\tprivate savedCameraQuaternion: Quaternion | null = null;\n\tprivate savedCameraZoom: number | null = null;\n\tprivate savedCameraLocalPosition: Vector3 | null = null;\n\n\t// Saved debug camera state for restoration when re-entering debug mode\n\tprivate savedDebugCameraPosition: Vector3 | null = null;\n\tprivate savedDebugCameraQuaternion: Quaternion | null = null;\n\tprivate savedDebugCameraZoom: number | null = null;\n\tprivate savedDebugOrbitTarget: Vector3 | null = null;\n\n\t/** Whether user-configured orbital controls are enabled (independent of debug) */\n\tprivate _userOrbitEnabled = false;\n\n\tconstructor(camera: Camera, domElement: HTMLElement, cameraRig?: Object3D | null) {\n\t\tthis.camera = camera;\n\t\tthis.domElement = domElement;\n\t\tthis.cameraRig = cameraRig ?? null;\n\t}\n\n\t/**\n\t * Set the scene reference for adding/removing camera when detaching from rig.\n\t */\n\tsetScene(scene: Scene | null): void {\n\t\tthis.sceneRef = scene;\n\t}\n\n\t/**\n\t * Check if debug mode is currently active (orbit controls enabled via debug system).\n\t */\n\tget isActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled;\n\t}\n\n\t/**\n\t * Check if any orbit controls are currently active (debug or user).\n\t */\n\tget isOrbitActive(): boolean {\n\t\treturn this.debugStateSnapshot.enabled || this._userOrbitEnabled;\n\t}\n\n\t/**\n\t * Update orbit controls each frame.\n\t * Should be called from the camera's update loop.\n\t */\n\tupdate() {\n\t\tif (this.orbitControls && this.orbitTarget) {\n\t\t\tthis.orbitTarget.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t}\n\t\tthis.orbitControls?.update();\n\t}\n\n\t/**\n\t * Enable user-configured orbital controls (not debug mode).\n\t * These orbit controls persist until explicitly disabled.\n\t */\n\tenableUserOrbitControls(): void {\n\t\tthis._userOrbitEnabled = true;\n\t\tif (!this.orbitControls) {\n\t\t\tthis.enableOrbitControls();\n\t\t}\n\t}\n\n\t/**\n\t * Disable user-configured orbital controls.\n\t * Will not disable orbit controls if debug mode is active.\n\t */\n\tdisableUserOrbitControls(): void {\n\t\tthis._userOrbitEnabled = false;\n\t\t// Only disable orbit controls if debug mode isn't also using them\n\t\tif (!this.debugStateSnapshot.enabled) {\n\t\t\tthis.disableOrbitControls();\n\t\t}\n\t}\n\n\t/**\n\t * Attach a delegate to react to debug state changes.\n\t */\n\tsetDebugDelegate(delegate: CameraDebugDelegate | null) {\n\t\tif (this.debugDelegate === delegate) {\n\t\t\treturn;\n\t\t}\n\t\tthis.detachDebugDelegate();\n\t\tthis.debugDelegate = delegate;\n\t\tif (!delegate) {\n\t\t\tthis.applyDebugState({ enabled: false, selected: [] });\n\t\t\treturn;\n\t\t}\n\t\tconst unsubscribe = delegate.subscribe((state) => {\n\t\t\tthis.applyDebugState(state);\n\t\t});\n\t\tthis.debugUnsubscribe = () => {\n\t\t\tunsubscribe?.();\n\t\t};\n\t}\n\n\t/**\n\t * Clean up resources.\n\t */\n\tdispose() {\n\t\tthis.disableOrbitControls();\n\t\tthis.detachDebugDelegate();\n\t}\n\n\t/**\n\t * Get the current debug state snapshot.\n\t */\n\tget debugState(): CameraDebugState {\n\t\treturn this.debugStateSnapshot;\n\t}\n\n\tprivate applyDebugState(state: CameraDebugState) {\n\t\tconst wasEnabled = this.debugStateSnapshot.enabled;\n\t\tthis.debugStateSnapshot = {\n\t\t\tenabled: state.enabled,\n\t\t\tselected: [...state.selected],\n\t\t};\n\t\tif (state.enabled && !wasEnabled) {\n\t\t\t// Entering debug mode: save game camera state, detach from rig, restore debug camera state if available\n\t\t\tthis.saveCameraState();\n\t\t\tthis.detachCameraFromRig();\n\t\t\tthis.enableOrbitControls();\n\t\t\tthis.restoreDebugCameraState();\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t} else if (!state.enabled && wasEnabled) {\n\t\t\t// Exiting debug mode: save debug camera state, then restore game camera state\n\t\t\tthis.saveDebugCameraState();\n\t\t\tthis.orbitTarget = null;\n\t\t\t// Only disable orbit controls if user mode isn't keeping them on\n\t\t\tif (!this._userOrbitEnabled) {\n\t\t\t\tthis.disableOrbitControls();\n\t\t\t}\n\t\t\tthis.reattachCameraToRig();\n\t\t\tthis.restoreCameraState();\n\t\t} else if (state.enabled) {\n\t\t\t// Still in debug mode, just update target\n\t\t\tthis.updateOrbitTargetFromSelection(state.selected);\n\t\t}\n\t}\n\n\tprivate enableOrbitControls() {\n\t\tif (this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls = new OrbitControls(this.camera, this.domElement);\n\t\tthis.orbitControls.enableDamping = true;\n\t\tthis.orbitControls.dampingFactor = 0.05;\n\t\tthis.orbitControls.screenSpacePanning = false;\n\t\tthis.orbitControls.minDistance = 1;\n\t\tthis.orbitControls.maxDistance = 500;\n\t\tthis.orbitControls.maxPolarAngle = Math.PI / 2;\n\t\t// Default target to origin\n\t\tthis.orbitControls.target.set(0, 0, 0);\n\t}\n\n\tprivate disableOrbitControls() {\n\t\tif (!this.orbitControls) {\n\t\t\treturn;\n\t\t}\n\t\tthis.orbitControls.dispose();\n\t\tthis.orbitControls = null;\n\t}\n\n\tprivate updateOrbitTargetFromSelection(selected: string[]) {\n\t\t// Default to origin when no entity is selected\n\t\tif (!this.debugDelegate || selected.length === 0) {\n\t\t\tthis.orbitTarget = null;\n\t\t\tif (this.orbitControls) {\n\t\t\t\tthis.orbitControls.target.set(0, 0, 0);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tfor (let i = selected.length - 1; i >= 0; i -= 1) {\n\t\t\tconst uuid = selected[i];\n\t\t\tconst targetObject = this.debugDelegate.resolveTarget(uuid);\n\t\t\tif (targetObject) {\n\t\t\t\tthis.orbitTarget = targetObject;\n\t\t\t\tif (this.orbitControls) {\n\t\t\t\t\ttargetObject.getWorldPosition(this.orbitTargetWorldPos);\n\t\t\t\t\tthis.orbitControls.target.copy(this.orbitTargetWorldPos);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tthis.orbitTarget = null;\n\t}\n\n\tprivate detachDebugDelegate() {\n\t\tif (this.debugUnsubscribe) {\n\t\t\ttry {\n\t\t\t\tthis.debugUnsubscribe();\n\t\t\t} catch { /* noop */ }\n\t\t}\n\t\tthis.debugUnsubscribe = null;\n\t\tthis.debugDelegate = null;\n\t}\n\n\t/**\n\t * Save camera position, rotation, and zoom before entering debug mode.\n\t */\n\tprivate saveCameraState() {\n\t\tthis.savedCameraPosition = this.camera.position.clone();\n\t\tthis.savedCameraQuaternion = this.camera.quaternion.clone();\n\t\t// Save zoom for orthographic/perspective cameras\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t}\n\n\t/**\n\t * Restore camera position, rotation, and zoom when exiting debug mode.\n\t */\n\tprivate restoreCameraState() {\n\t\tif (this.savedCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraPosition);\n\t\t\tthis.savedCameraPosition = null;\n\t\t}\n\t\tif (this.savedCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedCameraQuaternion);\n\t\t\tthis.savedCameraQuaternion = null;\n\t\t}\n\t\tif (this.savedCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t\tthis.savedCameraZoom = null;\n\t\t}\n\t}\n\n\t/**\n\t * Save debug camera state when exiting debug mode.\n\t */\n\tprivate saveDebugCameraState() {\n\t\tthis.savedDebugCameraPosition = this.camera.position.clone();\n\t\tthis.savedDebugCameraQuaternion = this.camera.quaternion.clone();\n\t\tif ('zoom' in this.camera) {\n\t\t\tthis.savedDebugCameraZoom = (this.camera as any).zoom as number;\n\t\t}\n\t\tif (this.orbitControls) {\n\t\t\tthis.savedDebugOrbitTarget = this.orbitControls.target.clone();\n\t\t}\n\t}\n\n\t/**\n\t * Restore debug camera state when re-entering debug mode.\n\t */\n\tprivate restoreDebugCameraState() {\n\t\tif (this.savedDebugCameraPosition) {\n\t\t\tthis.camera.position.copy(this.savedDebugCameraPosition);\n\t\t}\n\t\tif (this.savedDebugCameraQuaternion) {\n\t\t\tthis.camera.quaternion.copy(this.savedDebugCameraQuaternion);\n\t\t}\n\t\tif (this.savedDebugCameraZoom !== null && 'zoom' in this.camera) {\n\t\t\tthis.camera.zoom = this.savedDebugCameraZoom;\n\t\t\t(this.camera as any).updateProjectionMatrix?.();\n\t\t}\n\t\tif (this.savedDebugOrbitTarget && this.orbitControls) {\n\t\t\tthis.orbitControls.target.copy(this.savedDebugOrbitTarget);\n\t\t}\n\t}\n\n\t/**\n\t * Detach camera from its rig to allow free orbit movement in debug mode.\n\t * Preserves the camera's world position.\n\t */\n\tprivate detachCameraFromRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent !== this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Save the camera's local position for later restoration\n\t\tthis.savedCameraLocalPosition = this.camera.position.clone();\n\n\t\t// Get camera's world position before detaching\n\t\tconst worldPos = new Vector3();\n\t\tthis.camera.getWorldPosition(worldPos);\n\n\t\t// Remove camera from rig\n\t\tthis.cameraRig.remove(this.camera);\n\n\t\t// Add camera directly to scene if scene ref is available\n\t\tif (this.sceneRef) {\n\t\t\tthis.sceneRef.add(this.camera);\n\t\t}\n\n\t\t// Set camera's position to its previous world position\n\t\tthis.camera.position.copy(worldPos);\n\t}\n\n\t/**\n\t * Reattach camera to its rig when exiting debug mode.\n\t * Restores the camera's local position relative to the rig.\n\t */\n\tprivate reattachCameraToRig(): void {\n\t\tif (!this.cameraRig || this.camera.parent === this.cameraRig) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remove camera from scene if it's there\n\t\tif (this.sceneRef && this.camera.parent === this.sceneRef) {\n\t\t\tthis.sceneRef.remove(this.camera);\n\t\t}\n\n\t\t// Add camera back to rig\n\t\tthis.cameraRig.add(this.camera);\n\n\t\t// Restore camera's local position\n\t\tif (this.savedCameraLocalPosition) {\n\t\t\tthis.camera.position.copy(this.savedCameraLocalPosition);\n\t\t\tthis.savedCameraLocalPosition = null;\n\t\t}\n\t}\n}\n","import { Vector2, WebGLRenderer, Scene, Camera, PerspectiveCamera } from 'three';\nimport { WebGPURenderer } from 'three/webgpu';\nimport { EffectComposer } from 'three/examples/jsm/postprocessing/EffectComposer.js';\nimport RenderPass from '../graphics/render-pass';\nimport type { ZylemCamera } from './zylem-camera';\n\n/**\n * Renderer type option for choosing rendering backend\n * - 'auto': Try WebGPU first, fall back to WebGL\n * - 'webgpu': Force WebGPU (error if not supported)\n * - 'webgl': Force WebGL\n */\nexport type RendererType = 'auto' | 'webgpu' | 'webgl';\n\n/**\n * Union type for renderer instances\n */\nexport type ZylemRenderer = WebGLRenderer | WebGPURenderer;\n\n/**\n * Viewport definition in normalized coordinates (0-1).\n * Represents a rectangular region of the canvas for camera rendering.\n */\nexport interface Viewport {\n\tx: number;\n\ty: number;\n\twidth: number;\n\theight: number;\n}\n\n/** Default fullscreen viewport */\nexport const DEFAULT_VIEWPORT: Viewport = { x: 0, y: 0, width: 1, height: 1 };\n\n/**\n * Check if WebGPU is supported in the current browser\n */\nexport async function isWebGPUSupported(): Promise<boolean> {\n\tif (!('gpu' in navigator)) return false;\n\ttry {\n\t\tconst adapter = await (navigator as any).gpu.requestAdapter();\n\t\treturn adapter !== null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * RendererManager owns the shared WebGL/WebGPU renderer, canvas element,\n * effect composer, and render loop. There is one RendererManager per game.\n *\n * It iterates active cameras and renders each with its configured viewport.\n */\nexport class RendererManager {\n\trenderer!: ZylemRenderer;\n\tcomposer!: EffectComposer;\n\tscreenResolution: Vector2;\n\trendererType: RendererType;\n\tprivate _isWebGPU = false;\n\tprivate _initialized = false;\n\tprivate _sceneRef: Scene | null = null;\n\tprivate _lastAnimationTimestamp: number | null = null;\n\n\tconstructor(screenResolution?: Vector2, rendererType: RendererType = 'webgl') {\n\t\tthis.screenResolution = screenResolution || new Vector2(window.innerWidth, window.innerHeight);\n\t\tthis.rendererType = rendererType;\n\t}\n\n\t/**\n\t * Check if the renderer has been initialized\n\t */\n\tget initialized(): boolean {\n\t\treturn this._initialized;\n\t}\n\n\t/**\n\t * Check if using WebGPU renderer\n\t */\n\tget isWebGPU(): boolean {\n\t\treturn this._isWebGPU;\n\t}\n\n\t/**\n\t * Initialize the renderer (must be called before rendering).\n\t * Async because WebGPU requires async initialization.\n\t */\n\tasync initRenderer(): Promise<void> {\n\t\tif (this._initialized) return;\n\n\t\tlet useWebGPU = false;\n\n\t\tif (this.rendererType === 'webgpu') {\n\t\t\tuseWebGPU = true;\n\t\t} else if (this.rendererType === 'auto') {\n\t\t\tuseWebGPU = await isWebGPUSupported();\n\t\t}\n\n\t\tif (useWebGPU) {\n\t\t\ttry {\n\t\t\t\tthis.renderer = new WebGPURenderer({ antialias: true });\n\t\t\t\tawait this.renderer.init();\n\t\t\t\tthis._isWebGPU = true;\n\t\t\t\tconsole.log('RendererManager: Using WebGPU renderer');\n\t\t\t} catch (e) {\n\t\t\t\tconsole.warn('RendererManager: WebGPU init failed, falling back to WebGL', e);\n\t\t\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\t\t\tthis._isWebGPU = false;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.renderer = new WebGLRenderer({ antialias: false, alpha: true });\n\t\t\tthis._isWebGPU = false;\n\t\t\tconsole.log('RendererManager: Using WebGL renderer');\n\t\t}\n\n\t\tthis.renderer.setSize(this.screenResolution.x, this.screenResolution.y);\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.shadowMap.enabled = true;\n\t\t}\n\n\t\t// Initialize composer (WebGPU uses different post-processing)\n\t\tif (!this._isWebGPU) {\n\t\t\tthis.composer = new EffectComposer(this.renderer as WebGLRenderer);\n\t\t}\n\n\t\tthis._initialized = true;\n\t}\n\n\t/**\n\t * Set the current scene reference for rendering.\n\t */\n\tsetScene(scene: Scene): void {\n\t\tthis._sceneRef = scene;\n\t}\n\n\t/**\n\t * Setup post-processing render pass for a camera (WebGL only).\n\t */\n\tsetupRenderPass(scene: Scene, camera: Camera): void {\n\t\tif (this._isWebGPU || !this.composer) return;\n\n\t\t// Dispose old passes before adding new ones (prevents GPU leak on stage transitions)\n\t\tif (this.composer.passes.length > 0) {\n\t\t\tthis.composer.passes.forEach((p: any) => { try { p.dispose?.(); } catch { /* noop */ } });\n\t\t\tthis.composer.passes.length = 0;\n\t\t}\n\n\t\tconst renderResolution = this.screenResolution.clone().divideScalar(2);\n\t\trenderResolution.x |= 0;\n\t\trenderResolution.y |= 0;\n\t\tconst pass = new RenderPass(renderResolution, scene, camera);\n\t\tthis.composer.addPass(pass);\n\t}\n\n\t/**\n\t * Start the render loop. Calls the provided callback each frame.\n\t */\n\tstartRenderLoop(onFrame: (delta: number) => void): void {\n\t\tthis._lastAnimationTimestamp = null;\n\t\tthis.renderer.setAnimationLoop((timestamp: number) => {\n\t\t\tconst deltaSeconds = this._lastAnimationTimestamp === null\n\t\t\t\t? 0\n\t\t\t\t: Math.max(0, (timestamp - this._lastAnimationTimestamp) / 1000);\n\t\t\tthis._lastAnimationTimestamp = timestamp;\n\t\t\tonFrame(deltaSeconds);\n\t\t});\n\t}\n\n\t/**\n\t * Stop the render loop.\n\t */\n\tstopRenderLoop(): void {\n\t\tthis._lastAnimationTimestamp = null;\n\t\ttry {\n\t\t\tthis.renderer.setAnimationLoop(null as any);\n\t\t} catch { /* noop */ }\n\t}\n\n\t/**\n\t * Render a scene from a single camera's perspective.\n\t * Sets the viewport based on the camera's viewport config.\n\t */\n\trenderCamera(scene: Scene, camera: ZylemCamera): void {\n\t\tconst vp = camera.viewport;\n\t\tconst w = this.screenResolution.x;\n\t\tconst h = this.screenResolution.y;\n\n\t\t// Set scissor and viewport for this camera\n\t\tconst pixelX = Math.floor(vp.x * w);\n\t\tconst pixelY = Math.floor(vp.y * h);\n\t\tconst pixelW = Math.floor(vp.width * w);\n\t\tconst pixelH = Math.floor(vp.height * h);\n\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setViewport(pixelX, pixelY, pixelW, pixelH);\n\t\t\tthis.renderer.setScissor(pixelX, pixelY, pixelW, pixelH);\n\t\t\tthis.renderer.setScissorTest(true);\n\t\t}\n\n\t\tif (this._isWebGPU) {\n\t\t\tthis.renderer.render(scene, camera.camera);\n\t\t} else if (this.composer) {\n\t\t\tthis.composer.render(0);\n\t\t}\n\t}\n\n\t/**\n\t * Render a camera to its offscreen render target (WebGL only).\n\t * Bypasses the EffectComposer since post-processing is not needed\n\t * for render-to-texture output.\n\t *\n\t * The camera must have a non-null renderTarget.\n\t */\n\trenderCameraToTarget(scene: Scene, camera: ZylemCamera): void {\n\t\tif (!camera.renderTarget) return;\n\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tconst prevTarget = this.renderer.getRenderTarget();\n\t\t\tthis.renderer.setRenderTarget(camera.renderTarget);\n\t\t\tthis.renderer.clear();\n\t\t\tthis.renderer.render(scene, camera.camera);\n\t\t\tthis.renderer.setRenderTarget(prevTarget);\n\t\t} else {\n\t\t\t// WebGPU RTT not yet supported\n\t\t\tconsole.warn('RendererManager: Render-to-texture is not yet supported for WebGPU');\n\t\t}\n\t}\n\n\t/**\n\t * Render a scene from multiple cameras, each with their own viewport.\n\t * Cameras are rendered in order (first = bottom layer, last = top layer).\n\t */\n\trenderCameras(scene: Scene, cameras: ZylemCamera[]): void {\n\t\tif (!scene || cameras.length === 0) return;\n\n\t\t// Clear the full canvas first\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setScissorTest(false);\n\t\t\tthis.renderer.clear();\n\t\t}\n\n\t\tfor (const cam of cameras) {\n\t\t\tthis.renderCamera(scene, cam);\n\t\t}\n\n\t\t// Restore scissor test state\n\t\tif (this.renderer instanceof WebGLRenderer) {\n\t\t\tthis.renderer.setScissorTest(false);\n\t\t}\n\t}\n\n\t/**\n\t * Simple single-camera render (backwards compatible).\n\t * Uses the full viewport for a single camera.\n\t */\n\trender(scene: Scene, camera: Camera): void {\n\t\tif (this._isWebGPU) {\n\t\t\tthis.renderer.render(scene, camera);\n\t\t} else if (this.composer) {\n\t\t\tthis.composer.render(0);\n\t\t}\n\t}\n\n\t/**\n\t * Resize the renderer and update resolution.\n\t */\n\tresize(width: number, height: number): void {\n\t\tthis.screenResolution.set(width, height);\n\t\tthis.renderer.setSize(width, height, false);\n\t\tif (this.composer) {\n\t\t\tthis.composer.setSize(width, height);\n\t\t}\n\t}\n\n\t/**\n\t * Update renderer pixel ratio (DPR).\n\t */\n\tsetPixelRatio(dpr: number): void {\n\t\tconst safe = Math.max(1, Number.isFinite(dpr) ? dpr : 1);\n\t\tthis.renderer.setPixelRatio(safe);\n\t}\n\n\t/**\n\t * Get the DOM element for the renderer.\n\t */\n\tgetDomElement(): HTMLCanvasElement {\n\t\treturn this.renderer.domElement;\n\t}\n\n\t/**\n\t * Dispose renderer, composer, and related resources.\n\t */\n\tdispose(): void {\n\t\tthis.stopRenderLoop();\n\t\ttry {\n\t\t\tthis.composer?.passes?.forEach((p: any) => p.dispose?.());\n\t\t\t(this.composer as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\tthis.renderer.dispose();\n\t\t} catch { /* noop */ }\n\t\tthis._sceneRef = null;\n\t\tthis._initialized = false;\n\t}\n}\n","import * as THREE from 'three';\nimport { standardShader } from './shaders/standard.shader';\nimport { WebGLRenderer, WebGLRenderTarget } from 'three';\nimport { Pass, FullScreenQuad } from 'three/addons/postprocessing/Pass.js';\n\nexport default class RenderPass extends Pass {\n\tfsQuad: FullScreenQuad;\n\tresolution: THREE.Vector2;\n\tscene: THREE.Scene;\n\tcamera: THREE.Camera;\n\trgbRenderTarget: WebGLRenderTarget;\n\tnormalRenderTarget: WebGLRenderTarget;\n\tnormalMaterial: THREE.Material;\n\n\tconstructor(resolution: THREE.Vector2, scene: THREE.Scene, camera: THREE.Camera) {\n\t\tsuper();\n\t\tthis.resolution = resolution;\n\t\tthis.fsQuad = new FullScreenQuad(this.material());\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\n\t\tthis.rgbRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\t\tthis.normalRenderTarget = new WebGLRenderTarget(resolution.x * 4, resolution.y * 4);\n\n\t\tthis.normalMaterial = new THREE.MeshNormalMaterial();\n\t}\n\n\trender(\n\t\trenderer: WebGLRenderer,\n\t\twriteBuffer: WebGLRenderTarget\n\t) {\n\t\trenderer.setRenderTarget(this.rgbRenderTarget);\n\t\trenderer.render(this.scene, this.camera);\n\n\t\tconst overrideMaterial_old = this.scene.overrideMaterial;\n\t\trenderer.setRenderTarget(this.normalRenderTarget);\n\t\tthis.scene.overrideMaterial = this.normalMaterial;\n\t\trenderer.render(this.scene, this.camera);\n\t\tthis.scene.overrideMaterial = overrideMaterial_old;\n\n\t\t// @ts-ignore\n\t\tconst uniforms = this.fsQuad.material.uniforms;\n\t\tuniforms.tDiffuse.value = this.rgbRenderTarget.texture;\n\t\tuniforms.tDepth.value = this.rgbRenderTarget.depthTexture;\n\t\tuniforms.tNormal.value = this.normalRenderTarget.texture;\n\t\tuniforms.iTime.value += 0.01;\n\n\t\tif (this.renderToScreen) {\n\t\t\trenderer.setRenderTarget(null);\n\t\t} else {\n\t\t\trenderer.setRenderTarget(writeBuffer);\n\t\t}\n\t\tthis.fsQuad.render(renderer);\n\t}\n\n\tmaterial() {\n\t\treturn new THREE.ShaderMaterial({\n\t\t\tuniforms: {\n\t\t\t\tiTime: { value: 0 },\n\t\t\t\ttDiffuse: { value: null },\n\t\t\t\ttDepth: { value: null },\n\t\t\t\ttNormal: { value: null },\n\t\t\t\tresolution: {\n\t\t\t\t\tvalue: new THREE.Vector4(\n\t\t\t\t\t\tthis.resolution.x,\n\t\t\t\t\t\tthis.resolution.y,\n\t\t\t\t\t\t1 / this.resolution.x,\n\t\t\t\t\t\t1 / this.resolution.y,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t},\n\t\t\tvertexShader: standardShader.vertex,\n\t\t\tfragmentShader: standardShader.fragment\n\t\t});\n\t}\n\n\tdispose() {\n\t\ttry {\n\t\t\tthis.fsQuad?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.rgbRenderTarget as any)?.dispose?.();\n\t\t\t(this.normalRenderTarget as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t\ttry {\n\t\t\t(this.normalMaterial as any)?.dispose?.();\n\t\t} catch { /* noop */ }\n\t}\n}\n","export const objectVertexShader = `\nuniform vec2 uvScale;\nvarying vec2 vUv;\n\nvoid main() {\n\tvUv = uv;\n\tvec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );\n\tgl_Position = projectionMatrix * mvPosition;\n}\n`;\n","import { objectVertexShader } from './vertex/object.shader';\n\nconst fragment = `\nuniform sampler2D tDiffuse;\nvarying vec2 vUv;\n\nvoid main() {\n\tvec4 texel = texture2D( tDiffuse, vUv );\n\n\tgl_FragColor = texel;\n}\n`;\n\nexport const standardShader = {\n vertex: objectVertexShader,\n fragment\n};\n","import { Vector3, Quaternion, MathUtils } from 'three';\nimport type { CameraPose, PoseDelta } from './types';\n\n/**\n * Create a default camera pose at the origin facing forward.\n */\nexport function defaultPose(): CameraPose {\n\treturn {\n\t\tposition: new Vector3(0, 0, 10),\n\t\trotation: new Quaternion(),\n\t\tfov: 75,\n\t\tzoom: 1,\n\t\tnear: 0.1,\n\t\tfar: 1000,\n\t};\n}\n\n/**\n * Deep-clone a CameraPose so mutations don't leak between pipeline stages.\n */\nexport function clonePose(pose: CameraPose): CameraPose {\n\treturn {\n\t\tposition: pose.position.clone(),\n\t\trotation: pose.rotation.clone(),\n\t\tfov: pose.fov,\n\t\tzoom: pose.zoom,\n\t\tnear: pose.near,\n\t\tfar: pose.far,\n\t\tlookAt: pose.lookAt?.clone(),\n\t};\n}\n\n/**\n * Apply an additive PoseDelta on top of a CameraPose.\n * - Position: vector addition\n * - Rotation: quaternion multiplication (compose)\n * - FOV/Zoom: scalar addition\n *\n * Returns a new CameraPose (does not mutate the input).\n */\nexport function applyDelta(pose: CameraPose, delta: PoseDelta): CameraPose {\n\tconst result = clonePose(pose);\n\n\tif (delta.position) {\n\t\tresult.position.add(delta.position);\n\t}\n\tif (delta.rotation) {\n\t\tresult.rotation.multiply(delta.rotation);\n\t}\n\tif (delta.fov != null && result.fov != null) {\n\t\tresult.fov += delta.fov;\n\t}\n\tif (delta.zoom != null && result.zoom != null) {\n\t\tresult.zoom += delta.zoom;\n\t}\n\n\treturn result;\n}\n\n/**\n * Interpolate from `current` pose toward `target` pose using frame-rate-independent damping.\n *\n * @param current The current (smoothed) pose from the previous frame.\n * @param target The desired pose for this frame.\n * @param damping Smoothing factor in 0-1 range. 1 = instant snap, 0 = no movement.\n * @param dt Frame delta time in seconds.\n * @returns A new CameraPose interpolated between current and target.\n */\nexport function smoothPose(current: CameraPose, target: CameraPose, damping: number, dt: number): CameraPose {\n\tconst t = 1 - Math.pow(1 - MathUtils.clamp(damping, 0, 1), dt * 60);\n\n\tconst result = clonePose(current);\n\n\tresult.position.lerp(target.position, t);\n\tresult.rotation.slerp(target.rotation, t);\n\n\tif (target.fov != null && result.fov != null) {\n\t\tresult.fov = MathUtils.lerp(result.fov, target.fov, t);\n\t}\n\tif (target.zoom != null && result.zoom != null) {\n\t\tresult.zoom = MathUtils.lerp(result.zoom, target.zoom, t);\n\t}\n\tif (target.near != null) {\n\t\tresult.near = target.near;\n\t}\n\tif (target.far != null) {\n\t\tresult.far = target.far;\n\t}\n\n\t// Preserve lookAt from target (smoothing is on position/rotation, not lookAt)\n\tresult.lookAt = target.lookAt?.clone();\n\n\treturn result;\n}\n","import type {\n\tCameraPerspective,\n\tCameraBehavior,\n\tCameraAction,\n\tCameraContext,\n\tCameraPose,\n\tCameraPipelineState,\n} from './types';\nimport { defaultPose, clonePose, applyDelta, smoothPose } from './smoothing';\n\n/**\n * CameraPipeline runs a deterministic per-frame update:\n *\n * Perspective -> Behaviors (priority) -> Actions (deltas) -> Smoothing -> finalPose\n *\n * It separates \"desired pose\" from \"final pose\". Everything writes to desired;\n * only smoothing converts desired into the final committed pose.\n */\nexport class CameraPipeline {\n\t/** Active perspective (exactly one at a time). */\n\tperspective: CameraPerspective | null = null;\n\n\t/** Keyed behaviors, sorted by priority each frame. */\n\tprivate behaviors: Map<string, CameraBehavior> = new Map();\n\n\t/** Active transient actions. Expired actions are auto-removed. */\n\tprivate actions: CameraAction[] = [];\n\n\t/** The desired pose after perspective + behaviors + actions. */\n\tprivate _desiredPose: CameraPose = defaultPose();\n\n\t/** The smoothed final pose committed to the Three.js camera. */\n\tprivate _finalPose: CameraPose = defaultPose();\n\n\t/** Whether the pipeline has run at least once (prevents lerp from origin on first frame). */\n\tprivate _initialized = false;\n\n\t/** Smoothing factor: 0 = no movement, 1 = instant snap. */\n\tdamping = 0.15;\n\n\tconstructor(perspective?: CameraPerspective) {\n\t\tif (perspective) {\n\t\t\tthis.perspective = perspective;\n\t\t\tif (perspective.defaults?.damping != null) {\n\t\t\t\tthis.damping = perspective.defaults.damping;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Run the full pipeline for one frame.\n\t * Returns the final pose that should be committed to the Three.js camera.\n\t */\n\trun(ctx: CameraContext): CameraPose {\n\t\t// 1. Base pose from perspective\n\t\tlet pose: CameraPose = this.perspective\n\t\t\t? this.perspective.getBasePose(ctx)\n\t\t\t: defaultPose();\n\n\t\t// 2. Behaviors in priority order (low -> high)\n\t\tconst sorted = this.getSortedBehaviors();\n\t\tfor (const behavior of sorted) {\n\t\t\tif (behavior.enabled === false) continue;\n\t\t\tpose = behavior.update(ctx, pose);\n\t\t}\n\n\t\t// Store desired pose (before actions and smoothing)\n\t\tthis._desiredPose = clonePose(pose);\n\n\t\t// 3. Actions apply additive deltas; expired ones are removed\n\t\tfor (let i = this.actions.length - 1; i >= 0; i--) {\n\t\t\tconst action = this.actions[i];\n\t\t\tconst delta = action.update(ctx);\n\t\t\tpose = applyDelta(pose, delta);\n\t\t\tif (action.isDone(ctx)) {\n\t\t\t\tthis.actions.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\t// 4. Smoothing: interpolate from previous final pose toward computed pose\n\t\tif (!this._initialized) {\n\t\t\tthis._finalPose = clonePose(pose);\n\t\t\tthis._initialized = true;\n\t\t} else {\n\t\t\tthis._finalPose = smoothPose(this._finalPose, pose, this.damping, ctx.dt);\n\t\t}\n\n\t\treturn this._finalPose;\n\t}\n\n\t// ─── Behavior management ───────────────────────────────────────────────\n\n\t/**\n\t * Add or replace a behavior by key (idempotent).\n\t * Calls onDetach on the old behavior and onAttach on the new one.\n\t */\n\taddBehavior(key: string, behavior: CameraBehavior, ctx?: CameraContext): void {\n\t\tconst existing = this.behaviors.get(key);\n\t\tif (existing?.onDetach && ctx) {\n\t\t\texisting.onDetach(ctx);\n\t\t}\n\t\tthis.behaviors.set(key, behavior);\n\t\tif (behavior.onAttach && ctx) {\n\t\t\tbehavior.onAttach(ctx);\n\t\t}\n\t}\n\n\t/**\n\t * Remove a behavior by key. Calls onDetach if a context is provided.\n\t */\n\tremoveBehavior(key: string, ctx?: CameraContext): boolean {\n\t\tconst existing = this.behaviors.get(key);\n\t\tif (!existing) return false;\n\t\tif (existing.onDetach && ctx) {\n\t\t\texisting.onDetach(ctx);\n\t\t}\n\t\treturn this.behaviors.delete(key);\n\t}\n\n\t/**\n\t * Check whether a behavior with the given key exists.\n\t */\n\thasBehavior(key: string): boolean {\n\t\treturn this.behaviors.has(key);\n\t}\n\n\t// ─── Action management ─────────────────────────────────────────────────\n\n\t/**\n\t * Add a transient action. Actions self-expire via isDone().\n\t */\n\taddAction(action: CameraAction): void {\n\t\tthis.actions.push(action);\n\t}\n\n\t// ─── State inspection ──────────────────────────────────────────────────\n\n\t/**\n\t * Return a debug snapshot of the pipeline state.\n\t */\n\tgetState(): CameraPipelineState {\n\t\treturn {\n\t\t\tperspectiveId: this.perspective?.id ?? null,\n\t\t\tdesiredPose: this._desiredPose ? clonePose(this._desiredPose) : null,\n\t\t\tfinalPose: this._finalPose ? clonePose(this._finalPose) : null,\n\t\t\tactiveBehaviors: Array.from(this.behaviors.keys()),\n\t\t\tactiveActionCount: this.actions.length,\n\t\t};\n\t}\n\n\t/**\n\t * Set a new perspective. Resets the pipeline initialization flag so the\n\t * first frame with the new perspective snaps instead of lerping from the old pose.\n\t */\n\tsetPerspective(perspective: CameraPerspective): void {\n\t\tthis.perspective = perspective;\n\t\tthis._initialized = false;\n\t\tif (perspective.defaults?.damping != null) {\n\t\t\tthis.damping = perspective.defaults.damping;\n\t\t}\n\t}\n\n\t// ─── Internal helpers ──────────────────────────────────────────────────\n\n\tprivate getSortedBehaviors(): CameraBehavior[] {\n\t\treturn Array.from(this.behaviors.values()).sort(\n\t\t\t(a, b) => (a.priority ?? 0) - (b.priority ?? 0)\n\t\t);\n\t}\n}\n","import { Vector3, Quaternion } from 'three';\nimport type { CameraPerspective, CameraContext, CameraPose } from '../types';\n\n/**\n * Configuration for the third-person perspective.\n */\nexport interface ThirdPersonOptions {\n\t/** Distance behind the target. Default 8. */\n\tdistance?: number;\n\t/** Height above the target. Default 5. */\n\theight?: number;\n\t/** Lateral offset from the target (shoulder cam). Default 0. */\n\tshoulderOffset?: number;\n\t/** Key in CameraContext.targets to follow. Default 'primary'. */\n\ttargetKey?: string;\n\t/** Perspective field of view. Default 75. */\n\tfov?: number;\n\t/** Padding multiplier when framing multiple targets. Default 1.5. */\n\tpaddingFactor?: number;\n\t/** Minimum camera distance when multi-framing. Default 5. */\n\tminDistance?: number;\n\t/** Fallback camera position when no targets exist (e.g. the user-specified initial position). */\n\tinitialPosition?: Vector3;\n\t/** Fallback lookAt point when no targets exist. */\n\tinitialLookAt?: Vector3;\n}\n\ninterface ThirdPersonBaseDefaults {\n\tdistance: number;\n\theight: number;\n\tshoulderOffset: number;\n\ttargetKey: string;\n\tfov: number;\n\tpaddingFactor: number;\n\tminDistance: number;\n}\n\nconst DEFAULTS: ThirdPersonBaseDefaults = {\n\tdistance: 8,\n\theight: 5,\n\tshoulderOffset: 0,\n\ttargetKey: 'primary',\n\tfov: 75,\n\tpaddingFactor: 1.5,\n\tminDistance: 5,\n};\n\n/**\n * Third-person 3D perspective.\n *\n * - 0 targets: returns a static pose behind the origin.\n * - 1 target: camera positioned behind and above the target, looking at it.\n * - 2+ targets: weighted-centroid framing with dynamic distance.\n */\nexport class ThirdPersonPerspective implements CameraPerspective {\n\treadonly id = 'third-person';\n\treadonly defaults = { damping: 0.15 };\n\n\tprivate opts: ThirdPersonBaseDefaults;\n\tprivate initialPosition?: Vector3;\n\tprivate initialLookAt?: Vector3;\n\n\tconstructor(options?: ThirdPersonOptions) {\n\t\tconst { initialPosition, initialLookAt, ...rest } = options ?? {};\n\t\tthis.opts = { ...DEFAULTS, ...rest };\n\t\tthis.initialPosition = initialPosition;\n\t\tthis.initialLookAt = initialLookAt;\n\t}\n\n\tgetBasePose(ctx: CameraContext): CameraPose {\n\t\tconst targetKeys = Object.keys(ctx.targets);\n\t\tconst primary = ctx.targets[this.opts.targetKey];\n\n\t\tif (targetKeys.length === 0 || !primary) {\n\t\t\treturn this.staticPose();\n\t\t}\n\n\t\tif (targetKeys.length === 1) {\n\t\t\treturn this.singleTargetPose(primary.position);\n\t\t}\n\n\t\treturn this.multiTargetPose(ctx);\n\t}\n\n\t/**\n\t * No targets: use the user-specified initial position if available,\n\t * otherwise fall back to a default pose behind the origin.\n\t */\n\tprivate staticPose(): CameraPose {\n\t\tif (this.initialPosition) {\n\t\t\treturn {\n\t\t\t\tposition: this.initialPosition.clone(),\n\t\t\t\trotation: new Quaternion(),\n\t\t\t\tfov: this.opts.fov,\n\t\t\t\tzoom: 1,\n\t\t\t\tnear: 0.1,\n\t\t\t\tfar: 1000,\n\t\t\t\tlookAt: this.initialLookAt?.clone() ?? new Vector3(0, 0, 0),\n\t\t\t};\n\t\t}\n\n\t\tconst position = new Vector3(\n\t\t\tthis.opts.shoulderOffset,\n\t\t\tthis.opts.height,\n\t\t\tthis.opts.distance\n\t\t);\n\t\treturn {\n\t\t\tposition,\n\t\t\trotation: new Quaternion(),\n\t\t\tfov: this.opts.fov,\n\t\t\tzoom: 1,\n\t\t\tnear: 0.1,\n\t\t\tfar: 1000,\n\t\t\tlookAt: new Vector3(0, 0, 0),\n\t\t};\n\t}\n\n\t/**\n\t * Single target: position = target + offset, lookAt = target.\n\t */\n\tprivate singleTargetPose(targetPos: Vector3): CameraPose {\n\t\tconst position = new Vector3(\n\t\t\ttargetPos.x + this.opts.shoulderOffset,\n\t\t\ttargetPos.y + this.opts.height,\n\t\t\ttargetPos.z + this.opts.distance\n\t\t);\n\t\treturn {\n\t\t\tposition,\n\t\t\trotation: new Quaternion(),\n\t\t\tfov: this.opts.fov,\n\t\t\tzoom: 1,\n\t\t\tnear: 0.1,\n\t\t\tfar: 1000,\n\t\t\tlookAt: targetPos.clone(),\n\t\t};\n\t}\n\n\t/**\n\t * Multi-target: compute centroid and adjust distance to frame all targets.\n\t */\n\tprivate multiTargetPose(ctx: CameraContext): CameraPose {\n\t\tconst targets = Object.values(ctx.targets);\n\n\t\t// Centroid\n\t\tconst centroid = new Vector3();\n\t\tfor (const t of targets) {\n\t\t\tcentroid.add(t.position);\n\t\t}\n\t\tcentroid.divideScalar(targets.length);\n\n\t\t// Max distance from centroid to any target\n\t\tlet maxDist = 0;\n\t\tfor (const t of targets) {\n\t\t\tconst d = centroid.distanceTo(t.position);\n\t\t\tif (d > maxDist) maxDist = d;\n\t\t}\n\n\t\tconst dynamicDistance = Math.max(\n\t\t\tmaxDist * this.opts.paddingFactor,\n\t\t\tthis.opts.minDistance\n\t\t);\n\n\t\t// Offset direction from the base offset\n\t\tconst baseOffset = new Vector3(\n\t\t\tthis.opts.shoulderOffset,\n\t\t\tthis.opts.height,\n\t\t\tthis.opts.distance\n\t\t);\n\t\tconst baseLen = baseOffset.length();\n\t\tconst dir = baseLen > 0 ? baseOffset.clone().normalize() : new Vector3(0, 0.5, 1).normalize();\n\n\t\tconst position = centroid.clone().add(dir.multiplyScalar(dynamicDistance));\n\n\t\t// Preserve vertical ratio\n\t\tif (baseLen > 0) {\n\t\t\tconst heightRatio = this.opts.height / baseLen;\n\t\t\tposition.y = centroid.y + dynamicDistance * heightRatio;\n\t\t}\n\n\t\treturn {\n\t\t\tposition,\n\t\t\trotation: new Quaternion(),\n\t\t\tfov: this.opts.fov,\n\t\t\tzoom: 1,\n\t\t\tnear: 0.1,\n\t\t\tfar: 1000,\n\t\t\tlookAt: centroid.clone(),\n\t\t};\n\t}\n}\n","import { Vector3, Quaternion } from 'three';\nimport type { CameraPerspective, CameraContext, CameraPose } from '../types';\n\n/**\n * Configuration for the fixed 2D perspective.\n */\nexport interface Fixed2DOptions {\n\t/** Fixed camera position. Default (0, 0, 10). */\n\tposition?: { x: number; y: number; z: number };\n\t/** Orthographic zoom (frustum size). Default 10. */\n\tzoom?: number;\n}\n\nconst DEFAULTS: Required<Fixed2DOptions> = {\n\tposition: { x: 0, y: 0, z: 10 },\n\tzoom: 10,\n};\n\n/**\n * Fixed 2D perspective.\n *\n * Returns a static orthographic pose looking down the Z-axis.\n * No target following -- the camera stays at the configured position.\n */\nexport class Fixed2DPerspective implements CameraPerspective {\n\treadonly id = 'fixed-2d';\n\treadonly defaults = { damping: 1 };\n\n\tprivate opts: Required<Fixed2DOptions>;\n\n\tconstructor(options?: Fixed2DOptions) {\n\t\tthis.opts = { ...DEFAULTS, ...options };\n\t}\n\n\tgetBasePose(_ctx: CameraContext): CameraPose {\n\t\treturn {\n\t\t\tposition: new Vector3(\n\t\t\t\tthis.opts.position.x,\n\t\t\t\tthis.opts.position.y,\n\t\t\t\tthis.opts.position.z\n\t\t\t),\n\t\t\trotation: new Quaternion(),\n\t\t\tzoom: this.opts.zoom,\n\t\t\tnear: 1,\n\t\t\tfar: 1000,\n\t\t\tlookAt: new Vector3(this.opts.position.x, this.opts.position.y, 0),\n\t\t};\n\t}\n}\n","import { Vector3, Quaternion, Euler, MathUtils } from 'three';\nimport type { CameraPerspective, CameraContext, CameraPose } from '../types';\n\n/**\n * Configuration for the first-person perspective.\n */\nexport interface FirstPersonOptions {\n\t/** Vertical offset above the target entity's position (eye height). @default 1.7 */\n\teyeHeight?: number;\n\t/** Default field of view in degrees. @default 75 */\n\tdefaultFov?: number;\n\t/** Maximum pitch angle in radians. @default Math.PI/2 - 0.01 */\n\tpitchLimit?: number;\n\t/** Lerp speed for smooth look-at transitions. @default 5 */\n\tlookAtLerpSpeed?: number;\n\t/** Lerp speed for FOV zoom transitions. @default 8 */\n\tfovLerpSpeed?: number;\n\t/** Key in CameraContext.targets to follow. @default 'primary' */\n\ttargetKey?: string;\n\t/** Fallback position when no target entity is attached. */\n\tinitialPosition?: Vector3;\n\t/** Fallback look-at point used to derive initial yaw/pitch when no target. */\n\tinitialLookAt?: Vector3;\n}\n\ninterface Defaults {\n\teyeHeight: number;\n\tdefaultFov: number;\n\tpitchLimit: number;\n\tlookAtLerpSpeed: number;\n\tfovLerpSpeed: number;\n\ttargetKey: string;\n}\n\nconst DEFAULTS: Defaults = {\n\teyeHeight: 1.7,\n\tdefaultFov: 75,\n\tpitchLimit: Math.PI / 2 - 0.01,\n\tlookAtLerpSpeed: 5,\n\tfovLerpSpeed: 8,\n\ttargetKey: 'primary',\n};\n\n/**\n * First-person camera perspective.\n *\n * Position is derived from the attached target entity (+ eye height).\n * Rotation is driven via `look()` / `setLook()` methods called by game code\n * or a future FPS behavior. Supports smooth FOV zoom and lerp'd look-at.\n */\nexport class FirstPersonPerspective implements CameraPerspective {\n\treadonly id = 'first-person';\n\treadonly defaults = { damping: 1 };\n\n\tprivate opts: Defaults;\n\t/** Fallback position when no target entity is attached. Mutate directly for manual movement. */\n\tinitialPosition?: Vector3;\n\tprivate initialLookAt?: Vector3;\n\n\t// --- Look state ---\n\tprivate _yaw = 0;\n\tprivate _pitch = 0;\n\n\t// --- FOV zoom state ---\n\tprivate _currentFov: number;\n\tprivate _targetFov: number;\n\n\t// --- Look-at target state ---\n\tprivate _lookAtTarget: Vector3 | null = null;\n\tprivate _lookAtLerpSpeed: number;\n\tprivate _currentRotation = new Quaternion();\n\tprivate _rotationInitialized = false;\n\n\tconstructor(options?: FirstPersonOptions) {\n\t\tconst { initialPosition, initialLookAt, ...rest } = options ?? {};\n\t\tthis.opts = { ...DEFAULTS, ...rest };\n\t\tthis.initialPosition = initialPosition;\n\t\tthis.initialLookAt = initialLookAt;\n\n\t\tthis._currentFov = this.opts.defaultFov;\n\t\tthis._targetFov = this.opts.defaultFov;\n\t\tthis._lookAtLerpSpeed = this.opts.lookAtLerpSpeed;\n\n\t\tif (initialPosition && initialLookAt) {\n\t\t\tthis.deriveYawPitchFromLookAt(initialPosition, initialLookAt);\n\t\t}\n\t}\n\n\t// --- Public API (called by game code / FPS behavior) ---\n\n\t/** Accumulate yaw and pitch deltas. Pitch is clamped to the configured limit. */\n\tlook(deltaYaw: number, deltaPitch: number): void {\n\t\tthis._yaw += deltaYaw;\n\t\tthis._pitch = MathUtils.clamp(\n\t\t\tthis._pitch + deltaPitch,\n\t\t\t-this.opts.pitchLimit,\n\t\t\tthis.opts.pitchLimit,\n\t\t);\n\t}\n\n\t/** Set absolute yaw and pitch. Pitch is clamped to the configured limit. */\n\tsetLook(yaw: number, pitch: number): void {\n\t\tthis._yaw = yaw;\n\t\tthis._pitch = MathUtils.clamp(pitch, -this.opts.pitchLimit, this.opts.pitchLimit);\n\t}\n\n\t/** Current yaw in radians. */\n\tget yaw(): number { return this._yaw; }\n\n\t/** Current pitch in radians. */\n\tget pitch(): number { return this._pitch; }\n\n\t/** Set the target FOV for a smooth zoom transition (e.g. sniper scope). */\n\tzoom(fov: number): void {\n\t\tthis._targetFov = fov;\n\t}\n\n\t/** Return to the default FOV. */\n\tresetZoom(): void {\n\t\tthis._targetFov = this.opts.defaultFov;\n\t}\n\n\t/** Current field of view. */\n\tget currentFov(): number { return this._currentFov; }\n\n\t/**\n\t * Enable smooth look-at toward a world position.\n\t * The camera will slerp from the current rotation toward the look-at direction.\n\t */\n\tlookAt(target: Vector3, lerpSpeed?: number): void {\n\t\tthis._lookAtTarget = target;\n\t\tif (lerpSpeed != null) {\n\t\t\tthis._lookAtLerpSpeed = lerpSpeed;\n\t\t}\n\t}\n\n\t/** Disable look-at and return to manual yaw/pitch control. */\n\tclearLookAt(): void {\n\t\tif (this._lookAtTarget) {\n\t\t\tthis.deriveYawPitchFromQuaternion(this._currentRotation);\n\t\t}\n\t\tthis._lookAtTarget = null;\n\t}\n\n\t// --- CameraPerspective interface ---\n\n\tgetBasePose(ctx: CameraContext): CameraPose {\n\t\tconst position = this.computePosition(ctx);\n\t\tconst rotation = this.computeRotation(position, ctx.dt);\n\t\tthis._currentFov = this.lerpFov(ctx.dt);\n\n\t\treturn {\n\t\t\tposition,\n\t\t\trotation,\n\t\t\tfov: this._currentFov,\n\t\t\tnear: 0.1,\n\t\t\tfar: 1000,\n\t\t};\n\t}\n\n\t// --- Private helpers ---\n\n\tprivate computePosition(ctx: CameraContext): Vector3 {\n\t\tconst target = ctx.targets[this.opts.targetKey];\n\t\tif (target) {\n\t\t\treturn new Vector3(\n\t\t\t\ttarget.position.x,\n\t\t\t\ttarget.position.y + this.opts.eyeHeight,\n\t\t\t\ttarget.position.z,\n\t\t\t);\n\t\t}\n\t\tif (this.initialPosition) {\n\t\t\treturn this.initialPosition.clone();\n\t\t}\n\t\treturn new Vector3(0, this.opts.eyeHeight, 0);\n\t}\n\n\tprivate computeRotation(eyePosition: Vector3, dt: number): Quaternion {\n\t\tconst yawPitchQuat = new Quaternion().setFromEuler(\n\t\t\tnew Euler(this._pitch, this._yaw, 0, 'YXZ'),\n\t\t);\n\n\t\tif (!this._rotationInitialized) {\n\t\t\tthis._currentRotation.copy(yawPitchQuat);\n\t\t\tthis._rotationInitialized = true;\n\t\t}\n\n\t\tif (this._lookAtTarget) {\n\t\t\tconst dir = _vec3.copy(this._lookAtTarget).sub(eyePosition);\n\t\t\tif (dir.lengthSq() > 0.0001) {\n\t\t\t\tdir.normalize();\n\t\t\t\tconst desiredYaw = Math.atan2(-dir.x, -dir.z);\n\t\t\t\tconst desiredPitch = Math.asin(MathUtils.clamp(dir.y, -1, 1));\n\t\t\t\tconst desiredQuat = _quat.setFromEuler(\n\t\t\t\t\t_euler.set(desiredPitch, desiredYaw, 0, 'YXZ'),\n\t\t\t\t);\n\n\t\t\t\tconst t = 1 - Math.pow(1 - Math.min(this._lookAtLerpSpeed * dt, 1), 1);\n\t\t\t\tthis._currentRotation.slerp(desiredQuat, MathUtils.clamp(t, 0, 1));\n\t\t\t\treturn this._currentRotation.clone();\n\t\t\t}\n\t\t}\n\n\t\tthis._currentRotation.copy(yawPitchQuat);\n\t\treturn yawPitchQuat;\n\t}\n\n\tprivate lerpFov(dt: number): number {\n\t\tif (Math.abs(this._currentFov - this._targetFov) < 0.01) {\n\t\t\treturn this._targetFov;\n\t\t}\n\t\tconst t = 1 - Math.pow(1 - Math.min(this.opts.fovLerpSpeed * dt, 1), 1);\n\t\treturn MathUtils.lerp(this._currentFov, this._targetFov, MathUtils.clamp(t, 0, 1));\n\t}\n\n\tprivate deriveYawPitchFromLookAt(from: Vector3, to: Vector3): void {\n\t\tconst dir = _vec3.copy(to).sub(from).normalize();\n\t\tthis._yaw = Math.atan2(-dir.x, -dir.z);\n\t\tthis._pitch = Math.asin(MathUtils.clamp(dir.y, -1, 1));\n\t}\n\n\tprivate deriveYawPitchFromQuaternion(q: Quaternion): void {\n\t\tconst euler = _euler.setFromQuaternion(q, 'YXZ');\n\t\tthis._yaw = euler.y;\n\t\tthis._pitch = MathUtils.clamp(euler.x, -this.opts.pitchLimit, this.opts.pitchLimit);\n\t}\n}\n\n// Reusable temporaries (avoid per-frame allocations)\nconst _vec3 = new Vector3();\nconst _quat = new Quaternion();\nconst _euler = new Euler();\n","import type { PerspectiveType } from '../perspective';\nimport type { CameraPerspective } from '../types';\nimport { ThirdPersonPerspective } from './third-person-perspective';\nimport type { ThirdPersonOptions } from './third-person-perspective';\nimport { Fixed2DPerspective } from './fixed-2d-perspective';\nimport type { Fixed2DOptions } from './fixed-2d-perspective';\nimport { FirstPersonPerspective } from './first-person-perspective';\nimport type { FirstPersonOptions } from './first-person-perspective';\n\nexport { ThirdPersonPerspective } from './third-person-perspective';\nexport type { ThirdPersonOptions } from './third-person-perspective';\nexport { Fixed2DPerspective } from './fixed-2d-perspective';\nexport type { Fixed2DOptions } from './fixed-2d-perspective';\nexport { FirstPersonPerspective } from './first-person-perspective';\nexport type { FirstPersonOptions } from './first-person-perspective';\n\n/**\n * Perspective-specific options union.\n * Extend as new perspective types are added.\n */\nexport type PerspectiveOptions = ThirdPersonOptions | Fixed2DOptions | FirstPersonOptions;\n\n/**\n * Factory: create a CameraPerspective from a PerspectiveType string.\n * Unrecognized types default to ThirdPersonPerspective.\n */\nexport function createPerspective(\n\ttype: PerspectiveType,\n\toptions?: PerspectiveOptions\n): CameraPerspective {\n\tswitch (type) {\n\t\tcase 'third-person':\n\t\t\treturn new ThirdPersonPerspective(options as ThirdPersonOptions);\n\t\tcase 'first-person':\n\t\t\treturn new FirstPersonPerspective(options as FirstPersonOptions);\n\t\tcase 'isometric':\n\t\t\t// Isometric placeholder -- fixed angle third-person\n\t\t\treturn new ThirdPersonPerspective({\n\t\t\t\tdistance: 10,\n\t\t\t\theight: 10,\n\t\t\t\t...(options as ThirdPersonOptions),\n\t\t\t});\n\t\tcase 'flat-2d':\n\t\t\treturn new Fixed2DPerspective(options as Fixed2DOptions);\n\t\tcase 'fixed-2d':\n\t\t\treturn new Fixed2DPerspective(options as Fixed2DOptions);\n\t\tdefault:\n\t\t\treturn new ThirdPersonPerspective(options as ThirdPersonOptions);\n\t}\n}\n","import { Vector2, Scene } from 'three';\nimport { ZylemCamera } from './zylem-camera';\nimport { RendererManager } from './renderer-manager';\nimport { Perspectives } from './perspective';\nimport { nanoid } from 'nanoid';\n\n/**\n * CameraManager orchestrates multiple cameras per stage.\n *\n * Responsibilities:\n * - Named camera registry (add/remove/get by name or reference)\n * - Active camera list management (determines which cameras render)\n * - Always-available debug camera with orbit controls\n * - Per-frame update of all active cameras' perspective controllers\n * - Coordinating rendering via RendererManager for all active viewports\n */\nexport class CameraManager {\n\t/** Named camera registry */\n\tprivate cameras: Map<string, ZylemCamera> = new Map();\n\n\t/** Currently active cameras, ordered by render layer (first = bottom) */\n\tprivate _activeCameras: ZylemCamera[] = [];\n\n\t/** Auto-created debug camera with orbit controls */\n\tprivate _debugCamera: ZylemCamera | null = null;\n\n\t/** Reference to the shared renderer manager */\n\tprivate _rendererManager: RendererManager | null = null;\n\n\t/** Scene reference */\n\tprivate _sceneRef: Scene | null = null;\n\n\t/** Counter for auto-generated camera names */\n\tprivate _autoNameCounter = 0;\n\n\tconstructor() {\n\t\t// Debug camera is created lazily during setup when we have screen resolution\n\t}\n\n\t/**\n\t * Get the list of currently active cameras.\n\t */\n\tget activeCameras(): ReadonlyArray<ZylemCamera> {\n\t\treturn this._activeCameras;\n\t}\n\n\t/**\n\t * Get the primary active camera (first in the active list).\n\t */\n\tget primaryCamera(): ZylemCamera | null {\n\t\treturn this._activeCameras.length > 0 ? this._activeCameras[0] : null;\n\t}\n\n\t/**\n\t * Get the debug camera.\n\t */\n\tget debugCamera(): ZylemCamera | null {\n\t\treturn this._debugCamera;\n\t}\n\n\t/**\n\t * Get all registered cameras.\n\t */\n\tget allCameras(): ReadonlyArray<ZylemCamera> {\n\t\treturn Array.from(this.cameras.values());\n\t}\n\n\t/**\n\t * Add a camera to the manager.\n\t * If no name is provided, one is auto-generated.\n\t * The first camera added becomes the active camera.\n\t *\n\t * @param camera The ZylemCamera instance to add\n\t * @param name Optional name for lookup\n\t * @returns The assigned name\n\t */\n\taddCamera(camera: ZylemCamera, name?: string): string {\n\t\tconst resolvedName = name || camera.name || `camera_${this._autoNameCounter++}`;\n\t\tcamera.name = resolvedName;\n\t\tthis.cameras.set(resolvedName, camera);\n\n\t\t// First camera added automatically becomes active\n\t\tif (this._activeCameras.length === 0) {\n\t\t\tthis._activeCameras.push(camera);\n\t\t}\n\n\t\treturn resolvedName;\n\t}\n\n\t/**\n\t * Remove a camera by name or reference.\n\t * Cannot remove the debug camera via this method.\n\t */\n\tremoveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tlet name: string | undefined;\n\n\t\tif (typeof nameOrRef === 'string') {\n\t\t\tname = nameOrRef;\n\t\t} else {\n\t\t\t// Find by reference\n\t\t\tfor (const [key, cam] of this.cameras.entries()) {\n\t\t\t\tif (cam === nameOrRef) {\n\t\t\t\t\tname = key;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (!name) return false;\n\n\t\tconst camera = this.cameras.get(name);\n\t\tif (!camera) return false;\n\n\t\t// Prevent removing the debug camera\n\t\tif (camera === this._debugCamera) {\n\t\t\tconsole.warn('CameraManager: Cannot remove the debug camera');\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.cameras.delete(name);\n\n\t\t// Remove from active cameras\n\t\tconst activeIndex = this._activeCameras.indexOf(camera);\n\t\tif (activeIndex !== -1) {\n\t\t\tthis._activeCameras.splice(activeIndex, 1);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Set a camera as the primary active camera (replaces all active cameras\n\t * except additional viewport cameras).\n\t *\n\t * @param nameOrRef Camera name or reference to activate\n\t */\n\tsetActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) {\n\t\t\tconsole.warn(`CameraManager: Camera not found: ${nameOrRef}`);\n\t\t\treturn false;\n\t\t}\n\n\t\t// Set as the sole active camera (keeping PiP cameras if any)\n\t\tconst pipCameras = this._activeCameras.filter(c => {\n\t\t\treturn c !== this._activeCameras[0] && c.viewport.width < 1;\n\t\t});\n\n\t\tthis._activeCameras = [camera, ...pipCameras];\n\t\treturn true;\n\t}\n\n\t/**\n\t * Add a camera as an additional active camera (for split-screen or PiP).\n\t */\n\taddActiveCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) return false;\n\n\t\tif (!this._activeCameras.includes(camera)) {\n\t\t\tthis._activeCameras.push(camera);\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Remove a camera from the active render list (does not remove from registry).\n\t */\n\tdeactivateCamera(nameOrRef: string | ZylemCamera): boolean {\n\t\tconst camera = this.resolveCamera(nameOrRef);\n\t\tif (!camera) return false;\n\n\t\tconst index = this._activeCameras.indexOf(camera);\n\t\tif (index !== -1) {\n\t\t\tthis._activeCameras.splice(index, 1);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get a camera by name.\n\t */\n\tgetCamera(name: string): ZylemCamera | null {\n\t\treturn this.cameras.get(name) ?? null;\n\t}\n\n\t/**\n\t * Setup all cameras with the given scene and renderer manager.\n\t * Also creates the debug camera.\n\t */\n\tasync setup(scene: Scene, rendererManager: RendererManager): Promise<void> {\n\t\tthis._sceneRef = scene;\n\t\tthis._rendererManager = rendererManager;\n\n\t\t// Create the debug camera\n\t\tthis.createDebugCamera(rendererManager.screenResolution);\n\n\t\t// Setup all registered cameras\n\t\tfor (const camera of this.cameras.values()) {\n\t\t\tcamera.setRendererManager(rendererManager);\n\t\t\tawait camera.setup(scene, rendererManager);\n\t\t}\n\n\t\t// Setup the debug camera\n\t\tif (this._debugCamera) {\n\t\t\tthis._debugCamera.setRendererManager(rendererManager);\n\t\t\tawait this._debugCamera.setup(scene, rendererManager);\n\t\t}\n\t}\n\n\t/**\n\t * Update all active cameras' controllers.\n\t */\n\tupdate(delta: number): void {\n\t\tfor (const camera of this._activeCameras) {\n\t\t\tcamera.update(delta);\n\t\t}\n\t}\n\n\t/**\n\t * Render all active cameras through the renderer manager.\n\t * RTT cameras (those with a renderTarget) are rendered first to their\n\t * offscreen textures, then viewport cameras are rendered to the screen.\n\t */\n\trender(scene: Scene): void {\n\t\tif (!this._rendererManager || this._activeCameras.length === 0) return;\n\n\t\tconst rttCameras: ZylemCamera[] = [];\n\t\tconst viewportCameras: ZylemCamera[] = [];\n\n\t\tfor (const cam of this._activeCameras) {\n\t\t\tif (cam.renderTarget) {\n\t\t\t\trttCameras.push(cam);\n\t\t\t} else {\n\t\t\t\tviewportCameras.push(cam);\n\t\t\t}\n\t\t}\n\n\t\t// RTT pass first so textures are ready for the viewport pass\n\t\tfor (const cam of rttCameras) {\n\t\t\tthis._rendererManager.renderCameraToTarget(scene, cam);\n\t\t}\n\n\t\t// Viewport pass renders to the screen canvas\n\t\tif (viewportCameras.length > 0) {\n\t\t\tthis._rendererManager.renderCameras(scene, viewportCameras);\n\t\t}\n\t}\n\n\t/**\n\t * Create a default third-person camera if no cameras have been added.\n\t */\n\tensureDefaultCamera(): ZylemCamera {\n\t\tif (this.cameras.size === 0 || this._activeCameras.length === 0) {\n\t\t\tconst screenRes = this._rendererManager?.screenResolution\n\t\t\t\t|| new Vector2(window.innerWidth, window.innerHeight);\n\t\t\tconst defaultCam = new ZylemCamera(Perspectives.ThirdPerson, screenRes);\n\t\t\tthis.addCamera(defaultCam, 'default');\n\t\t\treturn defaultCam;\n\t\t}\n\t\treturn this._activeCameras[0];\n\t}\n\n\t/**\n\t * Dispose all cameras and cleanup.\n\t */\n\tdispose(): void {\n\t\tfor (const camera of this.cameras.values()) {\n\t\t\tcamera.destroy();\n\t\t}\n\t\tthis._debugCamera?.destroy();\n\t\tthis.cameras.clear();\n\t\tthis._activeCameras = [];\n\t\tthis._debugCamera = null;\n\t\tthis._rendererManager = null;\n\t\tthis._sceneRef = null;\n\t}\n\n\t/**\n\t * Create the always-available debug camera with orbit controls.\n\t */\n\tprivate createDebugCamera(screenResolution: Vector2): void {\n\t\tthis._debugCamera = new ZylemCamera(Perspectives.ThirdPerson, screenResolution);\n\t\tthis._debugCamera.name = '__debug__';\n\t\tthis._debugCamera.enableOrbitalControls();\n\t\t// Debug camera is NOT added to the active cameras by default;\n\t\t// it's activated via the debug system\n\t}\n\n\t/**\n\t * Resolve a camera from a name or reference.\n\t */\n\tprivate resolveCamera(nameOrRef: string | ZylemCamera): ZylemCamera | null {\n\t\tif (typeof nameOrRef === 'string') {\n\t\t\treturn this.cameras.get(nameOrRef) ?? null;\n\t\t}\n\t\t// Check if the reference exists in our registry\n\t\tfor (const cam of this.cameras.values()) {\n\t\t\tif (cam === nameOrRef) return cam;\n\t\t}\n\t\treturn null;\n\t}\n}\n"],"mappings":"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","names":["Vector2","Vector3","PerspectiveCamera","Vector3","WebGLRenderTarget","WebGLRenderer","WebGLRenderer","Vector3","Quaternion","Vector3","Quaternion","Vector3","Quaternion","DEFAULTS","Vector3","Quaternion","MathUtils","DEFAULTS","Vector3","PerspectiveCamera","WebGLRenderTarget","Vector2","Vector3","Vector2","Vector2"]}
@@ -1,4 +1,4 @@
1
- import { A as Action, I as GameEntity } from './entity-BpbZqg19.js';
1
+ import { A as Action, I as GameEntity } from './entity-vj-HTjzU.js';
2
2
 
3
3
  interface MoveByOptions {
4
4
  /** X displacement (default: 0) */