@zylem/game-lib 0.9.5 → 0.9.7

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 (134) hide show
  1. package/dist/actions.d.ts +3 -3
  2. package/dist/api/game-lib.api.json +100288 -42733
  3. package/dist/api/game-lib.api.md +3842 -685
  4. package/dist/api/game-lib.d.ts +8934 -818
  5. package/dist/api/game-lib.typedoc.json +327569 -192737
  6. package/dist/behavior/action/fighting.d.ts +1 -0
  7. package/dist/behavior/action/fighting.js +1 -0
  8. package/dist/behavior/action/pinball.d.ts +1 -0
  9. package/dist/behavior/action/pinball.js +1 -0
  10. package/dist/behavior/action/platform.d.ts +1 -0
  11. package/dist/behavior/action/platform.js +1 -0
  12. package/dist/behavior/action/rhythm.d.ts +1 -0
  13. package/dist/behavior/action/rhythm.js +1 -0
  14. package/dist/behavior/action/shooter/first-person.d.ts +1 -0
  15. package/dist/behavior/action/shooter/first-person.js +1 -0
  16. package/dist/behavior/action/shooter/shoot-em-up.d.ts +1 -0
  17. package/dist/behavior/action/shooter/shoot-em-up.js +1 -0
  18. package/dist/behavior/action/shooter.d.ts +1 -0
  19. package/dist/behavior/action/shooter.js +1 -0
  20. package/dist/behavior/action/stealth.d.ts +1 -0
  21. package/dist/behavior/action/stealth.js +1 -0
  22. package/dist/behavior/action/survival.d.ts +1 -0
  23. package/dist/behavior/action/survival.js +1 -0
  24. package/dist/behavior/action-adventure.d.ts +1 -0
  25. package/dist/behavior/action-adventure.js +1 -0
  26. package/dist/behavior/action.d.ts +1 -0
  27. package/dist/behavior/action.js +1 -0
  28. package/dist/behavior/genre-map.d.ts +1 -0
  29. package/dist/behavior/genre-map.js +1 -0
  30. package/dist/behavior/mechanics.d.ts +1 -0
  31. package/dist/behavior/mechanics.js +1 -0
  32. package/dist/behavior/puzzle/physics.d.ts +1 -0
  33. package/dist/behavior/puzzle/physics.js +1 -0
  34. package/dist/behavior/puzzle/tile-matching.d.ts +1 -0
  35. package/dist/behavior/puzzle/tile-matching.js +1 -0
  36. package/dist/behavior/puzzle.d.ts +1 -0
  37. package/dist/behavior/puzzle.js +1 -0
  38. package/dist/behavior/role-playing/action-rpg.d.ts +1 -0
  39. package/dist/behavior/role-playing/action-rpg.js +1 -0
  40. package/dist/behavior/role-playing/monster-taming.d.ts +1 -0
  41. package/dist/behavior/role-playing/monster-taming.js +1 -0
  42. package/dist/behavior/role-playing/tactical-rpg.d.ts +1 -0
  43. package/dist/behavior/role-playing/tactical-rpg.js +1 -0
  44. package/dist/behavior/role-playing/turn-based.d.ts +1 -0
  45. package/dist/behavior/role-playing/turn-based.js +1 -0
  46. package/dist/behavior/role-playing.d.ts +1 -0
  47. package/dist/behavior/role-playing.js +1 -0
  48. package/dist/behavior/simulation/life.d.ts +1 -0
  49. package/dist/behavior/simulation/life.js +1 -0
  50. package/dist/behavior/simulation/vehicle/racing.d.ts +1 -0
  51. package/dist/behavior/simulation/vehicle/racing.js +1 -0
  52. package/dist/behavior/simulation/vehicle.d.ts +1 -0
  53. package/dist/behavior/simulation/vehicle.js +1 -0
  54. package/dist/behavior/simulation.d.ts +1 -0
  55. package/dist/behavior/simulation.js +1 -0
  56. package/dist/behavior/sports/golf.d.ts +1 -0
  57. package/dist/behavior/sports/golf.js +1 -0
  58. package/dist/behavior/sports/racing.d.ts +1 -0
  59. package/dist/behavior/sports/racing.js +1 -0
  60. package/dist/behavior/sports/racket.d.ts +1 -0
  61. package/dist/behavior/sports/racket.js +1 -0
  62. package/dist/behavior/sports/skate.d.ts +1 -0
  63. package/dist/behavior/sports/skate.js +1 -0
  64. package/dist/behavior/sports.d.ts +1 -0
  65. package/dist/behavior/sports.js +1 -0
  66. package/dist/behavior/strategy/real-time-tactics.d.ts +1 -0
  67. package/dist/behavior/strategy/real-time-tactics.js +1 -0
  68. package/dist/behavior/strategy/tower-defense.d.ts +1 -0
  69. package/dist/behavior/strategy/tower-defense.js +1 -0
  70. package/dist/behavior/strategy/turn-based-tactics.d.ts +1 -0
  71. package/dist/behavior/strategy/turn-based-tactics.js +1 -0
  72. package/dist/behavior/strategy.d.ts +1 -0
  73. package/dist/behavior/strategy.js +1 -0
  74. package/dist/behavior.d.ts +34 -0
  75. package/dist/bridge.d.ts +9 -2
  76. package/dist/bridge.js +1 -1
  77. package/dist/catalog.d.ts +1 -1
  78. package/dist/catalog.js +1 -1
  79. package/dist/{chunk-BQRMYLYD.js → chunk-273CUPEO.js} +1 -1
  80. package/dist/chunk-4DAITCJS.js +1 -0
  81. package/dist/chunk-63T3K5EQ.js +1 -0
  82. package/dist/chunk-AJSIVGDX.js +1 -0
  83. package/dist/chunk-CVKEWWIH.js +1 -0
  84. package/dist/chunk-DYD7MDWO.js +1 -0
  85. package/dist/chunk-IHGRFR4H.js +1 -0
  86. package/dist/{chunk-4CZZZCFB.js → chunk-JCGW5PIR.js} +1 -1
  87. package/dist/{chunk-2IJLXFWY.js → chunk-JJEYLGD2.js} +4 -4
  88. package/dist/chunk-KL7NGD76.js +1 -0
  89. package/dist/chunk-M2FZ224T.js +1 -0
  90. package/dist/chunk-MJ7RGE47.js +1 -0
  91. package/dist/chunk-Q22Z4PBD.js +19 -0
  92. package/dist/chunk-SD7EHS4W.js +1 -0
  93. package/dist/chunk-UKNMIHAP.js +1 -0
  94. package/dist/chunk-UM5VNQPY.js +1 -0
  95. package/dist/chunk-Y5IU6IA5.js +1 -0
  96. package/dist/cinematics.d.ts +8 -5
  97. package/dist/core.d.ts +25 -10
  98. package/dist/core.js +1 -1
  99. package/dist/{debug-state-Cg3f5FB6.d.ts → debug-state-BgX5Q0Ff.d.ts} +2 -2
  100. package/dist/debug.d.ts +6 -125
  101. package/dist/debug.js +1 -1
  102. package/dist/{entity-XqvuWgPm.d.ts → entity-CY75JJSw.d.ts} +83 -4
  103. package/dist/{entity-type-map-CrsrKT8c.d.ts → entity-type-map-BMaPY8cd.d.ts} +53 -14
  104. package/dist/entity.d.ts +6 -18
  105. package/dist/entity.js +1 -1
  106. package/dist/{game-DBt7iVu4.d.ts → game-CmkhPP-9.d.ts} +8 -8
  107. package/dist/game-default-LAGMEHNQ.js +1 -0
  108. package/dist/graphics.d.ts +3 -3
  109. package/dist/graphics.js +1 -1
  110. package/dist/level-types-D10LiOcn.d.ts +91 -0
  111. package/dist/{material-CxxAyJYp.d.ts → material-D1IVeQc5.d.ts} +48 -2
  112. package/dist/placement-session-BNQoL7Jb.d.ts +82 -0
  113. package/dist/placement.d.ts +52 -0
  114. package/dist/placement.js +1 -0
  115. package/dist/public.d.ts +14 -10
  116. package/dist/public.js +1 -1
  117. package/dist/{stage-PBmwT5-Y.d.ts → stage-CCGJh9TD.d.ts} +189 -7
  118. package/dist/transform-gizmo-DappLQ9w.d.ts +123 -0
  119. package/dist/web-components.d.ts +10 -7
  120. package/dist/web-components.js +1 -1
  121. package/dist/{zylem-camera-CWhIGXlW.d.ts → zylem-camera-BA3VPFlS.d.ts} +9 -0
  122. package/package.json +147 -7
  123. package/dist/chunk-3CLQWJ2I.js +0 -1
  124. package/dist/chunk-6FGXC4T6.js +0 -19
  125. package/dist/chunk-GPCSX3M6.js +0 -1
  126. package/dist/chunk-K3NNXZIJ.js +0 -1
  127. package/dist/chunk-KP6DLLJO.js +0 -1
  128. package/dist/chunk-LI43BZQN.js +0 -1
  129. package/dist/chunk-NK4IXK5V.js +0 -1
  130. package/dist/chunk-QB3NL7VQ.js +0 -1
  131. package/dist/chunk-STVEILJJ.js +0 -1
  132. package/dist/chunk-VSFULLND.js +0 -1
  133. package/dist/chunk-YQS7CGXE.js +0 -1
  134. package/dist/game-default-BAZPDNPS.js +0 -1
