@pmndrs/klipp 0.0.0-stage → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +72 -2
  3. package/dist/_virtual/_rolldown/runtime.js +13 -0
  4. package/dist/core/CameraState.d.ts +32 -0
  5. package/dist/core/CameraState.js +97 -0
  6. package/dist/core/EventDispatcher.d.ts +18 -0
  7. package/dist/core/EventDispatcher.js +28 -0
  8. package/dist/core/Klipp.d.ts +109 -0
  9. package/dist/core/Klipp.js +253 -0
  10. package/dist/core/TargetExtent.d.ts +11 -0
  11. package/dist/core/TargetExtent.js +54 -0
  12. package/dist/core/TargetPose.d.ts +13 -0
  13. package/dist/core/TargetPose.js +21 -0
  14. package/dist/core/VirtualCamera.d.ts +102 -0
  15. package/dist/core/VirtualCamera.js +290 -0
  16. package/dist/core/aim/HardLookAtAim.d.ts +10 -0
  17. package/dist/core/aim/HardLookAtAim.js +19 -0
  18. package/dist/core/aim/PanTiltAim.d.ts +26 -0
  19. package/dist/core/aim/PanTiltAim.js +38 -0
  20. package/dist/core/aim/RotateWithFollowTargetAim.d.ts +19 -0
  21. package/dist/core/aim/RotateWithFollowTargetAim.js +23 -0
  22. package/dist/core/aim/RotationComposerAim.d.ts +27 -0
  23. package/dist/core/aim/RotationComposerAim.js +27 -0
  24. package/dist/core/aim/hardLookAt.d.ts +4 -0
  25. package/dist/core/aim/hardLookAt.js +13 -0
  26. package/dist/core/aim/index.d.ts +11 -0
  27. package/dist/core/aim/lookRotation.d.ts +6 -0
  28. package/dist/core/aim/lookRotation.js +46 -0
  29. package/dist/core/aim/panTilt.d.ts +16 -0
  30. package/dist/core/aim/panTilt.js +121 -0
  31. package/dist/core/aim/rotateWithFollowTarget.d.ts +20 -0
  32. package/dist/core/aim/rotateWithFollowTarget.js +35 -0
  33. package/dist/core/aim/rotationComposer.d.ts +58 -0
  34. package/dist/core/aim/rotationComposer.js +284 -0
  35. package/dist/core/blend/BlendCurves.d.ts +19 -0
  36. package/dist/core/blend/BlendCurves.js +22 -0
  37. package/dist/core/blend/BlendDefinition.d.ts +21 -0
  38. package/dist/core/blend/BlendDefinition.js +9 -0
  39. package/dist/core/blend/BlendDriver.d.ts +23 -0
  40. package/dist/core/blend/BlendDriver.js +42 -0
  41. package/dist/core/blend/BlendHints.d.ts +9 -0
  42. package/dist/core/blend/BlendHints.js +13 -0
  43. package/dist/core/blend/blend.d.ts +41 -0
  44. package/dist/core/blend/blend.js +110 -0
  45. package/dist/core/blend/index.d.ts +6 -0
  46. package/dist/core/blend/lerpCameraState.d.ts +4 -0
  47. package/dist/core/blend/lerpCameraState.js +143 -0
  48. package/dist/core/body/BindingModes.d.ts +9 -0
  49. package/dist/core/body/BindingModes.js +11 -0
  50. package/dist/core/body/FollowBody.d.ts +24 -0
  51. package/dist/core/body/FollowBody.js +26 -0
  52. package/dist/core/body/HardLockToTargetBody.d.ts +17 -0
  53. package/dist/core/body/HardLockToTargetBody.js +20 -0
  54. package/dist/core/body/OrbitFollowBody.d.ts +47 -0
  55. package/dist/core/body/OrbitFollowBody.js +48 -0
  56. package/dist/core/body/PositionComposerBody.d.ts +28 -0
  57. package/dist/core/body/PositionComposerBody.js +27 -0
  58. package/dist/core/body/follow.d.ts +33 -0
  59. package/dist/core/body/follow.js +83 -0
  60. package/dist/core/body/hardLockToTarget.d.ts +17 -0
  61. package/dist/core/body/hardLockToTarget.js +26 -0
  62. package/dist/core/body/index.d.ts +17 -0
  63. package/dist/core/body/orbitFollow.d.ts +76 -0
  64. package/dist/core/body/orbitFollow.js +336 -0
  65. package/dist/core/body/positionComposer.d.ts +56 -0
  66. package/dist/core/body/positionComposer.js +207 -0
  67. package/dist/core/body/safeFromToRotation.d.ts +3 -0
  68. package/dist/core/body/safeFromToRotation.js +39 -0
  69. package/dist/core/body/threeRing.d.ts +28 -0
  70. package/dist/core/body/threeRing.js +100 -0
  71. package/dist/core/body/tracker.d.ts +42 -0
  72. package/dist/core/body/tracker.js +193 -0
  73. package/dist/core/damping/Damper.d.ts +11 -0
  74. package/dist/core/damping/Damper.js +22 -0
  75. package/dist/core/damping/damping.d.ts +30 -0
  76. package/dist/core/damping/damping.js +119 -0
  77. package/dist/core/damping/index.d.ts +5 -0
  78. package/dist/core/damping/predictor.d.ts +16 -0
  79. package/dist/core/damping/predictor.js +56 -0
  80. package/dist/core/debug/debugZones.d.ts +16 -0
  81. package/dist/core/debug/debugZones.js +38 -0
  82. package/dist/core/debug/index.d.ts +2 -0
  83. package/dist/core/extension/GroupFramingExtension.d.ts +26 -0
  84. package/dist/core/extension/GroupFramingExtension.js +24 -0
  85. package/dist/core/extension/LensExtension.d.ts +20 -0
  86. package/dist/core/extension/LensExtension.js +12 -0
  87. package/dist/core/extension/groupFraming.d.ts +62 -0
  88. package/dist/core/extension/groupFraming.js +271 -0
  89. package/dist/core/extension/index.d.ts +6 -0
  90. package/dist/core/extension/lens.d.ts +35 -0
  91. package/dist/core/extension/lens.js +57 -0
  92. package/dist/core/groups/ClearShot.d.ts +32 -0
  93. package/dist/core/groups/MixingCamera.d.ts +20 -0
  94. package/dist/core/groups/Sequencer.d.ts +24 -0
  95. package/dist/core/groups/StateDrivenCamera.d.ts +26 -0
  96. package/dist/core/groups/clearShotState.d.ts +32 -0
  97. package/dist/core/groups/index.d.ts +11 -0
  98. package/dist/core/groups/mixCameraStates.d.ts +13 -0
  99. package/dist/core/groups/sequencerState.d.ts +26 -0
  100. package/dist/core/groups/stateDrivenState.d.ts +28 -0
  101. package/dist/core/impulse/ImpulseField.d.ts +15 -0
  102. package/dist/core/impulse/ImpulseField.js +22 -0
  103. package/dist/core/impulse/ImpulseListenerNoise.d.ts +19 -0
  104. package/dist/core/impulse/ImpulseListenerNoise.js +29 -0
  105. package/dist/core/impulse/impulseListener.d.ts +13 -0
  106. package/dist/core/impulse/impulseListener.js +14 -0
  107. package/dist/core/impulse/impulses.d.ts +54 -0
  108. package/dist/core/impulse/impulses.js +84 -0
  109. package/dist/core/impulse/index.d.ts +6 -0
  110. package/dist/core/index.d.ts +20 -0
  111. package/dist/core/index.js +52 -0
  112. package/dist/core/input/InputAxis.d.ts +29 -0
  113. package/dist/core/input/InputAxis.js +28 -0
  114. package/dist/core/input/InputAxisOwner.d.ts +6 -0
  115. package/dist/core/input/InputAxisOwner.js +4 -0
  116. package/dist/core/input/InputController.d.ts +15 -0
  117. package/dist/core/input/InputController.js +24 -0
  118. package/dist/core/input/axis.d.ts +52 -0
  119. package/dist/core/input/axis.js +89 -0
  120. package/dist/core/input/consumedInput.d.ts +37 -0
  121. package/dist/core/input/consumedInput.js +34 -0
  122. package/dist/core/input/index.d.ts +9 -0
  123. package/dist/core/input/inputMapping.d.ts +46 -0
  124. package/dist/core/input/inputMapping.js +55 -0
  125. package/dist/core/input/shortestWrappedDelta.d.ts +2 -0
  126. package/dist/core/input/shortestWrappedDelta.js +11 -0
  127. package/dist/core/internal.d.ts +16 -0
  128. package/dist/core/internal.js +19 -0
  129. package/dist/core/klippState.d.ts +78 -0
  130. package/dist/core/klippState.js +124 -0
  131. package/dist/core/noise/BasicMultiChannelPerlinNoise.d.ts +21 -0
  132. package/dist/core/noise/BasicMultiChannelPerlinNoise.js +13 -0
  133. package/dist/core/noise/index.d.ts +3 -0
  134. package/dist/core/noise/perlinNoise.d.ts +36 -0
  135. package/dist/core/noise/perlinNoise.js +110 -0
  136. package/dist/core/params.d.ts +2 -0
  137. package/dist/core/params.js +12 -0
  138. package/dist/dom/DebugOverlay.d.ts +11 -0
  139. package/dist/dom/DebugOverlay.js +96 -0
  140. package/dist/dom/InputControllerDom.d.ts +15 -0
  141. package/dist/dom/InputControllerDom.js +31 -0
  142. package/dist/dom/InputSystem.d.ts +40 -0
  143. package/dist/dom/InputSystem.js +113 -0
  144. package/dist/dom/index.d.ts +3 -0
  145. package/dist/dom/index.js +5 -0
  146. package/dist/input-sources/buttonInput.d.ts +15 -0
  147. package/dist/input-sources/buttonInput.js +23 -0
  148. package/dist/input-sources/isInsideInteractiveArea.d.ts +9 -0
  149. package/dist/input-sources/isInsideInteractiveArea.js +11 -0
  150. package/dist/input-sources/mouse.d.ts +47 -0
  151. package/dist/input-sources/mouse.js +171 -0
  152. package/dist/input-sources/safariGesture.d.ts +32 -0
  153. package/dist/input-sources/safariGesture.js +107 -0
  154. package/dist/input-sources/suppressNativeGestures.d.ts +5 -0
  155. package/dist/input-sources/suppressNativeGestures.js +32 -0
  156. package/dist/input-sources/touch.d.ts +47 -0
  157. package/dist/input-sources/touch.js +173 -0
  158. package/dist/input-sources/wheel.d.ts +28 -0
  159. package/dist/input-sources/wheel.js +44 -0
  160. package/dist/react/CameraFrustumHelper.d.ts +13 -0
  161. package/dist/react/CameraFrustumHelper.js +32 -0
  162. package/dist/react/DebugZoneOverlay.d.ts +7 -0
  163. package/dist/react/DebugZoneOverlay.js +23 -0
  164. package/dist/react/Klipp.d.ts +20 -0
  165. package/dist/react/Klipp.js +47 -0
  166. package/dist/react/KlippContext.d.ts +5 -0
  167. package/dist/react/KlippContext.js +11 -0
  168. package/dist/react/VirtualCamera.d.ts +28 -0
  169. package/dist/react/VirtualCamera.js +81 -0
  170. package/dist/react/VirtualCameraContext.d.ts +11 -0
  171. package/dist/react/VirtualCameraContext.js +21 -0
  172. package/dist/react/aim/Aim.d.ts +11 -0
  173. package/dist/react/aim/Aim.js +14 -0
  174. package/dist/react/aim/HardLookAt.d.ts +10 -0
  175. package/dist/react/aim/HardLookAt.js +15 -0
  176. package/dist/react/aim/PanTilt.d.ts +31 -0
  177. package/dist/react/aim/PanTilt.js +38 -0
  178. package/dist/react/aim/RotateWithFollowTarget.d.ts +10 -0
  179. package/dist/react/aim/RotateWithFollowTarget.js +18 -0
  180. package/dist/react/aim/RotationComposer.d.ts +12 -0
  181. package/dist/react/aim/RotationComposer.js +34 -0
  182. package/dist/react/body/Body.d.ts +11 -0
  183. package/dist/react/body/Body.js +14 -0
  184. package/dist/react/body/CameraControls.d.ts +50 -0
  185. package/dist/react/body/CameraControls.js +106 -0
  186. package/dist/react/body/Follow.d.ts +10 -0
  187. package/dist/react/body/Follow.js +20 -0
  188. package/dist/react/body/HardLockToTarget.d.ts +10 -0
  189. package/dist/react/body/HardLockToTarget.js +18 -0
  190. package/dist/react/body/OrbitFollow.d.ts +25 -0
  191. package/dist/react/body/OrbitFollow.js +67 -0
  192. package/dist/react/body/PositionComposer.d.ts +12 -0
  193. package/dist/react/body/PositionComposer.js +32 -0
  194. package/dist/react/body/camera-controls.d.ts +2 -0
  195. package/dist/react/body/camera-controls.js +3 -0
  196. package/dist/react/extension/Extension.d.ts +7 -0
  197. package/dist/react/extension/Extension.js +10 -0
  198. package/dist/react/extension/GroupFraming.d.ts +14 -0
  199. package/dist/react/extension/GroupFraming.js +52 -0
  200. package/dist/react/extension/Lens.d.ts +7 -0
  201. package/dist/react/extension/Lens.js +31 -0
  202. package/dist/react/impulse/ImpulseListener.d.ts +12 -0
  203. package/dist/react/impulse/ImpulseListener.js +33 -0
  204. package/dist/react/index.d.ts +24 -0
  205. package/dist/react/index.js +24 -0
  206. package/dist/react/input/InputAxisOwnerContext.d.ts +3 -0
  207. package/dist/react/input/InputAxisOwnerContext.js +6 -0
  208. package/dist/react/input/InputController.d.ts +53 -0
  209. package/dist/react/input/InputController.js +115 -0
  210. package/dist/react/noise/BasicMultiChannelPerlin.d.ts +7 -0
  211. package/dist/react/noise/BasicMultiChannelPerlin.js +14 -0
  212. package/dist/react/noise/Noise.d.ts +5 -0
  213. package/dist/react/noise/Noise.js +6 -0
  214. package/dist/react/noise/useBasicMultiChannelPerlinNoise.d.ts +4 -0
  215. package/dist/react/noise/useBasicMultiChannelPerlinNoise.js +21 -0
  216. package/dist/react/useCameraTransitionEvent.d.ts +12 -0
  217. package/dist/react/useCameraTransitionEvent.js +14 -0
  218. package/dist/three/CameraFrustumHelperThree.d.ts +11 -0
  219. package/dist/three/CameraFrustumHelperThree.js +44 -0
  220. package/dist/three/KlippThree.d.ts +18 -0
  221. package/dist/three/KlippThree.js +50 -0
  222. package/dist/three/VirtualCameraThree.d.ts +35 -0
  223. package/dist/three/VirtualCameraThree.js +108 -0
  224. package/dist/three/aim/HardLookAtAimThree.d.ts +10 -0
  225. package/dist/three/aim/HardLookAtAimThree.js +14 -0
  226. package/dist/three/aim/PanTiltAimThree.d.ts +10 -0
  227. package/dist/three/aim/PanTiltAimThree.js +15 -0
  228. package/dist/three/aim/RotateWithFollowTargetAimThree.d.ts +11 -0
  229. package/dist/three/aim/RotateWithFollowTargetAimThree.js +15 -0
  230. package/dist/three/aim/RotationComposerAimThree.d.ts +26 -0
  231. package/dist/three/aim/RotationComposerAimThree.js +35 -0
  232. package/dist/three/body/CameraControlsBodyThree.d.ts +30 -0
  233. package/dist/three/body/CameraControlsBodyThree.js +54 -0
  234. package/dist/three/body/FollowBodyThree.d.ts +16 -0
  235. package/dist/three/body/FollowBodyThree.js +23 -0
  236. package/dist/three/body/HardLockToTargetBodyThree.d.ts +11 -0
  237. package/dist/three/body/HardLockToTargetBodyThree.js +14 -0
  238. package/dist/three/body/OrbitFollowBodyThree.d.ts +16 -0
  239. package/dist/three/body/OrbitFollowBodyThree.js +23 -0
  240. package/dist/three/body/OrbitFollowHelperThree.d.ts +23 -0
  241. package/dist/three/body/OrbitFollowHelperThree.js +85 -0
  242. package/dist/three/body/PositionComposerBodyThree.d.ts +24 -0
  243. package/dist/three/body/PositionComposerBodyThree.js +31 -0
  244. package/dist/three/camera.d.ts +10 -0
  245. package/dist/three/camera.js +39 -0
  246. package/dist/three/damping/Predictor.d.ts +12 -0
  247. package/dist/three/damping/Predictor.js +30 -0
  248. package/dist/three/damping/QuaternionDamper.d.ts +10 -0
  249. package/dist/three/damping/QuaternionDamper.js +28 -0
  250. package/dist/three/damping/Vector3Damper.d.ts +10 -0
  251. package/dist/three/damping/Vector3Damper.js +26 -0
  252. package/dist/three/extension/GroupFramingExtensionThree.d.ts +13 -0
  253. package/dist/three/extension/GroupFramingExtensionThree.js +23 -0
  254. package/dist/three/extension/TargetGroup.d.ts +32 -0
  255. package/dist/three/extension/TargetGroup.js +53 -0
  256. package/dist/three/index.d.ts +24 -0
  257. package/dist/three/index.js +25 -0
  258. package/dist/three/noise/BasicMultiChannelPerlinNoiseThree.d.ts +16 -0
  259. package/dist/three/noise/BasicMultiChannelPerlinNoiseThree.js +17 -0
  260. package/dist/three/readTargetExtent.d.ts +9 -0
  261. package/dist/three/readTargetExtent.js +25 -0
  262. package/dist/three/readTargetPose.d.ts +8 -0
  263. package/dist/three/readTargetPose.js +21 -0
  264. package/dist/three/resolve/Target.d.ts +17 -0
  265. package/dist/three/resolve/Target.js +62 -0
  266. package/dist/three/resolve/TargetRegistry.d.ts +27 -0
  267. package/dist/three/resolve/TargetRegistry.js +78 -0
  268. package/dist/three/resolve/resolveVector3.d.ts +12 -0
  269. package/dist/three/resolve/resolveVector3.js +29 -0
  270. package/package.json +120 -4
