@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.
- package/LICENSE +21 -0
- package/README.md +72 -2
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/core/CameraState.d.ts +32 -0
- package/dist/core/CameraState.js +97 -0
- package/dist/core/EventDispatcher.d.ts +18 -0
- package/dist/core/EventDispatcher.js +28 -0
- package/dist/core/Klipp.d.ts +109 -0
- package/dist/core/Klipp.js +253 -0
- package/dist/core/TargetExtent.d.ts +11 -0
- package/dist/core/TargetExtent.js +54 -0
- package/dist/core/TargetPose.d.ts +13 -0
- package/dist/core/TargetPose.js +21 -0
- package/dist/core/VirtualCamera.d.ts +102 -0
- package/dist/core/VirtualCamera.js +290 -0
- package/dist/core/aim/HardLookAtAim.d.ts +10 -0
- package/dist/core/aim/HardLookAtAim.js +19 -0
- package/dist/core/aim/PanTiltAim.d.ts +26 -0
- package/dist/core/aim/PanTiltAim.js +38 -0
- package/dist/core/aim/RotateWithFollowTargetAim.d.ts +19 -0
- package/dist/core/aim/RotateWithFollowTargetAim.js +23 -0
- package/dist/core/aim/RotationComposerAim.d.ts +27 -0
- package/dist/core/aim/RotationComposerAim.js +27 -0
- package/dist/core/aim/hardLookAt.d.ts +4 -0
- package/dist/core/aim/hardLookAt.js +13 -0
- package/dist/core/aim/index.d.ts +11 -0
- package/dist/core/aim/lookRotation.d.ts +6 -0
- package/dist/core/aim/lookRotation.js +46 -0
- package/dist/core/aim/panTilt.d.ts +16 -0
- package/dist/core/aim/panTilt.js +121 -0
- package/dist/core/aim/rotateWithFollowTarget.d.ts +20 -0
- package/dist/core/aim/rotateWithFollowTarget.js +35 -0
- package/dist/core/aim/rotationComposer.d.ts +58 -0
- package/dist/core/aim/rotationComposer.js +284 -0
- package/dist/core/blend/BlendCurves.d.ts +19 -0
- package/dist/core/blend/BlendCurves.js +22 -0
- package/dist/core/blend/BlendDefinition.d.ts +21 -0
- package/dist/core/blend/BlendDefinition.js +9 -0
- package/dist/core/blend/BlendDriver.d.ts +23 -0
- package/dist/core/blend/BlendDriver.js +42 -0
- package/dist/core/blend/BlendHints.d.ts +9 -0
- package/dist/core/blend/BlendHints.js +13 -0
- package/dist/core/blend/blend.d.ts +41 -0
- package/dist/core/blend/blend.js +110 -0
- package/dist/core/blend/index.d.ts +6 -0
- package/dist/core/blend/lerpCameraState.d.ts +4 -0
- package/dist/core/blend/lerpCameraState.js +143 -0
- package/dist/core/body/BindingModes.d.ts +9 -0
- package/dist/core/body/BindingModes.js +11 -0
- package/dist/core/body/FollowBody.d.ts +24 -0
- package/dist/core/body/FollowBody.js +26 -0
- package/dist/core/body/HardLockToTargetBody.d.ts +17 -0
- package/dist/core/body/HardLockToTargetBody.js +20 -0
- package/dist/core/body/OrbitFollowBody.d.ts +47 -0
- package/dist/core/body/OrbitFollowBody.js +48 -0
- package/dist/core/body/PositionComposerBody.d.ts +28 -0
- package/dist/core/body/PositionComposerBody.js +27 -0
- package/dist/core/body/follow.d.ts +33 -0
- package/dist/core/body/follow.js +83 -0
- package/dist/core/body/hardLockToTarget.d.ts +17 -0
- package/dist/core/body/hardLockToTarget.js +26 -0
- package/dist/core/body/index.d.ts +17 -0
- package/dist/core/body/orbitFollow.d.ts +76 -0
- package/dist/core/body/orbitFollow.js +336 -0
- package/dist/core/body/positionComposer.d.ts +56 -0
- package/dist/core/body/positionComposer.js +207 -0
- package/dist/core/body/safeFromToRotation.d.ts +3 -0
- package/dist/core/body/safeFromToRotation.js +39 -0
- package/dist/core/body/threeRing.d.ts +28 -0
- package/dist/core/body/threeRing.js +100 -0
- package/dist/core/body/tracker.d.ts +42 -0
- package/dist/core/body/tracker.js +193 -0
- package/dist/core/damping/Damper.d.ts +11 -0
- package/dist/core/damping/Damper.js +22 -0
- package/dist/core/damping/damping.d.ts +30 -0
- package/dist/core/damping/damping.js +119 -0
- package/dist/core/damping/index.d.ts +5 -0
- package/dist/core/damping/predictor.d.ts +16 -0
- package/dist/core/damping/predictor.js +56 -0
- package/dist/core/debug/debugZones.d.ts +16 -0
- package/dist/core/debug/debugZones.js +38 -0
- package/dist/core/debug/index.d.ts +2 -0
- package/dist/core/extension/GroupFramingExtension.d.ts +26 -0
- package/dist/core/extension/GroupFramingExtension.js +24 -0
- package/dist/core/extension/LensExtension.d.ts +20 -0
- package/dist/core/extension/LensExtension.js +12 -0
- package/dist/core/extension/groupFraming.d.ts +62 -0
- package/dist/core/extension/groupFraming.js +271 -0
- package/dist/core/extension/index.d.ts +6 -0
- package/dist/core/extension/lens.d.ts +35 -0
- package/dist/core/extension/lens.js +57 -0
- package/dist/core/groups/ClearShot.d.ts +32 -0
- package/dist/core/groups/MixingCamera.d.ts +20 -0
- package/dist/core/groups/Sequencer.d.ts +24 -0
- package/dist/core/groups/StateDrivenCamera.d.ts +26 -0
- package/dist/core/groups/clearShotState.d.ts +32 -0
- package/dist/core/groups/index.d.ts +11 -0
- package/dist/core/groups/mixCameraStates.d.ts +13 -0
- package/dist/core/groups/sequencerState.d.ts +26 -0
- package/dist/core/groups/stateDrivenState.d.ts +28 -0
- package/dist/core/impulse/ImpulseField.d.ts +15 -0
- package/dist/core/impulse/ImpulseField.js +22 -0
- package/dist/core/impulse/ImpulseListenerNoise.d.ts +19 -0
- package/dist/core/impulse/ImpulseListenerNoise.js +29 -0
- package/dist/core/impulse/impulseListener.d.ts +13 -0
- package/dist/core/impulse/impulseListener.js +14 -0
- package/dist/core/impulse/impulses.d.ts +54 -0
- package/dist/core/impulse/impulses.js +84 -0
- package/dist/core/impulse/index.d.ts +6 -0
- package/dist/core/index.d.ts +20 -0
- package/dist/core/index.js +52 -0
- package/dist/core/input/InputAxis.d.ts +29 -0
- package/dist/core/input/InputAxis.js +28 -0
- package/dist/core/input/InputAxisOwner.d.ts +6 -0
- package/dist/core/input/InputAxisOwner.js +4 -0
- package/dist/core/input/InputController.d.ts +15 -0
- package/dist/core/input/InputController.js +24 -0
- package/dist/core/input/axis.d.ts +52 -0
- package/dist/core/input/axis.js +89 -0
- package/dist/core/input/consumedInput.d.ts +37 -0
- package/dist/core/input/consumedInput.js +34 -0
- package/dist/core/input/index.d.ts +9 -0
- package/dist/core/input/inputMapping.d.ts +46 -0
- package/dist/core/input/inputMapping.js +55 -0
- package/dist/core/input/shortestWrappedDelta.d.ts +2 -0
- package/dist/core/input/shortestWrappedDelta.js +11 -0
- package/dist/core/internal.d.ts +16 -0
- package/dist/core/internal.js +19 -0
- package/dist/core/klippState.d.ts +78 -0
- package/dist/core/klippState.js +124 -0
- package/dist/core/noise/BasicMultiChannelPerlinNoise.d.ts +21 -0
- package/dist/core/noise/BasicMultiChannelPerlinNoise.js +13 -0
- package/dist/core/noise/index.d.ts +3 -0
- package/dist/core/noise/perlinNoise.d.ts +36 -0
- package/dist/core/noise/perlinNoise.js +110 -0
- package/dist/core/params.d.ts +2 -0
- package/dist/core/params.js +12 -0
- package/dist/dom/DebugOverlay.d.ts +11 -0
- package/dist/dom/DebugOverlay.js +96 -0
- package/dist/dom/InputControllerDom.d.ts +15 -0
- package/dist/dom/InputControllerDom.js +31 -0
- package/dist/dom/InputSystem.d.ts +40 -0
- package/dist/dom/InputSystem.js +113 -0
- package/dist/dom/index.d.ts +3 -0
- package/dist/dom/index.js +5 -0
- package/dist/input-sources/buttonInput.d.ts +15 -0
- package/dist/input-sources/buttonInput.js +23 -0
- package/dist/input-sources/isInsideInteractiveArea.d.ts +9 -0
- package/dist/input-sources/isInsideInteractiveArea.js +11 -0
- package/dist/input-sources/mouse.d.ts +47 -0
- package/dist/input-sources/mouse.js +171 -0
- package/dist/input-sources/safariGesture.d.ts +32 -0
- package/dist/input-sources/safariGesture.js +107 -0
- package/dist/input-sources/suppressNativeGestures.d.ts +5 -0
- package/dist/input-sources/suppressNativeGestures.js +32 -0
- package/dist/input-sources/touch.d.ts +47 -0
- package/dist/input-sources/touch.js +173 -0
- package/dist/input-sources/wheel.d.ts +28 -0
- package/dist/input-sources/wheel.js +44 -0
- package/dist/react/CameraFrustumHelper.d.ts +13 -0
- package/dist/react/CameraFrustumHelper.js +32 -0
- package/dist/react/DebugZoneOverlay.d.ts +7 -0
- package/dist/react/DebugZoneOverlay.js +23 -0
- package/dist/react/Klipp.d.ts +20 -0
- package/dist/react/Klipp.js +47 -0
- package/dist/react/KlippContext.d.ts +5 -0
- package/dist/react/KlippContext.js +11 -0
- package/dist/react/VirtualCamera.d.ts +28 -0
- package/dist/react/VirtualCamera.js +81 -0
- package/dist/react/VirtualCameraContext.d.ts +11 -0
- package/dist/react/VirtualCameraContext.js +21 -0
- package/dist/react/aim/Aim.d.ts +11 -0
- package/dist/react/aim/Aim.js +14 -0
- package/dist/react/aim/HardLookAt.d.ts +10 -0
- package/dist/react/aim/HardLookAt.js +15 -0
- package/dist/react/aim/PanTilt.d.ts +31 -0
- package/dist/react/aim/PanTilt.js +38 -0
- package/dist/react/aim/RotateWithFollowTarget.d.ts +10 -0
- package/dist/react/aim/RotateWithFollowTarget.js +18 -0
- package/dist/react/aim/RotationComposer.d.ts +12 -0
- package/dist/react/aim/RotationComposer.js +34 -0
- package/dist/react/body/Body.d.ts +11 -0
- package/dist/react/body/Body.js +14 -0
- package/dist/react/body/CameraControls.d.ts +50 -0
- package/dist/react/body/CameraControls.js +106 -0
- package/dist/react/body/Follow.d.ts +10 -0
- package/dist/react/body/Follow.js +20 -0
- package/dist/react/body/HardLockToTarget.d.ts +10 -0
- package/dist/react/body/HardLockToTarget.js +18 -0
- package/dist/react/body/OrbitFollow.d.ts +25 -0
- package/dist/react/body/OrbitFollow.js +67 -0
- package/dist/react/body/PositionComposer.d.ts +12 -0
- package/dist/react/body/PositionComposer.js +32 -0
- package/dist/react/body/camera-controls.d.ts +2 -0
- package/dist/react/body/camera-controls.js +3 -0
- package/dist/react/extension/Extension.d.ts +7 -0
- package/dist/react/extension/Extension.js +10 -0
- package/dist/react/extension/GroupFraming.d.ts +14 -0
- package/dist/react/extension/GroupFraming.js +52 -0
- package/dist/react/extension/Lens.d.ts +7 -0
- package/dist/react/extension/Lens.js +31 -0
- package/dist/react/impulse/ImpulseListener.d.ts +12 -0
- package/dist/react/impulse/ImpulseListener.js +33 -0
- package/dist/react/index.d.ts +24 -0
- package/dist/react/index.js +24 -0
- package/dist/react/input/InputAxisOwnerContext.d.ts +3 -0
- package/dist/react/input/InputAxisOwnerContext.js +6 -0
- package/dist/react/input/InputController.d.ts +53 -0
- package/dist/react/input/InputController.js +115 -0
- package/dist/react/noise/BasicMultiChannelPerlin.d.ts +7 -0
- package/dist/react/noise/BasicMultiChannelPerlin.js +14 -0
- package/dist/react/noise/Noise.d.ts +5 -0
- package/dist/react/noise/Noise.js +6 -0
- package/dist/react/noise/useBasicMultiChannelPerlinNoise.d.ts +4 -0
- package/dist/react/noise/useBasicMultiChannelPerlinNoise.js +21 -0
- package/dist/react/useCameraTransitionEvent.d.ts +12 -0
- package/dist/react/useCameraTransitionEvent.js +14 -0
- package/dist/three/CameraFrustumHelperThree.d.ts +11 -0
- package/dist/three/CameraFrustumHelperThree.js +44 -0
- package/dist/three/KlippThree.d.ts +18 -0
- package/dist/three/KlippThree.js +50 -0
- package/dist/three/VirtualCameraThree.d.ts +35 -0
- package/dist/three/VirtualCameraThree.js +108 -0
- package/dist/three/aim/HardLookAtAimThree.d.ts +10 -0
- package/dist/three/aim/HardLookAtAimThree.js +14 -0
- package/dist/three/aim/PanTiltAimThree.d.ts +10 -0
- package/dist/three/aim/PanTiltAimThree.js +15 -0
- package/dist/three/aim/RotateWithFollowTargetAimThree.d.ts +11 -0
- package/dist/three/aim/RotateWithFollowTargetAimThree.js +15 -0
- package/dist/three/aim/RotationComposerAimThree.d.ts +26 -0
- package/dist/three/aim/RotationComposerAimThree.js +35 -0
- package/dist/three/body/CameraControlsBodyThree.d.ts +30 -0
- package/dist/three/body/CameraControlsBodyThree.js +54 -0
- package/dist/three/body/FollowBodyThree.d.ts +16 -0
- package/dist/three/body/FollowBodyThree.js +23 -0
- package/dist/three/body/HardLockToTargetBodyThree.d.ts +11 -0
- package/dist/three/body/HardLockToTargetBodyThree.js +14 -0
- package/dist/three/body/OrbitFollowBodyThree.d.ts +16 -0
- package/dist/three/body/OrbitFollowBodyThree.js +23 -0
- package/dist/three/body/OrbitFollowHelperThree.d.ts +23 -0
- package/dist/three/body/OrbitFollowHelperThree.js +85 -0
- package/dist/three/body/PositionComposerBodyThree.d.ts +24 -0
- package/dist/three/body/PositionComposerBodyThree.js +31 -0
- package/dist/three/camera.d.ts +10 -0
- package/dist/three/camera.js +39 -0
- package/dist/three/damping/Predictor.d.ts +12 -0
- package/dist/three/damping/Predictor.js +30 -0
- package/dist/three/damping/QuaternionDamper.d.ts +10 -0
- package/dist/three/damping/QuaternionDamper.js +28 -0
- package/dist/three/damping/Vector3Damper.d.ts +10 -0
- package/dist/three/damping/Vector3Damper.js +26 -0
- package/dist/three/extension/GroupFramingExtensionThree.d.ts +13 -0
- package/dist/three/extension/GroupFramingExtensionThree.js +23 -0
- package/dist/three/extension/TargetGroup.d.ts +32 -0
- package/dist/three/extension/TargetGroup.js +53 -0
- package/dist/three/index.d.ts +24 -0
- package/dist/three/index.js +25 -0
- package/dist/three/noise/BasicMultiChannelPerlinNoiseThree.d.ts +16 -0
- package/dist/three/noise/BasicMultiChannelPerlinNoiseThree.js +17 -0
- package/dist/three/readTargetExtent.d.ts +9 -0
- package/dist/three/readTargetExtent.js +25 -0
- package/dist/three/readTargetPose.d.ts +8 -0
- package/dist/three/readTargetPose.js +21 -0
- package/dist/three/resolve/Target.d.ts +17 -0
- package/dist/three/resolve/Target.js +62 -0
- package/dist/three/resolve/TargetRegistry.d.ts +27 -0
- package/dist/three/resolve/TargetRegistry.js +78 -0
- package/dist/three/resolve/resolveVector3.d.ts +12 -0
- package/dist/three/resolve/resolveVector3.js +29 -0
- package/package.json +120 -4
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createParams } from "../../core/extension/lens.js";
|
|
2
|
+
import { LensExtension } from "../../core/extension/LensExtension.js";
|
|
3
|
+
import { useVirtualCamera } from "../VirtualCameraContext.js";
|
|
4
|
+
import { useThree } from "@react-three/fiber";
|
|
5
|
+
import { useEffect, useImperativeHandle, useState } from "react";
|
|
6
|
+
//#region src/react/extension/Lens.tsx
|
|
7
|
+
/** Animates the camera lens without forcing a React re-render. */
|
|
8
|
+
function Lens({ ref, ...settings }) {
|
|
9
|
+
const camera = useVirtualCamera();
|
|
10
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
11
|
+
const params = createParams(settings);
|
|
12
|
+
const [extension] = useState(() => new LensExtension(params));
|
|
13
|
+
Object.assign(extension, params);
|
|
14
|
+
useImperativeHandle(ref, () => extension, [extension]);
|
|
15
|
+
useEffect(() => camera.addExtension(extension), [camera, extension]);
|
|
16
|
+
const { fov, near, far, fovDamping, nearDamping, farDamping } = params;
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
invalidate();
|
|
19
|
+
}, [
|
|
20
|
+
fov,
|
|
21
|
+
near,
|
|
22
|
+
far,
|
|
23
|
+
fovDamping,
|
|
24
|
+
nearDamping,
|
|
25
|
+
farDamping,
|
|
26
|
+
invalidate
|
|
27
|
+
]);
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { Lens };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Ref } from 'react';
|
|
2
|
+
import { ImpulseListenerNoise, type ImpulseListenerOptions } from '../../core/impulse/ImpulseListenerNoise.js';
|
|
3
|
+
import type { BasicMultiChannelPerlinProps } from '../noise/BasicMultiChannelPerlin.js';
|
|
4
|
+
/** Perlin shake options driven by the current impulse strength. */
|
|
5
|
+
export type ImpulseShakeProps = Omit<BasicMultiChannelPerlinProps, 'amplitudeGain' | 'ref'>;
|
|
6
|
+
export type ImpulseListenerProps = Omit<ImpulseListenerOptions, 'shake'> & {
|
|
7
|
+
/** Optional Perlin shake driven by the impulse strength. */
|
|
8
|
+
shake?: ImpulseShakeProps;
|
|
9
|
+
ref?: Ref<ImpulseListenerNoise>;
|
|
10
|
+
};
|
|
11
|
+
/** Adds impulse-driven camera shake and kick. */
|
|
12
|
+
export declare function ImpulseListener({ shake, ref, ...settings }: ImpulseListenerProps): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createParams } from "../../core/impulse/impulseListener.js";
|
|
2
|
+
import { ImpulseListenerNoise } from "../../core/impulse/ImpulseListenerNoise.js";
|
|
3
|
+
import { useVirtualCamera } from "../VirtualCameraContext.js";
|
|
4
|
+
import { useBasicMultiChannelPerlinNoise } from "../noise/useBasicMultiChannelPerlinNoise.js";
|
|
5
|
+
import { useEffect, useImperativeHandle, useState } from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
//#region src/react/impulse/ImpulseListener.tsx
|
|
8
|
+
/** Adds impulse-driven camera shake and kick. */
|
|
9
|
+
function ImpulseListener({ shake, ref, ...settings }) {
|
|
10
|
+
const camera = useVirtualCamera();
|
|
11
|
+
const params = createParams(settings);
|
|
12
|
+
const [listener] = useState(() => new ImpulseListenerNoise(params));
|
|
13
|
+
Object.assign(listener, params);
|
|
14
|
+
useImperativeHandle(ref, () => listener, [listener]);
|
|
15
|
+
useEffect(() => camera.addNoise(listener), [camera, listener]);
|
|
16
|
+
return shake ? /* @__PURE__ */ jsx(ImpulseListenerShake, {
|
|
17
|
+
listener,
|
|
18
|
+
...shake
|
|
19
|
+
}) : null;
|
|
20
|
+
}
|
|
21
|
+
/** Mounts the optional Perlin shake. */
|
|
22
|
+
function ImpulseListenerShake({ listener, ...props }) {
|
|
23
|
+
const shakeNoise = useBasicMultiChannelPerlinNoise(props);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
listener.shake = shakeNoise;
|
|
26
|
+
return () => {
|
|
27
|
+
listener.shake = void 0;
|
|
28
|
+
};
|
|
29
|
+
}, [listener, shakeNoise]);
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
//#endregion
|
|
33
|
+
export { ImpulseListener };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export { CameraFrustumHelper, type CameraFrustumHelperProps } from './CameraFrustumHelper.js';
|
|
2
|
+
export { Klipp, KlippEvents, type KlippEventsProps, type KlippMode, type KlippProps } from './Klipp.js';
|
|
3
|
+
export { useKlipp, type FrameUpdate } from './KlippContext.js';
|
|
4
|
+
export { VirtualCamera, VirtualCameraEvents, type VirtualCameraEventsProps, type VirtualCameraProps, } from './VirtualCamera.js';
|
|
5
|
+
export { useIsActiveVirtualCamera, useIsLiveVirtualCamera, useVirtualCamera } from './VirtualCameraContext.js';
|
|
6
|
+
export type { InputAxisOwner } from '../core/input/InputAxisOwner.js';
|
|
7
|
+
export { InputAxisOwnerContext } from './input/InputAxisOwnerContext.js';
|
|
8
|
+
export { InputController, type InputAxisSourceConfig, type InputControllerProps, type InputSourceConfig, } from './input/InputController.js';
|
|
9
|
+
export { Body } from './body/Body.js';
|
|
10
|
+
export { Follow, type FollowProps } from './body/Follow.js';
|
|
11
|
+
export { HardLockToTarget, type HardLockToTargetProps } from './body/HardLockToTarget.js';
|
|
12
|
+
export { OrbitFollow, type OrbitFollowAxisSettings, type OrbitFollowProps } from './body/OrbitFollow.js';
|
|
13
|
+
export { PositionComposer, type PositionComposerProps } from './body/PositionComposer.js';
|
|
14
|
+
export { Aim } from './aim/Aim.js';
|
|
15
|
+
export { HardLookAt, type HardLookAtProps } from './aim/HardLookAt.js';
|
|
16
|
+
export { PanTilt, type PanTiltProps } from './aim/PanTilt.js';
|
|
17
|
+
export { RotateWithFollowTarget, type RotateWithFollowTargetProps } from './aim/RotateWithFollowTarget.js';
|
|
18
|
+
export { RotationComposer, type RotationComposerProps } from './aim/RotationComposer.js';
|
|
19
|
+
export { BasicMultiChannelPerlin, type BasicMultiChannelPerlinProps } from './noise/BasicMultiChannelPerlin.js';
|
|
20
|
+
export { Noise } from './noise/Noise.js';
|
|
21
|
+
export { ImpulseListener, type ImpulseListenerProps, type ImpulseShakeProps } from './impulse/ImpulseListener.js';
|
|
22
|
+
export { Extension } from './extension/Extension.js';
|
|
23
|
+
export { GroupFraming, type GroupFramingProps } from './extension/GroupFraming.js';
|
|
24
|
+
export { Lens, type LensProps } from './extension/Lens.js';
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { useIsActiveVirtualCamera, useIsLiveVirtualCamera, useVirtualCamera } from "./VirtualCameraContext.js";
|
|
2
|
+
import { CameraFrustumHelper } from "./CameraFrustumHelper.js";
|
|
3
|
+
import { useKlipp } from "./KlippContext.js";
|
|
4
|
+
import { Klipp, KlippEvents } from "./Klipp.js";
|
|
5
|
+
import { VirtualCamera, VirtualCameraEvents } from "./VirtualCamera.js";
|
|
6
|
+
import { InputAxisOwnerContext } from "./input/InputAxisOwnerContext.js";
|
|
7
|
+
import { InputController } from "./input/InputController.js";
|
|
8
|
+
import { Follow } from "./body/Follow.js";
|
|
9
|
+
import { HardLockToTarget } from "./body/HardLockToTarget.js";
|
|
10
|
+
import { OrbitFollow } from "./body/OrbitFollow.js";
|
|
11
|
+
import { PositionComposer } from "./body/PositionComposer.js";
|
|
12
|
+
import { Body } from "./body/Body.js";
|
|
13
|
+
import { HardLookAt } from "./aim/HardLookAt.js";
|
|
14
|
+
import { PanTilt } from "./aim/PanTilt.js";
|
|
15
|
+
import { RotateWithFollowTarget } from "./aim/RotateWithFollowTarget.js";
|
|
16
|
+
import { RotationComposer } from "./aim/RotationComposer.js";
|
|
17
|
+
import { Aim } from "./aim/Aim.js";
|
|
18
|
+
import { BasicMultiChannelPerlin } from "./noise/BasicMultiChannelPerlin.js";
|
|
19
|
+
import { Noise } from "./noise/Noise.js";
|
|
20
|
+
import { ImpulseListener } from "./impulse/ImpulseListener.js";
|
|
21
|
+
import { GroupFraming } from "./extension/GroupFraming.js";
|
|
22
|
+
import { Lens } from "./extension/Lens.js";
|
|
23
|
+
import { Extension } from "./extension/Extension.js";
|
|
24
|
+
export { Aim, BasicMultiChannelPerlin, Body, CameraFrustumHelper, Extension, Follow, GroupFraming, HardLockToTarget, HardLookAt, ImpulseListener, InputAxisOwnerContext, InputController, Klipp, KlippEvents, Lens, Noise, OrbitFollow, PanTilt, PositionComposer, RotateWithFollowTarget, RotationComposer, VirtualCamera, VirtualCameraEvents, useIsActiveVirtualCamera, useIsLiveVirtualCamera, useKlipp, useVirtualCamera };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { InputAxisOwner } from '../../core/input/InputAxisOwner.js';
|
|
2
|
+
/** Set by a Body/Aim/Extension around its `children`, so a nested `<InputController>` finds its `inputAxes`. */
|
|
3
|
+
export declare const InputAxisOwnerContext: import("react").Context<InputAxisOwner | null>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { createContext } from "react";
|
|
2
|
+
//#region src/react/input/InputAxisOwnerContext.ts
|
|
3
|
+
/** Set by a Body/Aim/Extension around its `children`, so a nested `<InputController>` finds its `inputAxes`. */
|
|
4
|
+
var InputAxisOwnerContext = createContext(null);
|
|
5
|
+
//#endregion
|
|
6
|
+
export { InputAxisOwnerContext };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type Ref, type RefObject } from 'react';
|
|
2
|
+
import type { InputAxisOwner } from '../../core/input/InputAxisOwner.js';
|
|
3
|
+
import type { InputInvert } from '../../core/input/inputMapping.js';
|
|
4
|
+
import { InputControllerDom } from '../../dom/InputControllerDom.js';
|
|
5
|
+
import type { InteractiveArea } from '../../dom/InputSystem.js';
|
|
6
|
+
export type InputSourceConfig = {
|
|
7
|
+
/** Axis names to drive for each source. */
|
|
8
|
+
axes: {
|
|
9
|
+
x: string;
|
|
10
|
+
y: string;
|
|
11
|
+
};
|
|
12
|
+
/** Multiplies the raw delta before it reaches the axes. */
|
|
13
|
+
gain?: number;
|
|
14
|
+
invert?: InputInvert;
|
|
15
|
+
};
|
|
16
|
+
export type InputAxisSourceConfig = {
|
|
17
|
+
/** Axis name to drive. */
|
|
18
|
+
axis: string;
|
|
19
|
+
/** Multiplies the raw delta before it reaches the axis. */
|
|
20
|
+
gain?: number;
|
|
21
|
+
invert?: boolean;
|
|
22
|
+
};
|
|
23
|
+
export type InputControllerProps = {
|
|
24
|
+
/** Axis owner to drive. Uses the nearest owner context when omitted, or else the virtual camera itself. */
|
|
25
|
+
target?: RefObject<InputAxisOwner | null>;
|
|
26
|
+
mouseButtons?: {
|
|
27
|
+
left?: InputSourceConfig | null;
|
|
28
|
+
right?: InputSourceConfig | null;
|
|
29
|
+
middle?: InputSourceConfig | null;
|
|
30
|
+
};
|
|
31
|
+
touches?: {
|
|
32
|
+
one?: InputSourceConfig | null;
|
|
33
|
+
two?: InputSourceConfig | null;
|
|
34
|
+
three?: InputSourceConfig | null;
|
|
35
|
+
};
|
|
36
|
+
/** Vertical wheel scrolling, in pixels. Scrolling up is positive, like spreading a pinch. */
|
|
37
|
+
wheel?: InputAxisSourceConfig | null;
|
|
38
|
+
/** Pinch with two fingers or on a trackpad, as the change in `ln(scale)`. Spreading is positive. */
|
|
39
|
+
pinch?: InputAxisSourceConfig | null;
|
|
40
|
+
/** Wait until this camera is live before listening to input. */
|
|
41
|
+
waitForBlend?: boolean;
|
|
42
|
+
/** Whether input reaches the axes. Unmount the component to stop listening altogether. */
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
/** Suppresses the native right-click context menu. */
|
|
45
|
+
suppressContextMenu?: boolean;
|
|
46
|
+
/** Restricts drag/wheel start to a normalized rect of the element's bounds. */
|
|
47
|
+
interactiveArea?: InteractiveArea | null;
|
|
48
|
+
/** Lock diagonal two-finger input to pinch or rotation. */
|
|
49
|
+
lockTouchAxis?: boolean;
|
|
50
|
+
ref?: Ref<InputControllerDom>;
|
|
51
|
+
};
|
|
52
|
+
/** Connects DOM input sources to named axes on a camera component. */
|
|
53
|
+
export declare function InputController(props: InputControllerProps): null;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { useIsActiveVirtualCamera, useIsLiveVirtualCamera, useVirtualCamera } from "../VirtualCameraContext.js";
|
|
2
|
+
import { useKlipp } from "../KlippContext.js";
|
|
3
|
+
import { InputAxisOwnerContext } from "./InputAxisOwnerContext.js";
|
|
4
|
+
import { InputControllerDom } from "../../dom/InputControllerDom.js";
|
|
5
|
+
import { useThree } from "@react-three/fiber";
|
|
6
|
+
import { use, useEffect, useImperativeHandle, useState } from "react";
|
|
7
|
+
//#region src/react/input/InputController.tsx
|
|
8
|
+
function resolveAxis(owner, name) {
|
|
9
|
+
const axis = owner.inputAxes[name];
|
|
10
|
+
if (!axis) {
|
|
11
|
+
console.warn(`<InputController>: no axis named "${name}" on target's inputAxes.`);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
return axis;
|
|
15
|
+
}
|
|
16
|
+
function resolveSource(owner, source) {
|
|
17
|
+
if (!source) return null;
|
|
18
|
+
const x = resolveAxis(owner, source.axes.x);
|
|
19
|
+
const y = resolveAxis(owner, source.axes.y);
|
|
20
|
+
if (!x || !y) return null;
|
|
21
|
+
return {
|
|
22
|
+
axes: {
|
|
23
|
+
x,
|
|
24
|
+
y
|
|
25
|
+
},
|
|
26
|
+
gain: source.gain,
|
|
27
|
+
invert: source.invert
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function resolveAxisSource(owner, source) {
|
|
31
|
+
if (!source) return null;
|
|
32
|
+
const axis = resolveAxis(owner, source.axis);
|
|
33
|
+
return axis && {
|
|
34
|
+
axis,
|
|
35
|
+
gain: source.gain,
|
|
36
|
+
invert: source.invert
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function buildConfig(owner, props) {
|
|
40
|
+
return {
|
|
41
|
+
mouseButtons: {
|
|
42
|
+
left: resolveSource(owner, props.mouseButtons?.left),
|
|
43
|
+
right: resolveSource(owner, props.mouseButtons?.right),
|
|
44
|
+
middle: resolveSource(owner, props.mouseButtons?.middle)
|
|
45
|
+
},
|
|
46
|
+
touches: {
|
|
47
|
+
one: resolveSource(owner, props.touches?.one),
|
|
48
|
+
two: resolveSource(owner, props.touches?.two),
|
|
49
|
+
three: resolveSource(owner, props.touches?.three)
|
|
50
|
+
},
|
|
51
|
+
wheel: resolveAxisSource(owner, props.wheel),
|
|
52
|
+
pinch: resolveAxisSource(owner, props.pinch)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/** Connects DOM input sources to named axes on a camera component. */
|
|
56
|
+
function InputController(props) {
|
|
57
|
+
const { waitForBlend = true, enabled = true, suppressContextMenu = false, interactiveArea = null, lockTouchAxis = false, ref } = props;
|
|
58
|
+
const contextOwner = use(InputAxisOwnerContext);
|
|
59
|
+
const camera = useVirtualCamera();
|
|
60
|
+
const klipp = useKlipp();
|
|
61
|
+
const isActive = useIsActiveVirtualCamera();
|
|
62
|
+
const isLive = useIsLiveVirtualCamera();
|
|
63
|
+
const shouldConnect = isActive && (waitForBlend ? isLive : true);
|
|
64
|
+
const domElement = useThree((state) => state.gl.domElement);
|
|
65
|
+
const invalidate = useThree((state) => state.invalidate);
|
|
66
|
+
const [controller] = useState(() => new InputControllerDom({}));
|
|
67
|
+
const [binding] = useState(() => ({
|
|
68
|
+
props,
|
|
69
|
+
contextOwner,
|
|
70
|
+
owner: null,
|
|
71
|
+
axes: null,
|
|
72
|
+
stale: true
|
|
73
|
+
}));
|
|
74
|
+
useImperativeHandle(ref, () => controller, [controller]);
|
|
75
|
+
controller.enabled = enabled;
|
|
76
|
+
controller.inputSystem.suppressContextMenu = suppressContextMenu;
|
|
77
|
+
controller.inputSystem.interactiveArea = interactiveArea;
|
|
78
|
+
controller.inputSystem.lockTouchAxis = lockTouchAxis;
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
binding.props = props;
|
|
81
|
+
binding.contextOwner = contextOwner;
|
|
82
|
+
binding.stale = true;
|
|
83
|
+
});
|
|
84
|
+
useEffect(() => klipp.registerUpdate(() => {
|
|
85
|
+
const owner = binding.props.target?.current ?? binding.contextOwner ?? camera;
|
|
86
|
+
if (binding.stale || owner !== binding.owner || owner.inputAxes !== binding.axes) {
|
|
87
|
+
controller.config = buildConfig(owner, binding.props);
|
|
88
|
+
binding.owner = owner;
|
|
89
|
+
binding.axes = owner.inputAxes;
|
|
90
|
+
binding.stale = false;
|
|
91
|
+
}
|
|
92
|
+
controller.update();
|
|
93
|
+
}), [
|
|
94
|
+
klipp,
|
|
95
|
+
controller,
|
|
96
|
+
binding,
|
|
97
|
+
camera
|
|
98
|
+
]);
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (!shouldConnect) return;
|
|
101
|
+
controller.connect(domElement, () => invalidate());
|
|
102
|
+
return () => {
|
|
103
|
+
controller.disconnect();
|
|
104
|
+
invalidate();
|
|
105
|
+
};
|
|
106
|
+
}, [
|
|
107
|
+
controller,
|
|
108
|
+
domElement,
|
|
109
|
+
shouldConnect,
|
|
110
|
+
invalidate
|
|
111
|
+
]);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
export { InputController };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Ref } from 'react';
|
|
2
|
+
import type { BasicMultiChannelPerlinNoiseThree, PerlinNoiseThreeOptions } from '../../three/noise/BasicMultiChannelPerlinNoiseThree.js';
|
|
3
|
+
export type BasicMultiChannelPerlinProps = PerlinNoiseThreeOptions & {
|
|
4
|
+
ref?: Ref<BasicMultiChannelPerlinNoiseThree>;
|
|
5
|
+
};
|
|
6
|
+
/** Adds position and rotation noise to the camera. */
|
|
7
|
+
export declare function BasicMultiChannelPerlin({ ref, ...props }: BasicMultiChannelPerlinProps): null;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useVirtualCamera } from "../VirtualCameraContext.js";
|
|
2
|
+
import { useBasicMultiChannelPerlinNoise } from "./useBasicMultiChannelPerlinNoise.js";
|
|
3
|
+
import { useEffect, useImperativeHandle } from "react";
|
|
4
|
+
//#region src/react/noise/BasicMultiChannelPerlin.tsx
|
|
5
|
+
/** Adds position and rotation noise to the camera. */
|
|
6
|
+
function BasicMultiChannelPerlin({ ref, ...props }) {
|
|
7
|
+
const camera = useVirtualCamera();
|
|
8
|
+
const noise = useBasicMultiChannelPerlinNoise(props);
|
|
9
|
+
useImperativeHandle(ref, () => noise, [noise]);
|
|
10
|
+
useEffect(() => camera.addNoise(noise), [camera, noise]);
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { BasicMultiChannelPerlin };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { BasicMultiChannelPerlin } from './BasicMultiChannelPerlin.js';
|
|
2
|
+
/** Noise components add position and rotation offsets to a virtual camera. Multiple noise components can stack. */
|
|
3
|
+
export declare const Noise: {
|
|
4
|
+
BasicMultiChannelPerlin: typeof BasicMultiChannelPerlin;
|
|
5
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BasicMultiChannelPerlin } from "./BasicMultiChannelPerlin.js";
|
|
2
|
+
//#region src/react/noise/Noise.ts
|
|
3
|
+
/** Noise components add position and rotation offsets to a virtual camera. Multiple noise components can stack. */
|
|
4
|
+
var Noise = { BasicMultiChannelPerlin };
|
|
5
|
+
//#endregion
|
|
6
|
+
export { Noise };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { BasicMultiChannelPerlinNoiseThree } from '../../three/noise/BasicMultiChannelPerlinNoiseThree.js';
|
|
2
|
+
import type { BasicMultiChannelPerlinProps } from './BasicMultiChannelPerlin.js';
|
|
3
|
+
/** Creates and synchronizes a shared Perlin noise instance from props. */
|
|
4
|
+
export declare function useBasicMultiChannelPerlinNoise({ positionAmplitude, positionFrequency, rotationAmplitude, rotationFrequency, seed, ...settings }: Omit<BasicMultiChannelPerlinProps, 'ref'>): BasicMultiChannelPerlinNoiseThree;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createParams } from "../../core/noise/perlinNoise.js";
|
|
2
|
+
import { resolveVec3 } from "../../three/resolve/resolveVector3.js";
|
|
3
|
+
import { BasicMultiChannelPerlinNoiseThree } from "../../three/noise/BasicMultiChannelPerlinNoiseThree.js";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
//#region src/react/noise/useBasicMultiChannelPerlinNoise.ts
|
|
6
|
+
/** Creates and synchronizes a shared Perlin noise instance from props. */
|
|
7
|
+
function useBasicMultiChannelPerlinNoise({ positionAmplitude, positionFrequency, rotationAmplitude, rotationFrequency, seed, ...settings }) {
|
|
8
|
+
const { positionAmplitude: defaultPositionAmplitude, positionFrequency: defaultPositionFrequency, rotationAmplitude: defaultRotationAmplitude, rotationFrequency: defaultRotationFrequency, ...params } = createParams(settings);
|
|
9
|
+
const [noise] = useState(() => new BasicMultiChannelPerlinNoiseThree({
|
|
10
|
+
...params,
|
|
11
|
+
seed
|
|
12
|
+
}));
|
|
13
|
+
Object.assign(noise, params);
|
|
14
|
+
resolveVec3(noise.positionAmplitude, positionAmplitude ?? defaultPositionAmplitude);
|
|
15
|
+
resolveVec3(noise.positionFrequency, positionFrequency ?? defaultPositionFrequency);
|
|
16
|
+
resolveVec3(noise.rotationAmplitude, rotationAmplitude ?? defaultRotationAmplitude);
|
|
17
|
+
resolveVec3(noise.rotationFrequency, rotationFrequency ?? defaultRotationFrequency);
|
|
18
|
+
return noise;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { useBasicMultiChannelPerlinNoise };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { EventDispatcher } from '../core/EventDispatcher.js';
|
|
2
|
+
import type { CameraTransitionEventMap } from '../core/Klipp.js';
|
|
3
|
+
/** Callback props for camera transition events. */
|
|
4
|
+
export type CameraTransitionEventProps = {
|
|
5
|
+
onActivated?: (event: CameraTransitionEventMap['activated']) => void;
|
|
6
|
+
onDeactivated?: (event: CameraTransitionEventMap['deactivated']) => void;
|
|
7
|
+
onBlendCreated?: (event: CameraTransitionEventMap['blendCreated']) => void;
|
|
8
|
+
onBlendFinished?: (event: CameraTransitionEventMap['blendFinished']) => void;
|
|
9
|
+
onCut?: (event: CameraTransitionEventMap['cut']) => void;
|
|
10
|
+
};
|
|
11
|
+
/** Subscribe to one camera transition event. */
|
|
12
|
+
export declare function useCameraTransitionEvent<T extends keyof CameraTransitionEventMap>(dispatcher: EventDispatcher<CameraTransitionEventMap>, type: T, listener: ((event: CameraTransitionEventMap[T]) => void) | undefined): void;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useEffect, useEffectEvent } from "react";
|
|
2
|
+
//#region src/react/useCameraTransitionEvent.ts
|
|
3
|
+
/** Subscribe to one camera transition event. */
|
|
4
|
+
function useCameraTransitionEvent(dispatcher, type, listener) {
|
|
5
|
+
const onEvent = useEffectEvent((event) => {
|
|
6
|
+
listener?.(event);
|
|
7
|
+
});
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
dispatcher.addEventListener(type, onEvent);
|
|
10
|
+
return () => dispatcher.removeEventListener(type, onEvent);
|
|
11
|
+
}, [dispatcher, type]);
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { useCameraTransitionEvent };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { CameraHelper } from 'three';
|
|
2
|
+
import type { CameraState } from '../core/CameraState.js';
|
|
3
|
+
/** A `CameraHelper` that draws a virtual camera's frustum from its `state`. */
|
|
4
|
+
export declare class CameraFrustumHelperThree extends CameraHelper {
|
|
5
|
+
/** How far the frustum is drawn. */
|
|
6
|
+
maxDistance: number;
|
|
7
|
+
private readonly lens;
|
|
8
|
+
constructor(maxDistance?: number);
|
|
9
|
+
/** Follow `state`, seen at `aspect`. Redraws only when the pose or lens changed. */
|
|
10
|
+
sync(state: CameraState, aspect: number): void;
|
|
11
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { CameraHelper, PerspectiveCamera, Quaternion, Vector3 } from "three";
|
|
2
|
+
//#region src/three/CameraFrustumHelperThree.ts
|
|
3
|
+
var scratchPosition = new Vector3();
|
|
4
|
+
var scratchQuaternion = new Quaternion();
|
|
5
|
+
/** A `CameraHelper` that draws a virtual camera's frustum from its `state`. */
|
|
6
|
+
var CameraFrustumHelperThree = class extends CameraHelper {
|
|
7
|
+
/** How far the frustum is drawn. */
|
|
8
|
+
maxDistance;
|
|
9
|
+
lens = {
|
|
10
|
+
fov: NaN,
|
|
11
|
+
near: NaN,
|
|
12
|
+
far: NaN,
|
|
13
|
+
aspect: NaN
|
|
14
|
+
};
|
|
15
|
+
constructor(maxDistance = 1) {
|
|
16
|
+
super(new PerspectiveCamera());
|
|
17
|
+
this.maxDistance = maxDistance;
|
|
18
|
+
}
|
|
19
|
+
/** Follow `state`, seen at `aspect`. Redraws only when the pose or lens changed. */
|
|
20
|
+
sync(state, aspect) {
|
|
21
|
+
const camera = this.camera;
|
|
22
|
+
const far = Math.min(state.far, this.maxDistance);
|
|
23
|
+
const lens = this.lens;
|
|
24
|
+
const lensChanged = lens.fov !== state.fov || lens.near !== state.near || lens.far !== far || lens.aspect !== aspect;
|
|
25
|
+
if (lensChanged) {
|
|
26
|
+
camera.fov = lens.fov = state.fov;
|
|
27
|
+
camera.near = lens.near = state.near;
|
|
28
|
+
camera.far = lens.far = far;
|
|
29
|
+
camera.aspect = lens.aspect = aspect;
|
|
30
|
+
camera.updateProjectionMatrix();
|
|
31
|
+
}
|
|
32
|
+
scratchPosition.fromArray(state.position);
|
|
33
|
+
scratchQuaternion.fromArray(state.quaternion);
|
|
34
|
+
const transformChanged = !camera.position.equals(scratchPosition) || !camera.quaternion.equals(scratchQuaternion);
|
|
35
|
+
if (transformChanged) {
|
|
36
|
+
camera.position.copy(scratchPosition);
|
|
37
|
+
camera.quaternion.copy(scratchQuaternion);
|
|
38
|
+
camera.updateMatrixWorld(true);
|
|
39
|
+
}
|
|
40
|
+
if (lensChanged || transformChanged) this.update();
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
//#endregion
|
|
44
|
+
export { CameraFrustumHelperThree };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Camera } from 'three';
|
|
2
|
+
import type { CameraState } from '../core/CameraState.js';
|
|
3
|
+
import { Klipp, type KlippOptions } from '../core/Klipp.js';
|
|
4
|
+
import { VirtualCameraThree, type VirtualCameraThreeOptions } from './VirtualCameraThree.js';
|
|
5
|
+
import { TargetRegistry } from './resolve/TargetRegistry.js';
|
|
6
|
+
export type { KlippMode, FrameUpdate } from '../core/Klipp.js';
|
|
7
|
+
export type KlippThreeOptions = Omit<KlippOptions, 'initialCameraState'>;
|
|
8
|
+
/** `Klipp` for three.js: reads `Object3D` targets once per frame and writes the shot to a camera. */
|
|
9
|
+
export declare class KlippThree extends Klipp {
|
|
10
|
+
/** Reads every target once per frame for all the pieces that follow it. */
|
|
11
|
+
readonly targets: TargetRegistry;
|
|
12
|
+
/** The camera to drive. New virtual cameras start from its pose and lens. */
|
|
13
|
+
camera: Camera;
|
|
14
|
+
constructor(camera: Camera, options?: KlippThreeOptions);
|
|
15
|
+
addCamera(name: string, options?: VirtualCameraThreeOptions): VirtualCameraThree;
|
|
16
|
+
protected prepareFrame(): void;
|
|
17
|
+
protected write(result: CameraState, transformChanged: boolean, lensChanged: boolean): void;
|
|
18
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { create } from "../core/CameraState.js";
|
|
2
|
+
import { Klipp } from "../core/Klipp.js";
|
|
3
|
+
import { copyCameraStateFromCamera, writeCameraLens, writeCameraTransform } from "./camera.js";
|
|
4
|
+
import { VirtualCameraThree } from "./VirtualCameraThree.js";
|
|
5
|
+
import { TargetRegistry } from "./resolve/TargetRegistry.js";
|
|
6
|
+
//#region src/three/KlippThree.ts
|
|
7
|
+
/** `three` can load twice in monorepos; `instanceof` then fails. Use the camera's own flag instead. */
|
|
8
|
+
function isPerspectiveCamera(camera) {
|
|
9
|
+
return camera.isPerspectiveCamera === true;
|
|
10
|
+
}
|
|
11
|
+
/** The original pose and lens per camera, so a later `KlippThree` on the same camera does not inherit stale state. */
|
|
12
|
+
var pristineCameraStates = /* @__PURE__ */ new WeakMap();
|
|
13
|
+
function pristineStateOf(camera) {
|
|
14
|
+
let pristine = pristineCameraStates.get(camera);
|
|
15
|
+
if (!pristine) {
|
|
16
|
+
pristine = create();
|
|
17
|
+
if (isPerspectiveCamera(camera)) copyCameraStateFromCamera(pristine, camera);
|
|
18
|
+
pristineCameraStates.set(camera, pristine);
|
|
19
|
+
}
|
|
20
|
+
return pristine;
|
|
21
|
+
}
|
|
22
|
+
/** `Klipp` for three.js: reads `Object3D` targets once per frame and writes the shot to a camera. */
|
|
23
|
+
var KlippThree = class extends Klipp {
|
|
24
|
+
/** Reads every target once per frame for all the pieces that follow it. */
|
|
25
|
+
targets = new TargetRegistry();
|
|
26
|
+
/** The camera to drive. New virtual cameras start from its pose and lens. */
|
|
27
|
+
camera;
|
|
28
|
+
constructor(camera, options = {}) {
|
|
29
|
+
super({
|
|
30
|
+
...options,
|
|
31
|
+
initialCameraState: pristineStateOf(camera)
|
|
32
|
+
});
|
|
33
|
+
this.camera = camera;
|
|
34
|
+
}
|
|
35
|
+
addCamera(name, options) {
|
|
36
|
+
const camera = new VirtualCameraThree(name, options);
|
|
37
|
+
this.add(camera);
|
|
38
|
+
return camera;
|
|
39
|
+
}
|
|
40
|
+
prepareFrame() {
|
|
41
|
+
super.prepareFrame();
|
|
42
|
+
this.targets.refresh();
|
|
43
|
+
}
|
|
44
|
+
write(result, transformChanged, lensChanged) {
|
|
45
|
+
if (transformChanged) writeCameraTransform(this.camera, result);
|
|
46
|
+
if (lensChanged && isPerspectiveCamera(this.camera)) writeCameraLens(this.camera, result, this.width || 1, this.height || 1);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
//#endregion
|
|
50
|
+
export { KlippThree };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type Quat } from 'math';
|
|
2
|
+
import { Quaternion } from 'three';
|
|
3
|
+
import type { CameraState } from '../core/CameraState.js';
|
|
4
|
+
import { attachTo, prepare } from '../core/internal.js';
|
|
5
|
+
import type { Klipp } from '../core/Klipp.js';
|
|
6
|
+
import { VirtualCamera, type CameraPiece, type VirtualCameraOptions } from '../core/VirtualCamera.js';
|
|
7
|
+
import { type Vector3Like } from './resolve/resolveVector3.js';
|
|
8
|
+
export type { CameraPiece };
|
|
9
|
+
/** A starting pose and lens, with three.js vector shorthand. */
|
|
10
|
+
export type InitialCameraState = Partial<Omit<CameraState, 'position' | 'quaternion' | 'target' | 'lookAtTarget' | 'referenceUp'>> & {
|
|
11
|
+
position?: Vector3Like;
|
|
12
|
+
quaternion?: Quaternion | Quat;
|
|
13
|
+
target?: Vector3Like;
|
|
14
|
+
lookAtTarget?: Vector3Like;
|
|
15
|
+
referenceUp?: Vector3Like;
|
|
16
|
+
};
|
|
17
|
+
export type VirtualCameraThreeOptions = Omit<VirtualCameraOptions, 'initialState'> & {
|
|
18
|
+
/** Starting pose, applied on creation. Defaults to the real camera's pose. */
|
|
19
|
+
initialState?: InitialCameraState;
|
|
20
|
+
};
|
|
21
|
+
/** `VirtualCamera` for three.js: points every piece's target at its slot in the `KlippThree`'s registry. */
|
|
22
|
+
export declare class VirtualCameraThree extends VirtualCamera {
|
|
23
|
+
/** The target registry of the `KlippThree` this camera is in. */
|
|
24
|
+
private registry;
|
|
25
|
+
private readonly slots;
|
|
26
|
+
private readonly groupSlots;
|
|
27
|
+
constructor(name: string, options?: VirtualCameraThreeOptions);
|
|
28
|
+
[attachTo](klipp: Klipp | null): void;
|
|
29
|
+
[prepare](width: number, height: number): void;
|
|
30
|
+
protected removePiece(piece: CameraPiece): void;
|
|
31
|
+
private releaseSlots;
|
|
32
|
+
private syncSlot;
|
|
33
|
+
private syncGroupSlots;
|
|
34
|
+
private releaseGroupSlots;
|
|
35
|
+
}
|