@@ -1,17 +1,20 @@
1
1
  import { B as BaseNode } from './base-node-idopiSw5.js';
2
2
  import { h as SetupFunction, g as UpdateFunction, j as DestroyFunction, a as SetupContext, U as UpdateContext, D as DestroyContext, L as LoadingEvent } from './base-node-life-cycle-BK9xebT9.js';
3
- import { Scene, Color, Object3D, Vector3, BufferGeometry, Material, Group, Texture } from 'three';
4
- import { al as ZylemWorld, aj as EntityTypeMap } from './entity-type-map-CrsrKT8c.js';
3
+ import { Box3, Scene, Color, Object3D, Vector3, BufferGeometry, Material, Group, Texture, Camera } from 'three';
4
+ import { an as ZylemWorld, al as EntityTypeMap } from './entity-type-map-BMaPY8cd.js';
5
5
  import { E as Entity, L as LifecycleFunction, S as StageEntity } from './entity-BIf_a4dl.js';
6
- import { G as GameEntity, a as GameEntityOptions } from './entity-XqvuWgPm.js';
7
- import { l as ZylemCamera, R as RendererManager, e as CameraPerspective, d as CameraContext, C as CameraPose, P as PerspectiveType, f as CameraBehavior, g as CameraAction, h as CameraPipelineState, V as Viewport, Z as ZylemPostEffect } from './zylem-camera-CWhIGXlW.js';
8
- import { d as ZylemShader } from './material-CxxAyJYp.js';
6
+ import { G as GameEntity, d as GameEntityOptions, b as PointerTargetEntity } from './entity-CY75JJSw.js';
7
+ import { l as ZylemCamera, R as RendererManager, e as CameraPerspective, d as CameraContext, C as CameraPose, P as PerspectiveType, f as CameraBehavior, g as CameraAction, h as CameraPipelineState, V as Viewport, Z as ZylemPostEffect } from './zylem-camera-BA3VPFlS.js';
8
+ import { f as ZylemShader } from './material-D1IVeQc5.js';
9
9
  import { a as SimulationBody } from './simulation-body-zQw-emOr.js';