@@ -0,0 +1,21 @@
1
+ import { type Ease } from './BlendCurves.js';
2
+ /** A fixed-duration curve or a damped transition. */
3
+ export type BlendDefinition = {
4
+ curve: Ease;
5
+ time: number;
6
+ damping?: never;
7
+ maxSpeed?: never;
8
+ } | {
9
+ damping: number;
10
+ maxSpeed?: number;
11
+ curve?: never;
12
+ time?: never;
13
+ };
14
+ /** A blend override for an optional source and destination camera. */
15
+ export type CustomBlend = {
16
+ from?: string;
17
+ to?: string;
18
+ blend: BlendDefinition;
19
+ };
20
+ /** Used when no blend is given. */
21
+ export declare const DEFAULT_BLEND: BlendDefinition;
@@ -0,0 +1,9 @@
1
+ import { BlendCurves } from "./BlendCurves.js";
2
+ //#region src/core/blend/BlendDefinition.ts
3
+ /** Used when no blend is given. */
4
+ var DEFAULT_BLEND = {
5
+ curve: BlendCurves.easeInOut,
6
+ time: 2
7
+ };
8
+ //#endregion
9
+ export { DEFAULT_BLEND };
@@ -0,0 +1,23 @@
1
+ import type { CameraState } from '../CameraState.js';
2
+ import * as blend from './blend.js';
3
+ import type { BlendDefinition } from './BlendDefinition.js';
4
+ import { BlendHints } from './BlendHints.js';
5
+ /** Stateful wrapper over the blend functions, resolving camera states by id. */
6
+ export declare class BlendDriver<Id> {
7
+ readonly state: blend.BlendState<Id>;
8
+ private readonly getState;
9
+ constructor(getState: (id: Id) => CameraState);
10
+ /** Candidate whose state is currently settled in the output. */
11
+ get liveId(): Id | null;
12
+ get isBlending(): boolean;
13
+ /** Whether the driver has produced a real output at least once. */
14
+ get hasEverActivated(): boolean;
15
+ /** Destination of the active blend, or `liveId` when settled. */
16
+ get blendTargetId(): Id | null;
17
+ /** Set the transition destination. Retargeting starts from the current output. */
18
+ setTarget(toId: Id, definition: BlendDefinition, hints?: BlendHints): void;
19
+ /** Remove a candidate without discarding the current output. */
20
+ forget(id: Id): void;
21
+ /** Advance the blend and return the reusable output state. */
22
+ tick(dt: number): CameraState;
23
+ }
@@ -0,0 +1,42 @@
1
+ import { BlendHints } from "./BlendHints.js";
2
+ import { create, forget, setTarget, targetId, tick } from "./blend.js";
3
+ //#region src/core/blend/BlendDriver.ts
4
+ /** Stateful wrapper over the blend functions, resolving camera states by id. */
5
+ var BlendDriver = class {
6
+ state = create();
7
+ getState;
8
+ constructor(getState) {
9
+ this.getState = getState;
10
+ }
11
+ /** Candidate whose state is currently settled in the output. */
12
+ get liveId() {
13
+ return this.state.liveId;
14
+ }
15
+ get isBlending() {
16
+ return this.state.transition.active;
17
+ }
18
+ /** Whether the driver has produced a real output at least once. */
19
+ get hasEverActivated() {
20
+ return this.state.hasEverActivated;
21
+ }
22
+ /** Destination of the active blend, or `liveId` when settled. */
23
+ get blendTargetId() {
24
+ return targetId(this.state);
25
+ }
26
+ /** Set the transition destination. Retargeting starts from the current output. */
27
+ setTarget(toId, definition, hints = BlendHints.none) {
28
+ if (toId === targetId(this.state)) return;
29
+ setTarget(this.state, toId, this.getState(toId), definition, hints);
30
+ }
31
+ /** Remove a candidate without discarding the current output. */
32
+ forget(id) {
33
+ forget(this.state, id);
34
+ }
35
+ /** Advance the blend and return the reusable output state. */
36
+ tick(dt) {
37
+ const targetId$1 = targetId(this.state);
38
+ return tick(this.state, dt, targetId$1 !== null ? this.getState(targetId$1) : null);
39
+ }
40
+ };
41
+ //#endregion
42
+ export { BlendDriver };
@@ -0,0 +1,9 @@
1
+ /** Bitmask controlling how a camera transition is blended. */
2
+ export declare const BlendHints: {
3
+ readonly none: 0;
4
+ readonly cylindricalPosition: number;
5
+ readonly sphericalPosition: number;
6
+ readonly ignoreTarget: number;
7
+ };
8
+ export type BlendHints = number;
9
+ export declare function hasBlendHint(hints: BlendHints, flag: number): boolean;
@@ -0,0 +1,13 @@
1
+ //#region src/core/blend/BlendHints.ts
2
+ /** Bitmask controlling how a camera transition is blended. */
3
+ var BlendHints = {
4
+ none: 0,
5
+ cylindricalPosition: 1,
6
+ sphericalPosition: 2,
7
+ ignoreTarget: 8
8
+ };
9
+ function hasBlendHint(hints, flag) {
10
+ return (hints & flag) !== 0;
11
+ }
12
+ //#endregion
13
+ export { BlendHints, hasBlendHint };
@@ -0,0 +1,41 @@
1
+ import type { CameraState } from '../CameraState.js';
2
+ import type { DamperState } from '../damping/damping.js';
3
+ import type { BlendDefinition, CustomBlend } from './BlendDefinition.js';
4
+ import { BlendHints } from './BlendHints.js';
5
+ /** A transition in flight from a frozen `from` state toward the live `toId` camera. */
6
+ export type BlendTransition<Id> = {
7
+ active: boolean;
8
+ from: CameraState;
9
+ toId: Id | null;
10
+ definition: BlendDefinition | null;
11
+ elapsed: number;
12
+ progress: number;
13
+ damper: DamperState;
14
+ hints: BlendHints;
15
+ };
16
+ export type BlendState<Id> = {
17
+ /** Camera currently settled in the output. */
18
+ liveId: Id | null;
19
+ /** Whether a real output has been produced at least once. */
20
+ hasEverActivated: boolean;
21
+ transition: BlendTransition<Id>;
22
+ /** Reusable output, returned by `tick`. */
23
+ output: CameraState;
24
+ };
25
+ export declare const create: <Id>() => BlendState<Id>;
26
+ /** Destination of the active transition, or `liveId` when settled. */
27
+ export declare const targetId: <Id>(state: BlendState<Id>) => Id | null;
28
+ /**
29
+ * Start a transition to `toId`, from the current output. The very first target is taken over at once
30
+ * from `toState`, since there is nothing to blend from yet.
31
+ */
32
+ export declare function setTarget<Id>(state: BlendState<Id>, toId: Id, toState: CameraState, definition: BlendDefinition, hints?: BlendHints): void;
33
+ /** Drop a camera that went away, keeping the current output. */
34
+ export declare function forget<Id>(state: BlendState<Id>, id: Id): void;
35
+ /**
36
+ * Advance the transition and composite the output. `targetState` is the state of `targetId(state)`,
37
+ * or `null` when there is none.
38
+ */
39
+ export declare function tick<Id>(state: BlendState<Id>, dt: number, targetState: CameraState | null): CameraState;
40
+ /** Resolves the most specific custom blend for a transition. */
41
+ export declare function resolveDefinition(customBlends: CustomBlend[], from: string | null, to: string, defaultBlend: BlendDefinition): BlendDefinition;
@@ -0,0 +1,110 @@
1
+ import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
2
+ import { BlendHints } from "./BlendHints.js";
3
+ import { lerp as lerp$1 } from "./lerpCameraState.js";
4
+ import { copy, create as create$1 } from "../CameraState.js";
5
+ import { createState, damp, reset } from "../damping/damping.js";
6
+ import { clamp } from "math";
7
+ //#region src/core/blend/blend.ts
8
+ var blend_exports = /* @__PURE__ */ __exportAll({
9
+ create: () => create,
10
+ forget: () => forget,
11
+ resolveDefinition: () => resolveDefinition,
12
+ setTarget: () => setTarget,
13
+ targetId: () => targetId,
14
+ tick: () => tick
15
+ });
16
+ var create = () => ({
17
+ liveId: null,
18
+ hasEverActivated: false,
19
+ transition: {
20
+ active: false,
21
+ from: create$1(),
22
+ toId: null,
23
+ definition: null,
24
+ elapsed: 0,
25
+ progress: 0,
26
+ damper: createState(),
27
+ hints: BlendHints.none
28
+ },
29
+ output: create$1()
30
+ });
31
+ /** Destination of the active transition, or `liveId` when settled. */
32
+ var targetId = (state) => state.transition.active ? state.transition.toId : state.liveId;
33
+ /**
34
+ * Start a transition to `toId`, from the current output. The very first target is taken over at once
35
+ * from `toState`, since there is nothing to blend from yet.
36
+ */
37
+ function setTarget(state, toId, toState, definition, hints = BlendHints.none) {
38
+ if (toId === targetId(state)) return;
39
+ if (!state.hasEverActivated) {
40
+ state.hasEverActivated = true;
41
+ state.liveId = toId;
42
+ copy(state.output, toState);
43
+ return;
44
+ }
45
+ const transition = state.transition;
46
+ copy(transition.from, state.output);
47
+ transition.active = true;
48
+ transition.toId = toId;
49
+ transition.definition = definition;
50
+ transition.elapsed = 0;
51
+ transition.progress = 0;
52
+ transition.hints = hints;
53
+ if (definition.damping !== void 0) {
54
+ reset(transition.damper);
55
+ damp(transition.damper, 0, definition.damping, 0);
56
+ }
57
+ }
58
+ /** Drop a camera that went away, keeping the current output. */
59
+ function forget(state, id) {
60
+ const transition = state.transition;
61
+ if (transition.active && transition.toId === id) {
62
+ transition.active = false;
63
+ transition.toId = null;
64
+ state.liveId = null;
65
+ } else if (state.liveId === id) state.liveId = null;
66
+ }
67
+ /**
68
+ * Advance the transition and composite the output. `targetState` is the state of `targetId(state)`,
69
+ * or `null` when there is none.
70
+ */
71
+ function tick(state, dt, targetState) {
72
+ const transition = state.transition;
73
+ if (transition.active && targetState) {
74
+ const definition = transition.definition;
75
+ let t;
76
+ if (definition.damping !== void 0) {
77
+ transition.damper.value = transition.progress;
78
+ transition.progress = damp(transition.damper, 1, definition.damping, dt, definition.maxSpeed).value;
79
+ t = transition.progress;
80
+ } else {
81
+ transition.elapsed += dt;
82
+ const rawT = definition.time <= 0 ? 1 : clamp(transition.elapsed / definition.time, 0, 1);
83
+ t = definition.curve(rawT);
84
+ }
85
+ lerp$1(state.output, transition.from, targetState, t, transition.hints);
86
+ if (t >= 1) {
87
+ state.liveId = transition.toId;
88
+ transition.active = false;
89
+ transition.toId = null;
90
+ }
91
+ } else if (state.liveId !== null && targetState) copy(state.output, targetState);
92
+ return state.output;
93
+ }
94
+ /** Resolves the most specific custom blend for a transition. */
95
+ function resolveDefinition(customBlends, from, to, defaultBlend) {
96
+ let best = null;
97
+ let bestSpecificity = -1;
98
+ for (const entry of customBlends) {
99
+ if (entry.to !== void 0 && entry.to !== to) continue;
100
+ if (entry.from !== void 0 && entry.from !== from) continue;
101
+ const specificity = (entry.to !== void 0 ? 2 : 0) + (entry.from !== void 0 ? 1 : 0);
102
+ if (specificity > bestSpecificity) {
103
+ best = entry;
104
+ bestSpecificity = specificity;
105
+ }
106
+ }
107
+ return best ? best.blend : defaultBlend;
108
+ }
109
+ //#endregion
110
+ export { blend_exports, create, forget, resolveDefinition, setTarget, targetId, tick };
@@ -0,0 +1,6 @@
1
+ export { BlendDriver } from './BlendDriver.js';
2
+ export * as blend from './blend.js';
3
+ export type { BlendState, BlendTransition } from './blend.js';
4
+ export { DEFAULT_BLEND, type BlendDefinition, type CustomBlend } from './BlendDefinition.js';
5
+ export { BlendHints, hasBlendHint } from './BlendHints.js';
6
+ export { BlendCurves, type Ease } from './BlendCurves.js';
@@ -0,0 +1,4 @@
1
+ import type { CameraState } from '../CameraState.js';
2
+ import { BlendHints } from './BlendHints.js';
3
+ /** Interpolates a camera state while preserving blend hints and rotation continuity. */
4
+ export declare function lerp(out: CameraState, a: CameraState, b: CameraState, t: number, hints?: BlendHints): CameraState;
@@ -0,0 +1,143 @@
1
+ import { BlendHints, hasBlendHint } from "./BlendHints.js";
2
+ import { clamp, deltaAngle, lerp, mat4, quat, spherical, vec3, vec4 } from "math";
3
+ //#region src/core/blend/lerpCameraState.ts
4
+ /** Reused quaternion for the sign-adjusted destination case. */
5
+ var negatedB = [
6
+ 0,
7
+ 0,
8
+ 0,
9
+ 1
10
+ ];
11
+ var scratchOffsetA = [
12
+ 0,
13
+ 0,
14
+ 0
15
+ ];
16
+ var scratchOffsetB = [
17
+ 0,
18
+ 0,
19
+ 0
20
+ ];
21
+ var scratchSphericalA = [
22
+ 0,
23
+ 0,
24
+ 0
25
+ ];
26
+ var scratchSphericalB = [
27
+ 0,
28
+ 0,
29
+ 0
30
+ ];
31
+ var scratchSphericalOut = [
32
+ 0,
33
+ 0,
34
+ 0
35
+ ];
36
+ var scratchLookMatrix = mat4.create();
37
+ var scratchLookAtCurrent = [
38
+ 0,
39
+ 0,
40
+ 0,
41
+ 1
42
+ ];
43
+ var scratchDeltaA = [
44
+ 0,
45
+ 0,
46
+ 0,
47
+ 1
48
+ ];
49
+ var scratchDeltaB = [
50
+ 0,
51
+ 0,
52
+ 0,
53
+ 1
54
+ ];
55
+ /** Interpolates look-at rotation while preserving each state's additional aim offset. */
56
+ function lerpLookAtRotation(out, a, b, t, current) {
57
+ quat.multiply(scratchDeltaA, quat.conjugate(scratchDeltaA, lookAtRotation(scratchDeltaA, a)), a.quaternion);
58
+ quat.multiply(scratchDeltaB, quat.conjugate(scratchDeltaB, lookAtRotation(scratchDeltaB, b)), b.quaternion);
59
+ lookAtRotation(scratchLookAtCurrent, current);
60
+ quat.multiply(out, scratchLookAtCurrent, quat.slerp(out, scratchDeltaA, scratchDeltaB, t));
61
+ }
62
+ /** The rotation looking from `state.position` at `state.lookAtTarget`. */
63
+ function lookAtRotation(out, state) {
64
+ mat4.targetTo(scratchLookMatrix, state.position, state.lookAtTarget, state.referenceUp);
65
+ return quat.fromMat4(out, scratchLookMatrix);
66
+ }
67
+ /** Below this radius, angular values are not meaningful. */
68
+ var RADIUS_EPSILON = 1e-4;
69
+ /** Keeps the valid side's angle when the other radius is too small. */
70
+ function blendAngle(angleA, radiusA, angleB, radiusB, t) {
71
+ const validA = radiusA >= RADIUS_EPSILON;
72
+ if (validA && radiusB >= RADIUS_EPSILON) return angleA + deltaAngle(angleA, angleB) * t;
73
+ return validA ? angleA : angleB;
74
+ }
75
+ /** Interpolates the camera offset in spherical or cylindrical coordinates. */
76
+ function lerpPositionAroundTarget(out, a, b, t, cylindrical) {
77
+ vec3.subtract(scratchOffsetA, a.position, a.target);
78
+ vec3.subtract(scratchOffsetB, b.position, b.target);
79
+ if (cylindrical) {
80
+ const radiusA = Math.hypot(scratchOffsetA[0], scratchOffsetA[2]);
81
+ const radiusB = Math.hypot(scratchOffsetB[0], scratchOffsetB[2]);
82
+ const angle = blendAngle(Math.atan2(scratchOffsetA[0], scratchOffsetA[2]), radiusA, Math.atan2(scratchOffsetB[0], scratchOffsetB[2]), radiusB, t);
83
+ const radius = lerp(radiusA, radiusB, t);
84
+ vec3.set(out, radius * Math.sin(angle), lerp(scratchOffsetA[1], scratchOffsetB[1], t), radius * Math.cos(angle));
85
+ } else {
86
+ spherical.setFromVec3(scratchSphericalA, scratchOffsetA);
87
+ spherical.setFromVec3(scratchSphericalB, scratchOffsetB);
88
+ const theta = blendAngle(scratchSphericalA[1], scratchSphericalA[0], scratchSphericalB[1], scratchSphericalB[0], t);
89
+ const phi = blendAngle(scratchSphericalA[2], scratchSphericalA[0], scratchSphericalB[2], scratchSphericalB[0], t);
90
+ spherical.toVec3(out, spherical.set(scratchSphericalOut, lerp(scratchSphericalA[0], scratchSphericalB[0], t), theta, phi));
91
+ }
92
+ out[0] += lerp(a.target[0], b.target[0], t);
93
+ out[1] += lerp(a.target[1], b.target[1], t);
94
+ out[2] += lerp(a.target[2], b.target[2], t);
95
+ }
96
+ /** Slerps quaternions without changing the caller-selected sign of `to`. */
97
+ function slerpWithContinuity(out, from, to, t) {
98
+ const toX = to[0], toY = to[1], toZ = to[2], toW = to[3];
99
+ const dot = clamp(from[0] * toX + from[1] * toY + from[2] * toZ + from[3] * toW, -1, 1);
100
+ const fromX = from[0], fromY = from[1], fromZ = from[2], fromW = from[3];
101
+ if (Math.abs(dot) < .9995) {
102
+ const theta = Math.acos(dot);
103
+ const sin = Math.sin(theta);
104
+ const s = Math.sin((1 - t) * theta) / sin;
105
+ const u = Math.sin(t * theta) / sin;
106
+ vec4.set(out, fromX * s + toX * u, fromY * s + toY * u, fromZ * s + toZ * u, fromW * s + toW * u);
107
+ } else {
108
+ const s = 1 - t;
109
+ vec4.set(out, fromX * s + toX * t, fromY * s + toY * t, fromZ * s + toZ * t, fromW * s + toW * t);
110
+ if (vec4.squaredLength(out) === 0) quat.identity(out);
111
+ else quat.normalize(out, out);
112
+ }
113
+ }
114
+ /** Interpolates a camera state while preserving blend hints and rotation continuity. */
115
+ function lerp$1(out, a, b, t, hints = BlendHints.none) {
116
+ const clamped = clamp(t, 0, 1);
117
+ const hasTarget = a.hasTarget && b.hasTarget;
118
+ const hasLookAtTarget = a.hasLookAtTarget && b.hasLookAtTarget;
119
+ const spherical = hasTarget && hasBlendHint(hints, BlendHints.sphericalPosition);
120
+ const cylindrical = hasTarget && !spherical && hasBlendHint(hints, BlendHints.cylindricalPosition);
121
+ const useLookAtRotation = hasLookAtTarget && !hasBlendHint(hints, BlendHints.ignoreTarget);
122
+ if (spherical || cylindrical) lerpPositionAroundTarget(out.position, a, b, clamped, cylindrical);
123
+ else vec3.lerp(out.position, a.position, b.position, clamped);
124
+ if (hasTarget) vec3.lerp(out.target, a.target, b.target, clamped);
125
+ out.hasTarget = hasTarget;
126
+ if (hasLookAtTarget) vec3.lerp(out.lookAtTarget, a.lookAtTarget, b.lookAtTarget, clamped);
127
+ out.hasLookAtTarget = hasLookAtTarget;
128
+ vec3.normalize(out.referenceUp, vec3.lerp(out.referenceUp, a.referenceUp, b.referenceUp, clamped));
129
+ quat.identity(out.rotationDampingBypass);
130
+ if (useLookAtRotation) lerpLookAtRotation(out.quaternion, a, b, clamped, out);
131
+ else {
132
+ const bQuaternion = vec4.dot(out.quaternion, b.quaternion) < 0 ? vec4.set(negatedB, -b.quaternion[0], -b.quaternion[1], -b.quaternion[2], -b.quaternion[3]) : b.quaternion;
133
+ slerpWithContinuity(out.quaternion, a.quaternion, bQuaternion, clamped);
134
+ }
135
+ out.fov = lerp(a.fov, b.fov, clamped);
136
+ out.near = lerp(a.near, b.near, clamped);
137
+ out.far = lerp(a.far, b.far, clamped);
138
+ out.viewOffset[0] = lerp(a.viewOffset[0], b.viewOffset[0], clamped);
139
+ out.viewOffset[1] = lerp(a.viewOffset[1], b.viewOffset[1], clamped);
140
+ return out;
141
+ }
142
+ //#endregion
143
+ export { lerp$1 as lerp };
@@ -0,0 +1,9 @@
1
+ /** Which rotation (if any) a Body applies to its offset before adding it to the target's world position. */
2
+ export declare const BindingModes: {
3
+ readonly worldSpace: 'worldSpace';
4
+ readonly lockToTarget: 'lockToTarget';
5
+ readonly lockToTargetWithWorldUp: 'lockToTargetWithWorldUp';
6
+ readonly lockToTargetNoRoll: 'lockToTargetNoRoll';
7
+ readonly lockToTargetOnAssign: 'lockToTargetOnAssign';
8
+ };
9
+ export type BindingMode = (typeof BindingModes)[keyof typeof BindingModes];
@@ -0,0 +1,11 @@
1
+ //#region src/core/body/BindingModes.ts
2
+ /** Which rotation (if any) a Body applies to its offset before adding it to the target's world position. */
3
+ var BindingModes = {
4
+ worldSpace: "worldSpace",
5
+ lockToTarget: "lockToTarget",
6
+ lockToTargetWithWorldUp: "lockToTargetWithWorldUp",
7
+ lockToTargetNoRoll: "lockToTargetNoRoll",
8
+ lockToTargetOnAssign: "lockToTargetOnAssign"
9
+ };
10
+ //#endregion
11
+ export { BindingModes };
@@ -0,0 +1,24 @@
1
+ import type { Vec3 } from 'math';
2
+ import type { CameraState } from '../CameraState.js';
3
+ import type { TargetPose } from '../TargetPose.js';
4
+ import type { DampingConstant } from '../damping/damping.js';
5
+ import * as follow from './follow.js';
6
+ import type { BindingMode } from './BindingModes.js';
7
+ import type { FollowParams } from './follow.js';
8
+ export type FollowOptions = Partial<FollowParams>;
9
+ /** Follows a target with an offset rotated according to `bindingMode`. Layers override `readTarget`. */
10
+ export declare class FollowBody<T = TargetPose | null> implements FollowParams {
11
+ target: T;
12
+ offset: Vec3;
13
+ damping: DampingConstant;
14
+ rotationDamping: DampingConstant;
15
+ bindingMode: BindingMode;
16
+ maxSpeed: number;
17
+ readonly state: follow.FollowState;
18
+ private lastTarget;
19
+ constructor(target: T, options?: FollowOptions);
20
+ update: (out: CameraState, dt: number, justActivated: boolean) => void;
21
+ primeFrom: (position: Vec3) => void;
22
+ /** This frame's target pose, or `null` when there is none. */
23
+ protected readTarget(): TargetPose | null;
24
+ }
@@ -0,0 +1,26 @@
1
+ import { createParams, createState, prime, update } from "./follow.js";
2
+ //#region src/core/body/FollowBody.ts
3
+ /** Follows a target with an offset rotated according to `bindingMode`. Layers override `readTarget`. */
4
+ var FollowBody = class {
5
+ target;
6
+ state = createState();
7
+ lastTarget = void 0;
8
+ constructor(target, options) {
9
+ this.target = target;
10
+ Object.assign(this, createParams(options));
11
+ }
12
+ update = (out, dt, justActivated) => {
13
+ if (justActivated || this.target !== this.lastTarget) {
14
+ this.lastTarget = this.target;
15
+ this.state.tracker.assigned = false;
16
+ }
17
+ update(out, this.state, this, this.readTarget(), dt, justActivated);
18
+ };
19
+ primeFrom = (position) => prime(this.state, position);
20
+ /** This frame's target pose, or `null` when there is none. */
21
+ readTarget() {
22
+ return this.target;
23
+ }
24
+ };
25
+ //#endregion
26
+ export { FollowBody };
@@ -0,0 +1,17 @@
1
+ import type { CameraState } from '../CameraState.js';
2
+ import type { TargetPose } from '../TargetPose.js';
3
+ import type { DampingConstant } from '../damping/damping.js';
4
+ import * as hardLockToTarget from './hardLockToTarget.js';
5
+ import type { HardLockToTargetParams } from './hardLockToTarget.js';
6
+ export type HardLockToTargetOptions = Partial<HardLockToTargetParams>;
7
+ /** Locks the camera position to a target. Layers override `readTarget` to read their own targets. */
8
+ export declare class HardLockToTargetBody<T = TargetPose | null> implements HardLockToTargetParams {
9
+ target: T;
10
+ damping: DampingConstant;
11
+ maxSpeed: number;
12
+ readonly state: hardLockToTarget.HardLockToTargetState;
13
+ constructor(target: T, options?: HardLockToTargetOptions);
14
+ update: (out: CameraState, dt: number, justActivated: boolean) => void;
15
+ /** This frame's target pose, or `null` when there is none. */
16
+ protected readTarget(): TargetPose | null;
17
+ }
@@ -0,0 +1,20 @@
1
+ import { createParams, createState, update } from "./hardLockToTarget.js";
2
+ //#region src/core/body/HardLockToTargetBody.ts
3
+ /** Locks the camera position to a target. Layers override `readTarget` to read their own targets. */
4
+ var HardLockToTargetBody = class {
5
+ target;
6
+ state = createState();
7
+ constructor(target, options) {
8
+ this.target = target;
9
+ Object.assign(this, createParams(options));
10
+ }
11
+ update = (out, dt, justActivated) => {
12
+ update(out, this.state, this, this.readTarget()?.position ?? null, dt, justActivated);
13
+ };
14
+ /** This frame's target pose, or `null` when there is none. */
15
+ readTarget() {
16
+ return this.target;
17
+ }
18
+ };
19
+ //#endregion
20
+ export { HardLockToTargetBody };
@@ -0,0 +1,47 @@
1
+ import type { Quat, Vec3 } from 'math';
2
+ import type { CameraState } from '../CameraState.js';
3
+ import type { TargetPose } from '../TargetPose.js';
4
+ import type { DampingConstant } from '../damping/damping.js';
5
+ import type { InputAxisOwner } from '../input/InputAxisOwner.js';
6
+ import * as orbitFollow from './orbitFollow.js';
7
+ import type { BindingMode } from './BindingModes.js';
8
+ import type { OrbitFollowParams, OrbitStyle, RecenteringTarget } from './orbitFollow.js';
9
+ import type { Orbits } from './threeRing.js';
10
+ export type OrbitFollowOptions = Partial<OrbitFollowParams>;
11
+ /**
12
+ * Orbits a target on a sphere or through three rings, driven by three `InputAxis`: `horizontal`, `vertical` and `radial`.
13
+ * Layers override `readTarget`.
14
+ */
15
+ export declare class OrbitFollowBody<T = TargetPose | null> implements OrbitFollowParams, InputAxisOwner {
16
+ target: T;
17
+ orbitStyle: OrbitStyle;
18
+ radius: number;
19
+ orbits: Orbits;
20
+ splineCurvature: number;
21
+ targetOffset: Vec3;
22
+ bindingMode: BindingMode;
23
+ damping: DampingConstant;
24
+ rotationDamping: DampingConstant;
25
+ maxSpeed: number;
26
+ recenteringTarget: RecenteringTarget;
27
+ readonly state: orbitFollow.OrbitFollowState;
28
+ readonly horizontal: import("../index.js").InputAxis;
29
+ readonly vertical: import("../index.js").InputAxis;
30
+ readonly radial: import("../index.js").InputAxis;
31
+ readonly inputAxes: {
32
+ horizontal: import("../index.js").InputAxis;
33
+ vertical: import("../index.js").InputAxis;
34
+ radial: import("../index.js").InputAxis;
35
+ };
36
+ private lastTarget;
37
+ constructor(target: T, options?: OrbitFollowOptions);
38
+ update: (out: CameraState, dt: number, justActivated: boolean) => boolean;
39
+ /** Start from `position`'s direction around the target, keeping the zoom. */
40
+ primeFrom: (position: Vec3) => void;
41
+ /** Eases the camera toward `position`'s direction around the target, keeping the zoom. */
42
+ setFromPosition: (position: Vec3) => void;
43
+ /** Eases the camera around the target until it looks along `rotation`'s forward, keeping the zoom. */
44
+ setFromRotation: (rotation: Quat) => void;
45
+ /** This frame's target pose, or `null` when there is none. */
46
+ protected readTarget(): TargetPose | null;
47
+ }
@@ -0,0 +1,48 @@
1
+ import { createParams, createState, prime, setFromPosition, setFromRotation, update } from "./orbitFollow.js";
2
+ //#region src/core/body/OrbitFollowBody.ts
3
+ /**
4
+ * Orbits a target on a sphere or through three rings, driven by three `InputAxis`: `horizontal`, `vertical` and `radial`.
5
+ * Layers override `readTarget`.
6
+ */
7
+ var OrbitFollowBody = class {
8
+ target;
9
+ state = createState();
10
+ horizontal = this.state.horizontal;
11
+ vertical = this.state.vertical;
12
+ radial = this.state.radial;
13
+ inputAxes = {
14
+ horizontal: this.horizontal,
15
+ vertical: this.vertical,
16
+ radial: this.radial
17
+ };
18
+ lastTarget = void 0;
19
+ constructor(target, options) {
20
+ this.target = target;
21
+ Object.assign(this, createParams(options));
22
+ }
23
+ update = (out, dt, justActivated) => {
24
+ if (justActivated || this.target !== this.lastTarget) {
25
+ this.lastTarget = this.target;
26
+ this.state.tracker.assigned = false;
27
+ }
28
+ return update(out, this.state, this, this.readTarget(), dt, justActivated);
29
+ };
30
+ /** Start from `position`'s direction around the target, keeping the zoom. */
31
+ primeFrom = (position) => prime(this.state, position);
32
+ /** Eases the camera toward `position`'s direction around the target, keeping the zoom. */
33
+ setFromPosition = (position) => {
34
+ const pose = this.readTarget();
35
+ if (pose) setFromPosition(this.state, this, pose, position);
36
+ };
37
+ /** Eases the camera around the target until it looks along `rotation`'s forward, keeping the zoom. */
38
+ setFromRotation = (rotation) => {
39
+ const pose = this.readTarget();
40
+ if (pose) setFromRotation(this.state, this, pose, rotation);
41
+ };
42
+ /** This frame's target pose, or `null` when there is none. */
43
+ readTarget() {
44
+ return this.target;
45
+ }
46
+ };
47
+ //#endregion
48
+ export { OrbitFollowBody };