@jgengine/shell 0.10.0 → 0.11.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/CHANGELOG.md +13 -2
- package/LICENSE +203 -661
- package/README.md +1 -1
- package/dist/GamePhaseStamp.d.ts +1 -0
- package/dist/GamePhaseStamp.js +9 -0
- package/dist/GamePlayerShell.d.ts +0 -12
- package/dist/GamePlayerShell.js +88 -1043
- package/dist/GameUiPreview.js +0 -2
- package/dist/audio/audioEngine.js +30 -8
- package/dist/audio/audioWire.d.ts +22 -0
- package/dist/audio/audioWire.js +19 -0
- package/dist/behaviour.d.ts +2 -1
- package/dist/behaviour.js +2 -1
- package/dist/behaviourAttach.d.ts +1 -0
- package/dist/behaviourAttach.js +1 -0
- package/dist/behaviourDriver.d.ts +1 -0
- package/dist/behaviourDriver.js +1 -0
- package/dist/boundActionDispatch.d.ts +13 -0
- package/dist/boundActionDispatch.js +37 -0
- package/dist/camera/GameCameraRig.d.ts +5 -2
- package/dist/camera/GameCameraRig.js +2 -2
- package/dist/camera/GameFirstPersonCamera.d.ts +9 -2
- package/dist/camera/GameFirstPersonCamera.js +8 -3
- package/dist/camera/GameInspectionCamera.d.ts +1 -1
- package/dist/camera/GameInspectionCamera.js +2 -2
- package/dist/camera/GameOrbitCamera.js +24 -9
- package/dist/camera/cameraBlendMath.d.ts +3 -0
- package/dist/camera/cameraBlendMath.js +3 -0
- package/dist/camera/fovPreference.d.ts +6 -1
- package/dist/camera/fovPreference.js +6 -1
- package/dist/camera/index.d.ts +4 -7
- package/dist/camera/index.js +4 -7
- package/dist/camera/inspectionCameraMath.d.ts +7 -2
- package/dist/camera/inspectionCameraMath.js +7 -2
- package/dist/camera/orbitCameraMath.d.ts +36 -6
- package/dist/camera/orbitCameraMath.js +56 -6
- package/dist/camera/rigMath.d.ts +94 -24
- package/dist/camera/rigMath.js +100 -24
- package/dist/camera/rigResolve.d.ts +4 -2
- package/dist/camera/rigResolve.js +4 -2
- package/dist/camera/shakeChannel.d.ts +6 -2
- package/dist/camera/shakeChannel.js +6 -2
- package/dist/camera/shakeChannelMath.d.ts +1 -0
- package/dist/camera/shakeChannelMath.js +1 -0
- package/dist/cartridge/runtime.d.ts +15 -0
- package/dist/cartridge/runtime.js +556 -0
- package/dist/cartridge/spec.d.ts +188 -0
- package/dist/cartridge/spec.js +19 -0
- package/dist/cartridge/validate.d.ts +2 -0
- package/dist/cartridge/validate.js +78 -0
- package/dist/cartridge.d.ts +1 -1
- package/dist/cartridge.js +3 -3
- package/dist/commandSink.d.ts +8 -3
- package/dist/commandSink.js +8 -3
- package/dist/defineGame.js +25 -6
- package/dist/devtools/ColPanel.d.ts +1 -0
- package/dist/devtools/ColPanel.js +14 -0
- package/dist/devtools/DevtoolsOverlay.d.ts +7 -3
- package/dist/devtools/DevtoolsOverlay.js +19 -450
- package/dist/devtools/KeysPanel.d.ts +4 -0
- package/dist/devtools/KeysPanel.js +31 -0
- package/dist/devtools/LogsPanel.d.ts +1 -0
- package/dist/devtools/LogsPanel.js +12 -0
- package/dist/devtools/NetPanel.d.ts +4 -0
- package/dist/devtools/NetPanel.js +10 -0
- package/dist/devtools/PerfPanel.d.ts +4 -0
- package/dist/devtools/PerfPanel.js +53 -0
- package/dist/devtools/TunePanel.d.ts +3 -0
- package/dist/devtools/TunePanel.js +309 -0
- package/dist/devtools/agentBridge.d.ts +41 -0
- package/dist/devtools/agentBridge.js +262 -0
- package/dist/devtools/collisionDebug.d.ts +6 -0
- package/dist/devtools/collisionDebug.js +6 -0
- package/dist/devtools/collisionDebugMath.d.ts +8 -2
- package/dist/devtools/collisionDebugMath.js +24 -5
- package/dist/devtools/devtoolsOverrides.d.ts +6 -0
- package/dist/devtools/devtoolsOverrides.js +48 -0
- package/dist/devtools/panelAtoms.d.ts +9 -0
- package/dist/devtools/panelAtoms.js +10 -0
- package/dist/devtools/perfDiagnose.d.ts +2 -0
- package/dist/devtools/perfDiagnose.js +43 -0
- package/dist/diagnostics/RuntimeDiagnostics.d.ts +29 -0
- package/dist/diagnostics/RuntimeDiagnostics.js +69 -0
- package/dist/drivers/FrameDriver.d.ts +37 -0
- package/dist/drivers/FrameDriver.js +232 -0
- package/dist/drivers/HudOnlyDriver.d.ts +16 -0
- package/dist/drivers/HudOnlyDriver.js +60 -0
- package/dist/environment/Daylight.d.ts +23 -7
- package/dist/environment/Daylight.js +106 -13
- package/dist/environment/EnvironmentScene.js +32 -6
- package/dist/environment/VolumetricClouds.d.ts +17 -0
- package/dist/environment/VolumetricClouds.js +202 -0
- package/dist/environment/daylightCycle.d.ts +3 -1
- package/dist/environment/daylightCycle.js +3 -1
- package/dist/environment/groundPadMath.d.ts +3 -0
- package/dist/environment/groundPadMath.js +3 -0
- package/dist/environment/index.d.ts +1 -0
- package/dist/environment/index.js +1 -0
- package/dist/environment/skyLightingPolicy.d.ts +2 -0
- package/dist/environment/skyLightingPolicy.js +2 -0
- package/dist/hotbarActions.d.ts +26 -0
- package/dist/hotbarActions.js +27 -0
- package/dist/inputSink.d.ts +16 -4
- package/dist/inputSink.js +57 -7
- package/dist/materialOverride.d.ts +10 -0
- package/dist/materialOverride.js +15 -3
- package/dist/multiplayer.js +8 -2
- package/dist/postfx/PostProcessing.js +47 -9
- package/dist/postfx/gradeShader.js +9 -1
- package/dist/registry.d.ts +3 -2
- package/dist/render/EnvironmentLighting.d.ts +10 -0
- package/dist/render/EnvironmentLighting.js +34 -0
- package/dist/render/SceneLighting.d.ts +7 -0
- package/dist/render/SceneLighting.js +18 -0
- package/dist/render/SceneModels.d.ts +14 -0
- package/dist/render/SceneModels.js +337 -0
- package/dist/render/defaultSurface.d.ts +29 -0
- package/dist/render/defaultSurface.js +101 -0
- package/dist/render/modelLoad.d.ts +24 -0
- package/dist/render/modelLoad.js +73 -0
- package/dist/render/modelRender.d.ts +11 -0
- package/dist/render/modelRender.js +15 -0
- package/dist/render/resolveModel.d.ts +39 -3
- package/dist/render/resolveModel.js +79 -2
- package/dist/render/useEntityRenderCues.d.ts +13 -0
- package/dist/render/useEntityRenderCues.js +62 -0
- package/dist/scatter/InstancedScatter.d.ts +24 -0
- package/dist/scatter/InstancedScatter.js +130 -0
- package/dist/scatter/scatterModels.d.ts +25 -0
- package/dist/scatter/scatterModels.js +61 -0
- package/dist/scatter/scatterProxies.d.ts +6 -0
- package/dist/scatter/scatterProxies.js +94 -0
- package/dist/scatter.d.ts +1 -0
- package/dist/scatter.js +1 -0
- package/dist/scene/AuthoredScene.d.ts +82 -0
- package/dist/scene/AuthoredScene.js +173 -0
- package/dist/scene/GeneratedAssetRenderer.d.ts +14 -0
- package/dist/scene/GeneratedAssetRenderer.js +59 -0
- package/dist/scene/GrassFieldRenderer.d.ts +2 -0
- package/dist/scene/GrassFieldRenderer.js +25 -0
- package/dist/scene/SoilPatchRenderer.d.ts +2 -0
- package/dist/scene/SoilPatchRenderer.js +21 -0
- package/dist/scene/StudioStage.d.ts +37 -0
- package/dist/scene/StudioStage.js +42 -0
- package/dist/scene/WaterRenderer.d.ts +2 -0
- package/dist/scene/WaterRenderer.js +37 -0
- package/dist/scene/builtinSceneKindRenderers.d.ts +2 -0
- package/dist/scene/builtinSceneKindRenderers.js +22 -0
- package/dist/scene/sceneKindRenderers.d.ts +28 -0
- package/dist/scene/sceneKindRenderers.js +17 -0
- package/dist/scene.d.ts +1 -0
- package/dist/scene.js +1 -0
- package/dist/settings/appliedSettings.d.ts +5 -0
- package/dist/settings/appliedSettings.js +9 -0
- package/dist/settings/settingsController.d.ts +2 -0
- package/dist/settings/settingsController.js +22 -1
- package/dist/shellConstants.d.ts +4 -0
- package/dist/shellConstants.js +4 -0
- package/dist/shellMovement.d.ts +8 -0
- package/dist/shellMovement.js +11 -0
- package/dist/shellPointer.d.ts +20 -0
- package/dist/shellPointer.js +28 -0
- package/dist/structures/PlacementGhost.d.ts +4 -0
- package/dist/structures/PlacementGhost.js +4 -0
- package/dist/structures/TransformGizmo.d.ts +43 -0
- package/dist/structures/TransformGizmo.js +55 -0
- package/dist/structures/index.d.ts +1 -0
- package/dist/structures/index.js +1 -0
- package/dist/terrain/GrassField.js +1 -1
- package/dist/terrain/TerraformBrushCursor.js +3 -0
- package/dist/terrain/grassBudget.d.ts +11 -2
- package/dist/terrain/grassBudget.js +20 -4
- package/dist/terrain/grassGeometry.d.ts +3 -0
- package/dist/terrain/grassGeometry.js +3 -0
- package/dist/terrain/grassMaterial.d.ts +2 -0
- package/dist/terrain/grassMaterial.js +2 -0
- package/dist/terrain/random.d.ts +3 -0
- package/dist/terrain/random.js +3 -0
- package/dist/terrain/soilPatchMaterial.d.ts +10 -0
- package/dist/terrain/soilPatchMaterial.js +109 -0
- package/dist/terrain/terrainDetailMaterial.d.ts +19 -2
- package/dist/terrain/terrainDetailMaterial.js +72 -5
- package/dist/terrain/terrainMath.d.ts +8 -1
- package/dist/terrain/terrainMath.js +8 -1
- package/dist/touch/TouchControlsOverlay.d.ts +9 -5
- package/dist/touch/TouchControlsOverlay.js +201 -22
- package/dist/useShellMultiplayerSync.d.ts +9 -0
- package/dist/useShellMultiplayerSync.js +98 -0
- package/dist/visibility/CullingProvider.js +1 -1
- package/dist/water/OceanConfig.d.ts +2 -0
- package/dist/water/OceanConfig.js +2 -0
- package/dist/weather/fireSpreadPose.d.ts +1 -0
- package/dist/weather/fireSpreadPose.js +1 -0
- package/dist/weather/weatherGeometry.d.ts +1 -0
- package/dist/weather/weatherGeometry.js +1 -0
- package/dist/weather/weatherMath.d.ts +3 -0
- package/dist/weather/weatherMath.js +3 -0
- package/dist/weather/weatherUniforms.d.ts +3 -0
- package/dist/weather/weatherUniforms.js +3 -0
- package/dist/world/RetainedVfx.d.ts +10 -0
- package/dist/world/RetainedVfx.js +136 -0
- package/dist/world/WorldHud.d.ts +49 -2
- package/dist/world/WorldHud.js +87 -2
- package/dist/world/WorldScene.d.ts +21 -0
- package/dist/world/WorldScene.js +159 -0
- package/dist/world/WorldVfx.d.ts +9 -0
- package/dist/world/WorldVfx.js +184 -0
- package/dist/world/entityPose.d.ts +2 -0
- package/dist/world/entityPose.js +2 -0
- package/dist/world/floatTextStyle.d.ts +1 -0
- package/dist/world/floatTextStyle.js +1 -0
- package/dist/world/telegraphPulse.d.ts +1 -0
- package/dist/world/telegraphPulse.js +1 -0
- package/dist/world/worldBarSamples.d.ts +25 -0
- package/dist/world/worldBarSamples.js +38 -0
- package/dist/worldSky.d.ts +5 -0
- package/dist/worldSky.js +11 -0
- package/dist/worldSync.d.ts +2 -1
- package/dist/worldSync.js +2 -1
- package/package.json +6 -6
- package/skills/jgengine/SKILL.md +51 -0
- package/skills/jgengine/api.md +434 -0
- package/skills/jgengine/capabilities.md +29 -0
- package/skills/jgengine/reference-cartridge.md +72 -0
- package/skills/jgengine-ui/SKILL.md +36 -0
- package/skills/jgengine-ui/api.md +1852 -0
- package/skills/jgengine-ui/capabilities.md +142 -0
- package/skills/jgengine-ui/reference.md +500 -0
- package/skills/jgengine-ui/references/visual-scorecard.md +73 -0
- package/skills/jgengine-world/SKILL.md +38 -0
- package/skills/jgengine-world/api.md +2652 -0
- package/skills/jgengine-world/capabilities.md +370 -0
- package/skills/jgengine-world/reference.md +222 -0
- package/llms.txt +0 -2761
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @internal */
|
|
1
2
|
export function resolveInspectionCameraConfig(config) {
|
|
2
3
|
return {
|
|
3
4
|
anchor: config?.anchor ?? "target",
|
|
@@ -24,7 +25,9 @@ export function resolveInspectionCameraConfig(config) {
|
|
|
24
25
|
dampingFactor: config?.dampingFactor ?? 0.08,
|
|
25
26
|
};
|
|
26
27
|
}
|
|
27
|
-
/** Seeds the camera/target world position before OrbitControls mounts. Falls back to `initialDistance` behind `target` on the -Z axis, raised by 40% of that distance, when `initialPosition` is unset.
|
|
28
|
+
/** Seeds the camera/target world position before OrbitControls mounts. Falls back to `initialDistance` behind `target` on the -Z axis, raised by 40% of that distance, when `initialPosition` is unset.
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
28
31
|
export function seedInspectionCamera(config) {
|
|
29
32
|
if (config.initialPosition !== null) {
|
|
30
33
|
return { camera: config.initialPosition, target: config.target };
|
|
@@ -38,7 +41,9 @@ export function seedInspectionCamera(config) {
|
|
|
38
41
|
target: config.target,
|
|
39
42
|
};
|
|
40
43
|
}
|
|
41
|
-
/** Maps the anchor mode onto three-stdlib OrbitControls' native `zoomToCursor` flag.
|
|
44
|
+
/** Maps the anchor mode onto three-stdlib OrbitControls' native `zoomToCursor` flag.
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
42
47
|
export function resolveInspectionZoomToCursor(anchor) {
|
|
43
48
|
return anchor === "cursor";
|
|
44
49
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
/** Horizontal facing derived from an orbit camera orbiting a target on the XZ plane.
|
|
1
|
+
/** Horizontal facing derived from an orbit camera orbiting a target on the XZ plane.
|
|
2
|
+
* @internal
|
|
3
|
+
*/
|
|
2
4
|
export declare function orbitYawFromCamera(cameraX: number, cameraZ: number, targetX: number, targetZ: number): number;
|
|
3
|
-
/** Elevation the camera looks along (radians): negative = aiming down, positive = aiming up, 0 = level. Feeds aim.pitch so vertical aim tracks the camera.
|
|
5
|
+
/** Elevation the camera looks along (radians): negative = aiming down, positive = aiming up, 0 = level. Feeds aim.pitch so vertical aim tracks the camera.
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
4
8
|
export declare function cameraLookPitch(camera: Vec3, target: Vec3): number;
|
|
5
9
|
export interface Vec3 {
|
|
6
10
|
x: number;
|
|
@@ -19,6 +23,12 @@ export interface OrbitCameraConfig {
|
|
|
19
23
|
targetHeight?: number;
|
|
20
24
|
initialDistance?: number;
|
|
21
25
|
initialHeight?: number;
|
|
26
|
+
/** Initial horizontal facing of the boom (radians): 0 = camera behind on -Z, PI = camera on +Z. Seeds the rig when set; unset keeps the legacy -Z placement. */
|
|
27
|
+
initialYaw?: number;
|
|
28
|
+
/** Initial boom elevation (radians): 0 = level, positive = camera above the target looking down. Seeds the rig when set; unset derives elevation from `initialHeight`/`initialDistance`. */
|
|
29
|
+
initialPitch?: number;
|
|
30
|
+
/** Signed boom-elevation clamp `[min, max]` (radians): min < 0 dips below the target, max > 0 rises overhead. Maps onto `minPolarAngle`/`maxPolarAngle` (polar = PI/2 − pitch); explicit polar fields win. */
|
|
31
|
+
pitchClamp?: readonly [number, number];
|
|
22
32
|
/** Extra offset applied on top of entity position for the orbit target. */
|
|
23
33
|
targetOffset?: Partial<Vec3>;
|
|
24
34
|
/** Keep orbit radius locked while the follow target moves. */
|
|
@@ -64,6 +74,8 @@ export interface ResolvedOrbitCameraConfig {
|
|
|
64
74
|
targetHeight: number;
|
|
65
75
|
initialDistance: number;
|
|
66
76
|
initialHeight: number;
|
|
77
|
+
initialYaw?: number;
|
|
78
|
+
initialPitch?: number;
|
|
67
79
|
targetOffset?: Partial<Vec3>;
|
|
68
80
|
followLock: boolean;
|
|
69
81
|
followEnabled: boolean;
|
|
@@ -87,22 +99,38 @@ export interface OrbitFollowRuntimeState {
|
|
|
87
99
|
camera: Vec3;
|
|
88
100
|
lockedDistance: number | null;
|
|
89
101
|
}
|
|
90
|
-
/** Frame-rate independent exponential smoothing factor in [0, 1].
|
|
102
|
+
/** Frame-rate independent exponential smoothing factor in [0, 1].
|
|
103
|
+
* @internal
|
|
104
|
+
*/
|
|
91
105
|
export declare function smoothBlend(deltaSeconds: number, speed: number): number;
|
|
106
|
+
/** @internal */
|
|
92
107
|
export declare function resolveOrbitCameraConfig(patch?: OrbitCameraConfig): ResolvedOrbitCameraConfig;
|
|
108
|
+
/**
|
|
109
|
+
* FOV that keeps a target's on-screen size constant as the spring-arm pulls the
|
|
110
|
+
* camera in. Widens the base FOV by the desired/pulled distance ratio; a no-op
|
|
111
|
+
* (returns the base) whenever the camera sits at or beyond its desired distance.
|
|
112
|
+
* @internal
|
|
113
|
+
*/
|
|
114
|
+
export declare function compensatedFov(baseFovDegrees: number, desiredDistance: number, pulledDistance: number): number;
|
|
115
|
+
/** @internal */
|
|
93
116
|
export declare function resolveTargetSmoothing(config: ResolvedOrbitCameraConfig, dragging: boolean): number;
|
|
117
|
+
/** @internal */
|
|
94
118
|
export declare function resolveFollowTargetFromPosition(position: readonly [number, number, number], config: Pick<ResolvedOrbitCameraConfig, "targetHeight" | "targetOffset">): Vec3;
|
|
119
|
+
/** @internal */
|
|
95
120
|
export declare function lerpVec3(from: Vec3, to: Vec3, blend: number): Vec3;
|
|
121
|
+
/** @internal */
|
|
96
122
|
export declare function distanceBetween(a: Vec3, b: Vec3): number;
|
|
123
|
+
/** @internal */
|
|
97
124
|
export declare function seedOrbitFollowState(input: {
|
|
98
125
|
entityPosition: readonly [number, number, number];
|
|
99
|
-
config: Pick<ResolvedOrbitCameraConfig, "targetHeight" | "targetOffset" | "initialDistance" | "initialHeight">;
|
|
126
|
+
config: Pick<ResolvedOrbitCameraConfig, "targetHeight" | "targetOffset" | "initialDistance" | "initialHeight" | "initialYaw" | "initialPitch">;
|
|
100
127
|
}): OrbitFollowRuntimeState;
|
|
101
128
|
/**
|
|
102
129
|
* Pure orbit follow step — smooth target tracking, camera carries target delta
|
|
103
130
|
* (OrbitControls alone keeps camera fixed when only target moves), optional
|
|
104
131
|
* distance lock. Call each frame before OrbitControls.update() in the shell.
|
|
105
|
-
|
|
132
|
+
* @internal
|
|
133
|
+
*/
|
|
106
134
|
export declare function orbitFollowStep(input: {
|
|
107
135
|
state: OrbitFollowRuntimeState;
|
|
108
136
|
desiredTarget: Vec3;
|
|
@@ -112,7 +140,9 @@ export declare function orbitFollowStep(input: {
|
|
|
112
140
|
}): OrbitFollowRuntimeState & {
|
|
113
141
|
distance: number;
|
|
114
142
|
};
|
|
115
|
-
/** @deprecated Use orbitFollowStep — kept for older call sites.
|
|
143
|
+
/** @deprecated Use orbitFollowStep — kept for older call sites.
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
116
146
|
export declare function cameraFollowStep(input: {
|
|
117
147
|
camera: Vec3;
|
|
118
148
|
target: Vec3;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
/** Horizontal facing derived from an orbit camera orbiting a target on the XZ plane.
|
|
1
|
+
/** Horizontal facing derived from an orbit camera orbiting a target on the XZ plane.
|
|
2
|
+
* @internal
|
|
3
|
+
*/
|
|
2
4
|
export function orbitYawFromCamera(cameraX, cameraZ, targetX, targetZ) {
|
|
3
5
|
const dx = targetX - cameraX;
|
|
4
6
|
const dz = targetZ - cameraZ;
|
|
5
7
|
return Math.atan2(dx, dz);
|
|
6
8
|
}
|
|
7
|
-
/** Elevation the camera looks along (radians): negative = aiming down, positive = aiming up, 0 = level. Feeds aim.pitch so vertical aim tracks the camera.
|
|
9
|
+
/** Elevation the camera looks along (radians): negative = aiming down, positive = aiming up, 0 = level. Feeds aim.pitch so vertical aim tracks the camera.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
8
12
|
export function cameraLookPitch(camera, target) {
|
|
9
13
|
const horizontal = Math.hypot(target.x - camera.x, target.z - camera.z);
|
|
10
14
|
return Math.atan2(target.y - camera.y, horizontal);
|
|
@@ -31,23 +35,48 @@ export const DEFAULT_ORBIT_CAMERA = {
|
|
|
31
35
|
export const GAME_SIM_FRAME_PRIORITY = 0;
|
|
32
36
|
/** Orbit follow reads the latest entity pose after GAME_SIM_FRAME_PRIORITY. */
|
|
33
37
|
export const ORBIT_CAMERA_FRAME_PRIORITY = -1;
|
|
34
|
-
/** Frame-rate independent exponential smoothing factor in [0, 1].
|
|
38
|
+
/** Frame-rate independent exponential smoothing factor in [0, 1].
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
35
41
|
export function smoothBlend(deltaSeconds, speed) {
|
|
36
42
|
return 1 - Math.exp(-speed * deltaSeconds);
|
|
37
43
|
}
|
|
44
|
+
/** @internal */
|
|
38
45
|
export function resolveOrbitCameraConfig(patch) {
|
|
39
|
-
|
|
46
|
+
const resolved = {
|
|
40
47
|
...DEFAULT_ORBIT_CAMERA,
|
|
41
48
|
...patch,
|
|
42
49
|
collision: { ...DEFAULT_ORBIT_CAMERA.collision, ...patch?.collision },
|
|
43
50
|
};
|
|
51
|
+
if (patch?.pitchClamp !== undefined) {
|
|
52
|
+
const [minPitch, maxPitch] = patch.pitchClamp;
|
|
53
|
+
resolved.minPolarAngle = patch.minPolarAngle ?? Math.PI / 2 - maxPitch;
|
|
54
|
+
resolved.maxPolarAngle = patch.maxPolarAngle ?? Math.PI / 2 - minPitch;
|
|
55
|
+
}
|
|
56
|
+
return resolved;
|
|
44
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* FOV that keeps a target's on-screen size constant as the spring-arm pulls the
|
|
60
|
+
* camera in. Widens the base FOV by the desired/pulled distance ratio; a no-op
|
|
61
|
+
* (returns the base) whenever the camera sits at or beyond its desired distance.
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
64
|
+
export function compensatedFov(baseFovDegrees, desiredDistance, pulledDistance) {
|
|
65
|
+
if (pulledDistance <= 0 || desiredDistance <= 0 || pulledDistance >= desiredDistance) {
|
|
66
|
+
return baseFovDegrees;
|
|
67
|
+
}
|
|
68
|
+
const half = (baseFovDegrees * Math.PI) / 360;
|
|
69
|
+
const widened = 2 * Math.atan(Math.tan(half) * (desiredDistance / pulledDistance));
|
|
70
|
+
return Math.min((widened * 180) / Math.PI, 170);
|
|
71
|
+
}
|
|
72
|
+
/** @internal */
|
|
45
73
|
export function resolveTargetSmoothing(config, dragging) {
|
|
46
74
|
if (dragging) {
|
|
47
75
|
return config.dragTargetSmoothing;
|
|
48
76
|
}
|
|
49
77
|
return config.targetSmoothing;
|
|
50
78
|
}
|
|
79
|
+
/** @internal */
|
|
51
80
|
export function resolveFollowTargetFromPosition(position, config) {
|
|
52
81
|
const offset = config.targetOffset;
|
|
53
82
|
return {
|
|
@@ -56,6 +85,7 @@ export function resolveFollowTargetFromPosition(position, config) {
|
|
|
56
85
|
z: position[2] + (offset?.z ?? 0),
|
|
57
86
|
};
|
|
58
87
|
}
|
|
88
|
+
/** @internal */
|
|
59
89
|
export function lerpVec3(from, to, blend) {
|
|
60
90
|
return {
|
|
61
91
|
x: from.x + (to.x - from.x) * blend,
|
|
@@ -63,14 +93,31 @@ export function lerpVec3(from, to, blend) {
|
|
|
63
93
|
z: from.z + (to.z - from.z) * blend,
|
|
64
94
|
};
|
|
65
95
|
}
|
|
96
|
+
/** @internal */
|
|
66
97
|
export function distanceBetween(a, b) {
|
|
67
98
|
const dx = a.x - b.x;
|
|
68
99
|
const dy = a.y - b.y;
|
|
69
100
|
const dz = a.z - b.z;
|
|
70
101
|
return Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
71
102
|
}
|
|
103
|
+
/** @internal */
|
|
72
104
|
export function seedOrbitFollowState(input) {
|
|
73
105
|
const target = resolveFollowTargetFromPosition(input.entityPosition, input.config);
|
|
106
|
+
const { initialDistance, initialYaw, initialPitch } = input.config;
|
|
107
|
+
if (initialYaw !== undefined || initialPitch !== undefined) {
|
|
108
|
+
const yaw = initialYaw ?? 0;
|
|
109
|
+
const pitch = initialPitch ?? Math.atan2(input.config.initialHeight - input.config.targetHeight, initialDistance);
|
|
110
|
+
const horizontal = initialDistance * Math.cos(pitch);
|
|
111
|
+
return {
|
|
112
|
+
target,
|
|
113
|
+
camera: {
|
|
114
|
+
x: target.x - horizontal * Math.sin(yaw),
|
|
115
|
+
y: target.y + initialDistance * Math.sin(pitch),
|
|
116
|
+
z: target.z - horizontal * Math.cos(yaw),
|
|
117
|
+
},
|
|
118
|
+
lockedDistance: initialDistance,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
74
121
|
return {
|
|
75
122
|
target,
|
|
76
123
|
camera: {
|
|
@@ -85,7 +132,8 @@ export function seedOrbitFollowState(input) {
|
|
|
85
132
|
* Pure orbit follow step — smooth target tracking, camera carries target delta
|
|
86
133
|
* (OrbitControls alone keeps camera fixed when only target moves), optional
|
|
87
134
|
* distance lock. Call each frame before OrbitControls.update() in the shell.
|
|
88
|
-
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
89
137
|
export function orbitFollowStep(input) {
|
|
90
138
|
const target = { ...input.state.target };
|
|
91
139
|
const camera = { ...input.state.camera };
|
|
@@ -124,7 +172,9 @@ export function orbitFollowStep(input) {
|
|
|
124
172
|
}
|
|
125
173
|
return { target, camera, lockedDistance, distance: distanceBetween(camera, target) };
|
|
126
174
|
}
|
|
127
|
-
/** @deprecated Use orbitFollowStep — kept for older call sites.
|
|
175
|
+
/** @deprecated Use orbitFollowStep — kept for older call sites.
|
|
176
|
+
* @internal
|
|
177
|
+
*/
|
|
128
178
|
export function cameraFollowStep(input) {
|
|
129
179
|
const state = {
|
|
130
180
|
target: input.previousTarget ?? input.target,
|
package/dist/camera/rigMath.d.ts
CHANGED
|
@@ -6,12 +6,19 @@ export interface CameraPose {
|
|
|
6
6
|
lookAt: Vec3;
|
|
7
7
|
fov: number;
|
|
8
8
|
}
|
|
9
|
+
/** @internal */
|
|
9
10
|
export declare function rtsPanKeysConflict(input: ActionCodesMap | undefined): boolean;
|
|
11
|
+
/** @internal */
|
|
10
12
|
export declare function clamp(value: number, min: number, max: number): number;
|
|
13
|
+
/** @internal */
|
|
11
14
|
export declare function lerp(from: number, to: number, blend: number): number;
|
|
15
|
+
/** @internal */
|
|
12
16
|
export declare function smoothstep(t: number): number;
|
|
17
|
+
/** @internal */
|
|
13
18
|
export declare function forwardVector(yaw: number): Vec3;
|
|
14
|
-
/** Screen-right of a yaw: `forward × up` with up = +Y.
|
|
19
|
+
/** Screen-right of a yaw: `forward × up` with up = +Y.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
15
22
|
export declare function rightVector(yaw: number): Vec3;
|
|
16
23
|
export interface ResolvedTopDown {
|
|
17
24
|
height: number;
|
|
@@ -20,15 +27,19 @@ export interface ResolvedTopDown {
|
|
|
20
27
|
offset: Vec3;
|
|
21
28
|
followSmoothing: number;
|
|
22
29
|
}
|
|
30
|
+
/** @internal */
|
|
23
31
|
export declare function resolveTopDown(config: TopDownCameraConfig | undefined): ResolvedTopDown;
|
|
24
32
|
/**
|
|
25
33
|
* Camera pose for a fixed top-down / isometric rig. `pitch` is the elevation of
|
|
26
34
|
* the camera→target ray above the ground (PI/2 = straight down); `yaw` is the
|
|
27
35
|
* fixed azimuth (PI/4 reads isometric). Height sets zoom; horizontal boom is
|
|
28
36
|
* derived so the look angle stays constant as height changes.
|
|
29
|
-
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
30
39
|
export declare function topDownPose(follow: Vec3, resolved: ResolvedTopDown, fov: number): CameraPose;
|
|
31
|
-
/** Exponential spring-arm approach toward a desired point (frame-rate independent).
|
|
40
|
+
/** Exponential spring-arm approach toward a desired point (frame-rate independent).
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
32
43
|
export declare function springArmStep(current: Vec3, desired: Vec3, damping: number, dt: number): Vec3;
|
|
33
44
|
export interface ResolvedSideScroll {
|
|
34
45
|
axis: "x" | "z";
|
|
@@ -37,26 +48,38 @@ export interface ResolvedSideScroll {
|
|
|
37
48
|
lookHeight: number;
|
|
38
49
|
followSmoothing: number;
|
|
39
50
|
}
|
|
51
|
+
/** @internal */
|
|
40
52
|
export declare function resolveSideScroll(config: SideScrollCameraConfig | undefined): ResolvedSideScroll;
|
|
41
|
-
/** Frame-rate independent follow blend for the side-scroll rig; `followSmoothing <= 0` hard-locks (blend 1) instead of freezing.
|
|
53
|
+
/** Frame-rate independent follow blend for the side-scroll rig; `followSmoothing <= 0` hard-locks (blend 1) instead of freezing.
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
42
56
|
export declare function sideScrollFollowBlend(followSmoothing: number, dt: number): number;
|
|
43
57
|
/**
|
|
44
58
|
* Fixed lateral 2.5D follow pose: the camera sits perpendicular to the travel
|
|
45
59
|
* axis at `distance`, above the entity by `height`, and looks at the entity
|
|
46
60
|
* raised by `lookHeight`. Axis "x" watches from +z; axis "z" watches from +x.
|
|
47
|
-
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
48
63
|
export declare function resolveSideScrollPose(entityPos: Vec3, resolved: ResolvedSideScroll, fov: number): CameraPose;
|
|
49
|
-
/** Speed→FOV curve: FOV climbs from base to max as speed rises to `speedForMax`.
|
|
64
|
+
/** Speed→FOV curve: FOV climbs from base to max as speed rises to `speedForMax`.
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
50
67
|
export declare function speedToFov(speed: number, curve: {
|
|
51
68
|
base?: number;
|
|
52
69
|
max?: number;
|
|
53
70
|
speedForMax?: number;
|
|
54
71
|
} | undefined): number;
|
|
55
|
-
/** Yaw that points from `from` toward `to` on the XZ plane (matches shell forward = (sin, cos)).
|
|
72
|
+
/** Yaw that points from `from` toward `to` on the XZ plane (matches shell forward = (sin, cos)).
|
|
73
|
+
* @internal
|
|
74
|
+
*/
|
|
56
75
|
export declare function yawTo(from: Vec3, to: Vec3): number;
|
|
57
|
-
/** Shortest signed angular delta from `a` to `b`, wrapped to (-PI, PI].
|
|
76
|
+
/** Shortest signed angular delta from `a` to `b`, wrapped to (-PI, PI].
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
58
79
|
export declare function angleDelta(a: number, b: number): number;
|
|
59
|
-
/** Exponential yaw smoothing that respects wrap-around.
|
|
80
|
+
/** Exponential yaw smoothing that respects wrap-around.
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
60
83
|
export declare function smoothYaw(current: number, desired: number, speed: number, dt: number): number;
|
|
61
84
|
export interface ResolvedShoulder {
|
|
62
85
|
shoulderOffset: number;
|
|
@@ -64,20 +87,25 @@ export interface ResolvedShoulder {
|
|
|
64
87
|
distance: number;
|
|
65
88
|
fov: number;
|
|
66
89
|
}
|
|
90
|
+
/** @internal */
|
|
67
91
|
export declare function resolveShoulder(config: ShoulderCameraConfig | undefined, aiming: boolean): ResolvedShoulder;
|
|
68
|
-
/** Blend two shoulder framings by an ADS factor in [0,1].
|
|
92
|
+
/** Blend two shoulder framings by an ADS factor in [0,1].
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
69
95
|
export declare function blendShoulder(hip: ResolvedShoulder, ads: ResolvedShoulder, t: number): ResolvedShoulder;
|
|
70
96
|
/**
|
|
71
97
|
* Over-the-shoulder camera pose. The boom sits behind the follow point along
|
|
72
98
|
* `yaw`, raised by `heightOffset`, and pushed sideways by `shoulderOffset`
|
|
73
99
|
* (sign set by `sideSign`: +1 right, -1 left). `pitch` tilts the look point.
|
|
74
|
-
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
75
102
|
export declare function shoulderPose(follow: Vec3, yaw: number, pitch: number, sideSign: number, shoulder: ResolvedShoulder): CameraPose;
|
|
76
103
|
/**
|
|
77
104
|
* Lock-on pose: camera sits behind the player along the player→target vector so
|
|
78
105
|
* the target stays framed. The look point is biased between player and target
|
|
79
106
|
* by `framingBias`.
|
|
80
|
-
|
|
107
|
+
* @internal
|
|
108
|
+
*/
|
|
81
109
|
export declare function lockOnPose(player: Vec3, target: Vec3, config: LockOnCameraConfig | undefined, fov: number): {
|
|
82
110
|
pose: CameraPose;
|
|
83
111
|
yaw: number;
|
|
@@ -94,10 +122,15 @@ export interface ResolvedChase {
|
|
|
94
122
|
bankMax: number;
|
|
95
123
|
bankDamping: number;
|
|
96
124
|
}
|
|
125
|
+
/** @internal */
|
|
97
126
|
export declare function resolveChase(config: ChaseCameraConfig | undefined): ResolvedChase;
|
|
98
|
-
/** Velocity-lead the follow point (#286.9): aim `leadTime` seconds along the target's frame velocity, clamped to `leadMax`.
|
|
127
|
+
/** Velocity-lead the follow point (#286.9): aim `leadTime` seconds along the target's frame velocity, clamped to `leadMax`.
|
|
128
|
+
* @internal
|
|
129
|
+
*/
|
|
99
130
|
export declare function leadFollowPoint(follow: Vec3, previous: Vec3, dt: number, resolved: ResolvedChase): Vec3;
|
|
100
|
-
/** One smoothing step of the chase rig's turn-bank roll (#286.10): roll opposes yaw rate, clamped and exponentially damped.
|
|
131
|
+
/** One smoothing step of the chase rig's turn-bank roll (#286.10): roll opposes yaw rate, clamped and exponentially damped.
|
|
132
|
+
* @internal
|
|
133
|
+
*/
|
|
101
134
|
export declare function bankRollStep(currentRoll: number, yaw: number, previousYaw: number, dt: number, resolved: ResolvedChase): number;
|
|
102
135
|
export interface ResolvedObserver {
|
|
103
136
|
distance: number;
|
|
@@ -105,14 +138,23 @@ export interface ResolvedObserver {
|
|
|
105
138
|
lookHeight: number;
|
|
106
139
|
orbitSpeed: number;
|
|
107
140
|
}
|
|
141
|
+
/** @internal */
|
|
108
142
|
export declare function resolveObserver(config: ObserverCameraConfig | undefined): ResolvedObserver;
|
|
109
|
-
/** Detached spectator pose: orbits `subject` at a fixed distance/height, never reading player input.
|
|
143
|
+
/** Detached spectator pose: orbits `subject` at a fixed distance/height, never reading player input.
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
110
146
|
export declare function observerPose(subject: Vec3, angle: number, resolved: ResolvedObserver, fov: number): CameraPose;
|
|
111
|
-
/** Desired chase-camera position behind a vehicle facing `yaw` (before spring smoothing).
|
|
147
|
+
/** Desired chase-camera position behind a vehicle facing `yaw` (before spring smoothing).
|
|
148
|
+
* @internal
|
|
149
|
+
*/
|
|
112
150
|
export declare function chaseDesiredPosition(follow: Vec3, yaw: number, resolved: ResolvedChase): Vec3;
|
|
113
|
-
/** Look point ahead of / above a chased vehicle.
|
|
151
|
+
/** Look point ahead of / above a chased vehicle.
|
|
152
|
+
* @internal
|
|
153
|
+
*/
|
|
114
154
|
export declare function chaseLookAt(follow: Vec3, yaw: number, resolved: ResolvedChase): Vec3;
|
|
115
|
-
/** World-space seat pose (cockpit/hood/rear) rigidly attached to the vehicle.
|
|
155
|
+
/** World-space seat pose (cockpit/hood/rear) rigidly attached to the vehicle.
|
|
156
|
+
* @internal
|
|
157
|
+
*/
|
|
116
158
|
export declare function seatPose(follow: Vec3, yaw: number, local: {
|
|
117
159
|
x?: number;
|
|
118
160
|
y?: number;
|
|
@@ -122,10 +164,15 @@ export interface TraumaState {
|
|
|
122
164
|
trauma: number;
|
|
123
165
|
time: number;
|
|
124
166
|
}
|
|
167
|
+
/** @internal */
|
|
125
168
|
export declare function createTrauma(): TraumaState;
|
|
126
|
-
/** Add trauma (0..1) and clamp; larger hits raise the ceiling toward 1.
|
|
169
|
+
/** Add trauma (0..1) and clamp; larger hits raise the ceiling toward 1.
|
|
170
|
+
* @internal
|
|
171
|
+
*/
|
|
127
172
|
export declare function addTrauma(state: TraumaState, amount: number): void;
|
|
128
|
-
/** Decay trauma linearly toward 0 and advance the shake clock.
|
|
173
|
+
/** Decay trauma linearly toward 0 and advance the shake clock.
|
|
174
|
+
* @internal
|
|
175
|
+
*/
|
|
129
176
|
export declare function stepTrauma(state: TraumaState, decayPerSecond: number, dt: number): void;
|
|
130
177
|
export interface ShakeOffset {
|
|
131
178
|
x: number;
|
|
@@ -136,14 +183,35 @@ export interface ShakeOffset {
|
|
|
136
183
|
* Positional + roll shake for the current trauma. Shake magnitude is
|
|
137
184
|
* `trauma^exponent` so small hits stay subtle; the oscillation is deterministic
|
|
138
185
|
* per-seed pseudo-noise (no per-frame RNG, so identical inputs reproduce).
|
|
139
|
-
|
|
186
|
+
* @internal
|
|
187
|
+
*/
|
|
140
188
|
export declare function shakeOffset(state: TraumaState, config: {
|
|
141
189
|
maxOffset?: number;
|
|
142
190
|
maxRoll?: number;
|
|
143
191
|
exponent?: number;
|
|
144
192
|
frequency?: number;
|
|
145
193
|
} | undefined): ShakeOffset;
|
|
146
|
-
/**
|
|
194
|
+
/** Calibrated trauma decay for `traumaShake`/`impactPresets` (trauma/second). */
|
|
195
|
+
export declare const CALIBRATED_TRAUMA_SHAKE_DECAY_PER_SECOND = 1.4;
|
|
196
|
+
/** Calibrated positional shake amplitude at full trauma (world units) for `traumaShake`. */
|
|
197
|
+
export declare const CALIBRATED_TRAUMA_SHAKE_MAX_OFFSET = 0.55;
|
|
198
|
+
/** Calibrated rotational shake amplitude at full trauma (radians) for `traumaShake`. */
|
|
199
|
+
export declare const CALIBRATED_TRAUMA_SHAKE_MAX_ROLL = 0.1;
|
|
200
|
+
/** Calibrated shake noise frequency (Hz) for `traumaShake`. */
|
|
201
|
+
export declare const CALIBRATED_TRAUMA_SHAKE_FREQUENCY = 32;
|
|
202
|
+
/**
|
|
203
|
+
* Calibrated trauma² camera shake: offset scales with `trauma` squared using
|
|
204
|
+
* game-feel defaults (decay 1.4/s, max offset 0.55, max roll 0.1 rad, noise
|
|
205
|
+
* freq 32×t) — the curve `impactPresets` trauma values are calibrated
|
|
206
|
+
* against, so an impact "just looks right" without hand-tuning `shakeOffset`.
|
|
207
|
+
*
|
|
208
|
+
* @capability camera-shake calibrated trauma² camera kick with zero tuning
|
|
209
|
+
* @internal
|
|
210
|
+
*/
|
|
211
|
+
export declare function traumaShake(trauma: number, time?: number): ShakeOffset;
|
|
212
|
+
/** Linear cross-fade between two full camera poses (position, lookAt, fov).
|
|
213
|
+
* @internal
|
|
214
|
+
*/
|
|
147
215
|
export declare function crossfadePose(from: CameraPose, to: CameraPose, t: number): CameraPose;
|
|
148
216
|
export interface DirectorCameraValues {
|
|
149
217
|
/** `undefined` = no runtime override (fall back to static); `null` = explicitly follow nothing. */
|
|
@@ -164,7 +232,8 @@ export interface ResolvedDirectedCamera {
|
|
|
164
232
|
* (#196.2). `director` omitted, or its fields `undefined`/`null`, is a pure
|
|
165
233
|
* passthrough to `staticConfig` so mounting a director with no active override
|
|
166
234
|
* changes nothing.
|
|
167
|
-
|
|
235
|
+
* @internal
|
|
236
|
+
*/
|
|
168
237
|
export declare function resolveDirectedCamera(director: DirectorCameraValues | undefined, staticConfig: StaticCameraValues): ResolvedDirectedCamera;
|
|
169
238
|
export interface CinematicSample {
|
|
170
239
|
pose: CameraPose;
|
|
@@ -175,5 +244,6 @@ export interface CinematicSample {
|
|
|
175
244
|
* travel time from the previous keyframe into it; segment easing is per the
|
|
176
245
|
* destination keyframe. Reports `done` once past the final keyframe (unless
|
|
177
246
|
* looping, which wraps `elapsed` into the total path duration).
|
|
178
|
-
|
|
247
|
+
* @internal
|
|
248
|
+
*/
|
|
179
249
|
export declare function cinematicSample(keyframes: readonly CameraKeyframe[], elapsed: number, loop: boolean, fallbackFov: number): CinematicSample;
|