10
10
  import { e as Vec3Input, b as Vec2Input, d as Vec3Components } from './vector-D3eDzvcA.js';
11
11
  import { StageEvents } from './events.js';
12
12
  import { G as GameInputConfig } from './game-interfaces-vF5sRi1n.js';
13
+ import { A as ArmPlacementOptions, P as PlacementSession } from './placement-session-BNQoL7Jb.js';
13
14
  import { SwatchApplyResult, SceneOperationEntry, EntityApplySwatchPayload, SceneOperationPayload } from '@zylem/bridge';
15
+ import { a as LevelSyncPayload, L as LevelDocument } from './level-types-D10LiOcn.js';
14
16
  import { BehaviorSystem, BehaviorEntityLink, BehaviorRuntime, BehaviorSystemFactory, BehaviorRef } from '@zylem/behaviors/core';
17
+ import { d as GizmoRay } from './transform-gizmo-DappLQ9w.js';
15
18
 
16
19
  /**
17
20
  * Editor-view cameras exist only while an editor is attached.
@@ -24,6 +27,8 @@ interface EditorCameraHost {
24
27
  ensureEditorCameras(): Promise<void>;
25
28
  destroyEditorCameras(): void;
26
29
  activateCameraById(id: string): boolean;
30
+ /** Copy the gameplay camera onto the free view, then show it. */
31
+ syncFreeCameraToGame(): void;
27
32
  }
28
33
 
29
34
  /**
@@ -47,6 +52,10 @@ declare class CameraManager implements EditorCameraHost {
47
52
  private _lockedEditorIds;
48
53
  /** Which editor views pan in screen space (the view plane). */
49
54
  private _screenSpacePanIds;
55
+ /** Side, top, and isometric views that have already been placed on the gameplay camera. */
56
+ private _framedEditorViews;
57
+ /** World boxes of stage entities, read when an orthographic view is first shown. */
58
+ private _entityBounds;
50
59
  /** Game camera to restore when the editor releases the main view. */
51
60
  private _rememberedGameCamera;
52
61
  /**
@@ -76,8 +85,20 @@ declare class CameraManager implements EditorCameraHost {
76
85
  get primaryCamera(): ZylemCamera | null;
77
86
  /** True while side, top, isometric, or free is the main view. */
78
87
  isEditorViewActive(): boolean;
88
+ /** Id of the editor view that is currently the main camera, if one is. */
89
+ activeEditorCameraId(): string | null;
79
90
  /** True after the four editor views have been created. */
80
91
  hasEditorCameras(): boolean;
92
+ /**
93
+ * World boxes used the first time side, top, or isometric is shown.
94
+ * Pass null to stop contributing boxes.
95
+ */
96
+ setEditorEntityBounds(read: (() => readonly Box3[]) | null): void;
97
+ /**
98
+ * Copy the gameplay camera onto the free view, then show that view.
99
+ * Waits for the editor cameras when they have not been created yet.
100
+ */
101
+ syncFreeCameraToGame(): void;
81
102
  /**
82
103
  * Get all registered cameras.
83
104
  */
@@ -165,6 +186,15 @@ declare class CameraManager implements EditorCameraHost {
165
186
  private showGameCamera;
166
187
  /** Enable orbit on the active editor view only. Inactive views keep their pose. */
167
188
  private syncEditorOrbit;
189
+ private isOrthographicEditorView;
190
+ /** Snapshot the gameplay camera onto the free orbit camera. Does not switch views. */
191
+ private copyFreeFromGame;
192
+ private copyGameplayProjection;
193
+ /**
194
+ * Place an orthographic view on the gameplay camera's look-at and fit the
195
+ * stage around that point. Returns false when there is no gameplay camera.
196
+ */
197
+ private frameOrthographicView;
168
198
  /** Stop game-camera orbit controls from sharing the canvas with an editor view. */
169
199
  private suspendOtherOrbits;
170
200
  private restoreOrbitFor;
@@ -914,8 +944,9 @@ interface SwatchApplyOutcome {
914
944
  * `PlacementGhost` — is live whenever a tool is armed, so the toolbar's buttons
915
945
  * work on their own. The debug layer — the wasm simulation's collider
916
946
  * wireframes — is the part `debugState.enabled` gates, and is torn down when
917
- * it goes off while the delegate stays alive to re-activate. Debug mode does
918
- * not switch cameras; picking and gizmos use whichever camera is rendering.
947
+ * it goes off while the delegate stays alive to re-activate. This delegate
948
+ * does not switch cameras; the bridge shows the free camera when debug is
949
+ * enabled. Picking and gizmos use whichever camera is rendering.
919
950
  *
920
951
  * Centralizes all of this so `ZylemStage` doesn't have to know about
921
952
  * raycasting, DOM input, or debug rendering.
@@ -958,6 +989,9 @@ declare class StageDebugDelegate {
958
989
  private selectionBoundsPool;
959
990
  private hoverBounds;
960
991
  private grid;
992
+ private levelSession;
993
+ /** The press belongs to the level session, through pointerup. */
994
+ private levelPointer;
961
995
  private lastTool;
962
996
  /** Element the current gizmo drag captured, so pointerup is never missed. */
963
997
  private capturedPointer;
@@ -967,6 +1001,13 @@ declare class StageDebugDelegate {
967
1001
  * point. Without one the tool warns instead of silently doing nothing.
968
1002
  */
969
1003
  setAddEntityFactory(factory: AddEntityFactory | null): void;
1004
+ /** Show the level document as an edit preview. Brush faces, no collision. */
1005
+ syncLevel(payload: LevelSyncPayload): void;
1006
+ /** Respawn the document for play: hull collision, hidden brush faces, live zones. */
1007
+ playLevel(document: LevelDocument): void;
1008
+ /** Remove the preview and any play collision. Stage entities stay. */
1009
+ closeLevel(): void;
1010
+ private levelSessionHost;
970
1011
  /** Camera used for raycasts and gizmos: whichever one is rendering. */
971
1012
  private getDebugViewCamera;
972
1013
  private resolveEntity;
@@ -1072,6 +1113,8 @@ declare class StageDebugDelegate {
1072
1113
  * physics raycast here and cannot preview itself.
1073
1114
  */
1074
1115
  private updatePlacementGhost;
1116
+ /** Selection boxes for the first side, top, and isometric placement. Level brushes are not included. */
1117
+ private editorEntityBoxes;
1075
1118
  /** Full teardown — unsubscribes from debugState and cleans up all resources. */
1076
1119
  dispose(): void;
1077
1120
  /**
@@ -1477,6 +1520,113 @@ declare class StageEntityDelegate {
1477
1520
  private unregisterBehaviorLinks;
1478
1521
  }
1479
1522
 
1523
+ /**
1524
+ * Geometry for the add tool's placement click.
1525
+ *
1526
+ * Split out from `StageDebugDelegate` because it is pure: rays and bounds in,
1527
+ * a position out, with no scene, world, or entity state involved. Placement is
1528
+ * also the part most worth pinning down — the fallback plane and the surface
1529
+ * offset are what make a click into empty space land somewhere sensible.
1530
+ */
1531
+
1532
+ /** A ray/collider intersection, as reported by the physics world. */
1533
+ interface PlacementHit {
1534
+ distance: number;
1535
+ normal: [number, number, number];
1536
+ }
1537
+
1538
+ /**
1539
+ * Play-mode pointer: hover areas, droppable areas, and click-to-place.
1540
+ *
1541
+ * The editor's Add tool owns the canvas while `isEditorInteractionActive()`
1542
+ * is true. This delegate stays out of that — an armed session is hidden and
1543
+ * not cancelled, and its listeners come off so the gizmo and the add ghost
1544
+ * keep the pointer. Left click is swallowed only when a placement commits or
1545
+ * a hover area handles the click, so an empty press still reaches the camera.
1546
+ */
1547
+
1548
+ interface StagePointerHost {
1549
+ getScene(): Scene | null;
1550
+ raycast(origin: Vector3, direction: Vector3, maxDistance: number): PlacementHit | null;
1551
+ addSpawn(entity: unknown): void;
1552
+ getCanvas(): HTMLElement | null;
1553
+ getCamera(): Camera | null;
1554
+ /** The durable stage should drop its saved session. Not called while repeating. */
1555
+ onSessionEnded?: () => void;
1556
+ }
1557
+ declare class StagePointerDelegate {
1558
+ private readonly host;
1559
+ private readonly unsubscribe;
1560
+ private readonly known;
1561
+ private readonly targets;
1562
+ private readonly bounds;
1563
+ private readonly raycaster;
1564
+ private readonly mouseNdc;
1565
+ private session;
1566
+ private view;
1567
+ private closing;
1568
+ private disposed;
1569
+ private hovered;
1570
+ private hoveredId;
1571
+ private lastAim;
1572
+ /** Test and host injection. When set, the camera ray is not used. */
1573
+ private rayOverride;
1574
+ private canvas;
1575
+ private listening;
1576
+ private keys;
1577
+ constructor(host: StagePointerHost);
1578
+ /** True while a click would still try to place. False during the fade-out. */
1579
+ get isPlacing(): boolean;
1580
+ get previewOpacity(): number;
1581
+ get previewPosition(): Vector3 | null;
1582
+ /**
1583
+ * Use this ray instead of the camera. Tests inject one; a live stage leaves
1584
+ * it null and rebuilds the ray from the canvas every frame so a moving
1585
+ * camera does not leave the preview behind.
1586
+ */
1587
+ setRay(ray: GizmoRay | null): void;
1588
+ /** Register a target that is not going through the stage entity list. */
1589
+ registerTarget(entity: PointerTargetEntity): void;
1590
+ unregisterTarget(uuid: string): void;
1591
+ arm(options: ArmPlacementOptions): void;
1592
+ setPayload(payload: unknown): void;
1593
+ setRepresentative(representative: ArmPlacementOptions['representative']): void;
1594
+ cancel(): void;
1595
+ update(delta: number): void;
1596
+ /**
1597
+ * @returns whether the press was handled. Unhandled presses are left for
1598
+ * the camera.
1599
+ */
1600
+ pointerDown(button: number): boolean;
1601
+ dispose(): void;
1602
+ private suspended;
1603
+ private mountView;
1604
+ private syncTarget;
1605
+ private resolveAim;
1606
+ private nearestArea;
1607
+ private hasDroppable;
1608
+ private surfacePoint;
1609
+ private present;
1610
+ private applyHover;
1611
+ private leaveHovered;
1612
+ private fire;
1613
+ private areaContext;
1614
+ private tryCommit;
1615
+ private pointContext;
1616
+ private notifyDrop;
1617
+ private finishCommit;
1618
+ private beginClose;
1619
+ private clickHovered;
1620
+ private currentRay;
1621
+ private syncListeners;
1622
+ private detachListeners;
1623
+ private detachPointer;
1624
+ private onPointerMove;
1625
+ private onPointerDown;
1626
+ private onKeyDown;
1627
+ private trackPointer;
1628
+ }
1629
+
1480
1630
  /**
1481
1631
  * The runtime heart of a loaded stage.
1482
1632
  *
@@ -1536,6 +1686,8 @@ declare class ZylemStage extends LifeCycleBase<ZylemStage> {
1536
1686
  scene: ZylemScene | null;
1537
1687
  renderStrategy: RenderStrategyManager | null;
1538
1688
  debugDelegate: StageDebugDelegate | null;
1689
+ /** Play-mode hover, drop, and click-to-place. Suspended while the editor tools are live. */
1690
+ readonly pointerDelegate: StagePointerDelegate;
1539
1691
  uuid: string;
1540
1692
  wrapperRef: Stage | null;
1541
1693
  camera?: CameraWrapper;
@@ -1646,6 +1798,9 @@ declare class Stage {
1646
1798
  private eventDelegate;
1647
1799
  /** Per-stage input configuration overrides. Merged with game-level defaults on stage load. */
1648
1800
  inputConfig: GameInputConfig | null;
1801
+ /** Placement armed before the runtime stage exists, applied on load. */
1802
+ private pendingPlacement;
1803
+ private placementGeneration;
1649
1804
  /**
1650
1805
  * Callback set by the game to trigger input reconfiguration
1651
1806
  * when this stage's input config changes at runtime.
@@ -1679,6 +1834,33 @@ declare class Stage {
1679
1834
  * @example stage.getEntityByName('scoreText', TEXT_TYPE)
1680
1835
  */
1681
1836
  getEntityByName<T extends symbol | void = void>(name: string, type?: T): T extends keyof EntityTypeMap ? EntityTypeMap[T] | undefined : BaseNode | undefined;
1837
+ /**
1838
+ * Follow the cursor with a representative and place an entity on left click.
1839
+ *
1840
+ * Click-to-place, not a drag. A hover area's `onClick` can call this to
1841
+ * pick something up. While the stage has any droppable, the click only
1842
+ * commits over one that accepts `payload`. Otherwise it lands on the
1843
+ * physics hit, or the ground plane. Right click, Escape, and
1844
+ * {@link cancelPlacement} fade the preview out.
1845
+ *
1846
+ * @example
1847
+ * stage.armPlacement({
1848
+ * payload: 'tower',
1849
+ * repeat: true,
1850
+ * representative: entityRepresentative(createBox, { opacity: 0.45 }),
1851
+ * spawnOnClick: ({ valid, position }) => valid ? createBox({ position }) : false,
1852
+ * });
1853
+ */
1854
+ armPlacement(options: ArmPlacementOptions): PlacementSession;
1855
+ /** Fade out the armed representative and ignore further placement clicks. */
1856
+ cancelPlacement(): this;
1857
+ /**
1858
+ * Drop the session the next load would re-arm.
1859
+ * The pointer delegate calls this after a cancel or a one-shot commit.
1860
+ * It does not touch the live preview — {@link cancelPlacement} does both.
1861
+ * @internal
1862
+ */
1863
+ abandonPlacement(): void;
1682
1864
  /**
1683
1865
  * Add a camera to this stage.
1684
1866
  * @param camera The ZylemCamera or CameraWrapper to add
@@ -0,0 +1,123 @@
1
+ import * as three from 'three';
2
+ import { Vector3, Group, Scene, Camera } from 'three';
3
+
4
+ type GizmoMode = 'translate' | 'rotate' | 'scale';
5
+ /** Single-axis, planar, and uniform handle identifiers. */
6
+ type GizmoAxis = 'x' | 'y' | 'z' | 'xy' | 'yz' | 'xz' | 'xyz';
7
+ /** A raw, unsnapped drag result in world space. */
8
+ type GizmoDelta = {
9
+ kind: 'translate';
10
+ offset: Vector3;
11
+ } | {
12
+ kind: 'rotate';
13
+ axis: Vector3;
14
+ angle: number;
15
+ } | {
16
+ kind: 'scale';
17
+ factor: Vector3;
18
+ };
19
+ /** A mouse ray in world space. */
20
+ interface GizmoRay {
21
+ origin: Vector3;
22
+ direction: Vector3;
23
+ }
24
+ /**
25
+ * Closest point along an infinite line to a ray, as a distance along the line.
26
+ *
27
+ * Returns `null` when the ray is close enough to parallel with the line that the
28
+ * closest point becomes unstable; see {@link MAX_DRAG_GAIN}.
29
+ */
30
+ declare function closestAxisValue(ray: GizmoRay, origin: Vector3, axis: Vector3): number | null;
31
+ /**
32
+ * Intersect a ray with the plane through `origin` with the given normal.
33
+ *
34
+ * Returns `null` for a plane seen too close to edge-on, where the hit point
35
+ * races away across the plane for very little pointer motion.
36
+ */
37
+ declare function intersectPlane(ray: GizmoRay, origin: Vector3, normal: Vector3, target: Vector3): Vector3 | null;
38
+ declare class TransformGizmo {
39
+ /** Root added to the scene; carries the pivot transform. */
40
+ readonly root: Group<three.Object3DEventMap>;
41
+ private scene;
42
+ private modeGroups;
43
+ private handles;
44
+ private materials;
45
+ private geometries;
46
+ private mode;
47
+ private highlighted;
48
+ private drag;
49
+ private raycaster;
50
+ constructor();
51
+ addTo(scene: Scene): void;
52
+ removeFromScene(): void;
53
+ dispose(): void;
54
+ setMode(mode: GizmoMode): void;
55
+ getMode(): GizmoMode;
56
+ /** Place the gizmo at a pivot and show it. */
57
+ show(pivot: Vector3): void;
58
+ hide(): void;
59
+ get visible(): boolean;
60
+ get pivot(): Vector3;
61
+ /**
62
+ * Keep the gizmo a constant size on screen.
63
+ *
64
+ * A world-sized gizmo is unusable in an orbit view: it fills the screen up
65
+ * close and disappears from a distance.
66
+ */
67
+ update(camera: Camera): void;
68
+ /**
69
+ * Which handle a ray hits, or `null`.
70
+ *
71
+ * Raycasts the gizmo's own meshes rather than the physics world. Handles are
72
+ * render-only objects with no colliders, so the physics raycast used to pick
73
+ * entities cannot see them at all.
74
+ */
75
+ pick(ray: GizmoRay): GizmoAxis | null;
76
+ /**
77
+ * Whether a handle can be dragged from the current viewing angle.
78
+ *
79
+ * Each handle type degenerates differently: an arrow aimed at the camera has
80
+ * no screen-space direction left to follow, while a plane quad or rotation
81
+ * ring seen edge-on turns a pixel of motion into a huge sweep across it.
82
+ */
83
+ private isHandleDraggable;
84
+ /** Tint a handle to show it is hovered or being dragged. */
85
+ setHighlight(axis: GizmoAxis | null): void;
86
+ /**
87
+ * Begin a drag on a handle.
88
+ *
89
+ * @returns `false` when the gesture cannot be tracked (a near-parallel view
90
+ * of the drag axis), so the caller can ignore the press rather than start a
91
+ * drag that would jump.
92
+ */
93
+ beginDrag(axis: GizmoAxis, ray: GizmoRay, camera: Camera): boolean;
94
+ /** Raw delta for the current pointer position, or `null` when unusable. */
95
+ updateDrag(ray: GizmoRay, camera: Camera): GizmoDelta | null;
96
+ endDrag(): void;
97
+ get isDragging(): boolean;
98
+ get draggingAxis(): GizmoAxis | null;
99
+ private isPlaneAxis;
100
+ /** Signed angle of the ray's hit point around `normal`, in radians. */
101
+ private angleOnPlane;
102
+ /** Distance from pivot to the ray hit on the camera-facing plane. */
103
+ private cameraPlaneRadius;
104
+ private applyModeVisibility;
105
+ private makeMaterial;
106
+ private track;
107
+ /**
108
+ * An invisible, generously sized mesh used only for hit testing.
109
+ *
110
+ * The visible shafts and rings are a couple of pixels wide, which is
111
+ * miserable to click. The raycaster still reaches `visible: false` meshes,
112
+ * so picking accuracy is decoupled from how thin the handle looks.
113
+ */
114
+ private makePicker;
115
+ private orientAlongAxis;
116
+ private buildTranslate;
117
+ private positionPlaneHandle;
118
+ private buildRotate;
119
+ private orientRing;
120
+ private buildScale;
121
+ }
122
+
123
+ export { type GizmoAxis as G, TransformGizmo as T, type GizmoDelta as a, type GizmoMode as b, closestAxisValue as c, type GizmoRay as d, intersectPlane as i };
@@ -1,17 +1,17 @@
1
- import { G as Game, D as DeviceProfile } from './game-DBt7iVu4.js';
2
- import { v as DebugTools } from './debug-state-Cg3f5FB6.js';
1
+ import { G as Game, D as DeviceProfile } from './game-CmkhPP-9.js';
2
+ import { v as DebugTools } from './debug-state-BgX5Q0Ff.js';
3
3
  import './base-node-life-cycle-BK9xebT9.js';
4
4
  import 'three';
5
5
  import './stage-transition-CmGpV4tc.js';
6
6
  import './game-interfaces-vF5sRi1n.js';
7
7
  import './base-node-idopiSw5.js';
8
- import './stage-PBmwT5-Y.js';
9
- import './entity-type-map-CrsrKT8c.js';
10
- import './entity-XqvuWgPm.js';
8
+ import './stage-CCGJh9TD.js';
9
+ import './entity-type-map-BMaPY8cd.js';
10
+ import './entity-CY75JJSw.js';
11
11
  import '@zylem/behaviors/core';
12
12
  import './simulation-body-zQw-emOr.js';
13
13
  import './vector-D3eDzvcA.js';
14
- import './material-CxxAyJYp.js';
14
+ import './material-D1IVeQc5.js';
15
15
  import 'three/webgpu';
16
16
  import './collision-builder-BckxkdmA.js';
17
17
  import './events.js';
@@ -20,8 +20,11 @@ import './selection-bounds-BKmSo9aG.js';
20
20
  import './entity-BIf_a4dl.js';
21
21
  import '@zylem/behaviors/particle-emitter';
22
22
  import 'three/addons/lines/webgpu/Line2.js';
23
- import './zylem-camera-CWhIGXlW.js';
23
+ import './zylem-camera-BA3VPFlS.js';
24
+ import './placement-session-BNQoL7Jb.js';
24
25
  import '@zylem/bridge';
26
+ import './level-types-D10LiOcn.js';
27
+ import './transform-gizmo-DappLQ9w.js';
25
28
  import './default-controls-CAKJ5zlo.js';
26
29
 
27
30
  /**
@@ -1 +1 @@
1
- import{a}from"./chunk-4CZZZCFB.js";import"./chunk-GPCSX3M6.js";import"./chunk-WOT6VMZA.js";export{a as ZylemGameElement};
1
+ import{a}from"./chunk-JCGW5PIR.js";import"./chunk-UM5VNQPY.js";import"./chunk-WOT6VMZA.js";export{a as ZylemGameElement};
@@ -514,6 +514,8 @@ declare class ZylemCamera {
514
514
  * to ignore pointer input while another camera is showing.
515
515
  */
516
516
  armEditorOrbit(lockRotation: boolean, screenSpacePan?: boolean): void;
517
+ /** Let this camera orbit below the horizon. Set before controls are created. */
518
+ allowFullOrbit(): void;
517
519
  /** Ignore pointer input without disposing orbit controls or their pose. */
518
520
  disarmEditorOrbit(): void;
519
521
  /**
@@ -566,6 +568,13 @@ declare class ZylemCamera {
566
568
  * Seed the debug orbit camera to an initial pose.
567
569
  */
568
570
  seedDebugOrbitPose(position: Vector3, lookAt: Vector3): void;
571
+ /** Write an orbit pose even when one was already seeded. */
572
+ replaceOrbitPose(position: Vector3, lookAt: Vector3): void;
573
+ /**
574
+ * Resize an orthographic editor view. `frustumSize` is the visible height;
575
+ * width follows the screen aspect, matching {@link resize}.
576
+ */
577
+ applyOrthographicFrame(frustumSize: number, near: number, far: number): void;
569
578
  /** Whether the debug orbit camera has received its initial pose. */
570
579
  isDebugOrbitPoseSeeded(): boolean;
571
580
  /**