@descix/frqtl-node 0.0.0-stage → 0.6.0-p0.2
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/CLAUDE.md +87 -0
- package/LICENSE.md +664 -0
- package/README.md +84 -2
- package/dist/dist-manifest.json +218 -0
- package/dist/eyes/index.js +109 -0
- package/dist/fat/pkg-node/egpt_wasm.js +1277 -0
- package/dist/fat/pkg-node/egpt_wasm_bg.wasm +0 -0
- package/dist/fat/pkg-node/package.json +12 -0
- package/dist/frqtl/assets/vendor/chroma.mjs +64 -0
- package/dist/frqtl/compat/boot-node.js +34 -0
- package/dist/frqtl/compat/engine.js +127 -0
- package/dist/frqtl/compat/package-root.js +24 -0
- package/dist/frqtl/compat/providers/wasm-engine.js +2499 -0
- package/dist/frqtl/compat/providers/wasm-load-browser.js +134 -0
- package/dist/frqtl/compat/providers/wasm-load-node.js +59 -0
- package/dist/frqtl/compat/renderer/FieldBuilder.js +145 -0
- package/dist/frqtl/compat/renderer/Filters.js +163 -0
- package/dist/frqtl/compat/renderer/RenderFamily.js +84 -0
- package/dist/frqtl/compat/renderer/RenderMesh.js +99 -0
- package/dist/frqtl/compat/renderer/RenderShape.js +154 -0
- package/dist/frqtl/compat/renderer/camera2d-geometry.js +183 -0
- package/dist/frqtl/compat/renderer/captureStill-common.js +258 -0
- package/dist/frqtl/compat/renderer/display-slot.js +96 -0
- package/dist/frqtl/compat/renderer/lo-drawn-center.js +231 -0
- package/dist/frqtl/compat/renderer/orbit-bag.js +216 -0
- package/dist/frqtl/compat/renderer/providers/godrays-layer.js +213 -0
- package/dist/frqtl/compat/renderer/providers/index.js +22 -0
- package/dist/frqtl/compat/renderer/providers/p5-provider.js +861 -0
- package/dist/frqtl/compat/renderer/providers/three-camera-contract.js +160 -0
- package/dist/frqtl/compat/renderer/providers/three-camera-geometry.js +571 -0
- package/dist/frqtl/compat/renderer/providers/three-provider.js +2470 -0
- package/dist/frqtl/compat/renderer/renderCapabilities-common.js +186 -0
- package/dist/frqtl/compat/renderer/renderer-provider-contract.js +238 -0
- package/dist/frqtl/compat/renderer/unprojectStill.js +172 -0
- package/dist/frqtl/compat/vendor.js +196 -0
- package/dist/frqtl/node-entry.js +17 -0
- package/dist/frqtl/objects/FrqtlApp.js +2920 -0
- package/dist/frqtl/objects/ObjectFactory.js +296 -0
- package/dist/frqtl/objects/RecipeContext.js +322 -0
- package/dist/frqtl/objects/collectors/DataCollector.js +116 -0
- package/dist/frqtl/objects/constants/WallBehaviors.js +178 -0
- package/dist/frqtl/objects/geometry/SlabFace.js +258 -0
- package/dist/frqtl/objects/instruments/capture-host.js +453 -0
- package/dist/frqtl/objects/instruments/capture.js +710 -0
- package/dist/frqtl/objects/instruments/hosted-eyes.js +984 -0
- package/dist/frqtl/objects/kinds-entry.js +14 -0
- package/dist/frqtl/objects/kinds.js +190 -0
- package/dist/frqtl/objects/objects/Box.js +273 -0
- package/dist/frqtl/objects/objects/Bullet.js +155 -0
- package/dist/frqtl/objects/objects/CircuitGate.js +380 -0
- package/dist/frqtl/objects/objects/CircuitProbe.js +214 -0
- package/dist/frqtl/objects/objects/DirectedTunnel.js +411 -0
- package/dist/frqtl/objects/objects/EgptFractal.js +164 -0
- package/dist/frqtl/objects/objects/LightSource.js +351 -0
- package/dist/frqtl/objects/objects/QuantumEmitter.js +760 -0
- package/dist/frqtl/objects/objects/Tube.js +471 -0
- package/dist/frqtl/objects/objects/absorbRadiation.js +309 -0
- package/dist/frqtl/objects/objects/actionCompiler.js +1747 -0
- package/dist/frqtl/objects/objects/controlAction.js +89 -0
- package/dist/frqtl/objects/objects/controlBind.js +278 -0
- package/dist/frqtl/objects/objects/directedRedirectProgram.js +120 -0
- package/dist/frqtl/objects/objects/emitterProgram.js +209 -0
- package/dist/frqtl/objects/objects/frqtl-control-slider.js +197 -0
- package/dist/frqtl/objects/objects/frqtl-control-sync.js +272 -0
- package/dist/frqtl/objects/objects/frqtl-control-widgets.js +219 -0
- package/dist/frqtl/objects/objects/frqtl-control-write-queue.js +174 -0
- package/dist/frqtl/objects/objects/makeControlsForObject.js +820 -0
- package/dist/frqtl/objects/objects/makeControlsForRenderSurface.js +161 -0
- package/dist/frqtl/objects/objects/slitLinerScatter.js +261 -0
- package/dist/frqtl/objects/objects/sustainedSource.js +298 -0
- package/dist/frqtl/objects/objects/tagger.js +228 -0
- package/dist/frqtl/objects/schema/engine-scopes.js +468 -0
- package/dist/frqtl/objects/schema/index.js +256 -0
- package/dist/frqtl/objects/schema/scopes.js +457 -0
- package/dist/frqtl/objects/schema/validate-descriptor.js +49 -0
- package/dist/frqtl/objects/schema/valueNormalizer.js +366 -0
- package/dist/frqtl/objects/setup/_collisionMatrixLanes.js +66 -0
- package/dist/frqtl/objects/setup/_setupOptions.js +118 -0
- package/dist/frqtl/objects/setup/_worldInit.js +162 -0
- package/dist/frqtl/objects/setup/setupBlackbodySubstrate.js +242 -0
- package/dist/frqtl/objects/setup/setupCircuitBasic.js +447 -0
- package/dist/frqtl/objects/setup/setupCollisionMatrix.js +188 -0
- package/dist/frqtl/objects/setup/setupConeEmitter3D.js +250 -0
- package/dist/frqtl/objects/setup/setupDoubleSlit.js +326 -0
- package/dist/frqtl/objects/setup/setupDoubleSlit_Laser.js +229 -0
- package/dist/frqtl/objects/setup/setupEmpty.js +59 -0
- package/dist/frqtl/objects/setup/setupFxSmoke.js +209 -0
- package/dist/frqtl/objects/setup/setupG1Race.js +80 -0
- package/dist/frqtl/objects/setup/setupG2Sweep.js +89 -0
- package/dist/frqtl/objects/setup/setupG3Collide.js +177 -0
- package/dist/frqtl/objects/setup/setupLightSourceLab.js +277 -0
- package/dist/frqtl/objects/setup/setupOscillator.js +68 -0
- package/dist/frqtl/objects/setup/setupParticleWalk.js +93 -0
- package/dist/frqtl/objects/setup/setupParticleWalk3D.js +133 -0
- package/dist/frqtl/objects/setup/setupSphereEmitter3D.js +1258 -0
- package/dist/frqtl/objects/setup/setupTraceCircuit.js +239 -0
- package/dist/frqtl/objects/setup/setupTunnelLab.js +240 -0
- package/dist/frqtl/objects/setup/setupTunnelPointExit.js +306 -0
- package/dist/frqtl/objects/setup/setupWaveInterference.js +177 -0
- package/dist/frqtl/objects/v1-replacements.js +29 -0
- package/dist/frqtl/package-core.js +23 -0
- package/dist/frqtl/parts/CameraControls.js +643 -0
- package/dist/frqtl/parts/CameraPath.js +575 -0
- package/dist/frqtl/parts/CollisionActions.js +34 -0
- package/dist/frqtl/parts/CollisionTypes.js +30 -0
- package/dist/frqtl/parts/DetectorWall.js +496 -0
- package/dist/frqtl/parts/FrqtlControlOverlay.js +227 -0
- package/dist/frqtl/parts/FrqtlControlsPanel.js +415 -0
- package/dist/frqtl/parts/FrqtlVision.js +818 -0
- package/dist/frqtl/parts/GraphingDetectorWall.js +489 -0
- package/dist/frqtl/parts/LargeObject.js +405 -0
- package/dist/frqtl/parts/LightColor.js +255 -0
- package/dist/frqtl/parts/LiveChart.js +285 -0
- package/dist/frqtl/parts/LogicGate.js +717 -0
- package/dist/frqtl/parts/OvenBox.js +611 -0
- package/dist/frqtl/parts/PointSource.js +762 -0
- package/dist/frqtl/parts/Rectangle.js +200 -0
- package/dist/frqtl/parts/SlitLightSource.js +234 -0
- package/dist/frqtl/parts/SlitScreen.js +628 -0
- package/dist/frqtl/parts/SphereEmitter.js +946 -0
- package/dist/frqtl/parts/Trace.js +508 -0
- package/dist/frqtl/parts/Tunnel.js +1057 -0
- package/dist/frqtl/parts/Wall.js +1211 -0
- package/dist/frqtl/parts/index.js +33 -0
- package/dist/frqtl/scenes/absorbing-wall-3d.js +33 -0
- package/dist/frqtl/scenes/absorbing-wall.js +32 -0
- package/dist/frqtl/scenes/atomic-model.js +88 -0
- package/dist/frqtl/scenes/big-bang.js +46 -0
- package/dist/frqtl/scenes/blackbody.js +81 -0
- package/dist/frqtl/scenes/circuit-sat.js +127 -0
- package/dist/frqtl/scenes/collision-matrix-3d.js +107 -0
- package/dist/frqtl/scenes/counting-wall-3d.js +36 -0
- package/dist/frqtl/scenes/counting-wall.js +38 -0
- package/dist/frqtl/scenes/double-slit.js +31 -0
- package/dist/frqtl/scenes/dse-one-emitter.js +196 -0
- package/dist/frqtl/scenes/dse-one-slit.js +114 -0
- package/dist/frqtl/scenes/dse-photoelectric.js +70 -0
- package/dist/frqtl/scenes/dse-tunnel-rebuild.js +243 -0
- package/dist/frqtl/scenes/dse-two-emitters.js +196 -0
- package/dist/frqtl/scenes/dse-two-slits.js +132 -0
- package/dist/frqtl/scenes/empty.js +14 -0
- package/dist/frqtl/scenes/laser-buildup.js +49 -0
- package/dist/frqtl/scenes/mirror-3d.js +56 -0
- package/dist/frqtl/scenes/mirror-route.js +140 -0
- package/dist/frqtl/scenes/mirror.js +38 -0
- package/dist/frqtl/scenes/omni-3d.js +27 -0
- package/dist/frqtl/scenes/omni-source.js +22 -0
- package/dist/frqtl/scenes/self-interference.js +39 -0
- package/dist/frqtl/scenes/smoking-gun.js +122 -0
- package/dist/frqtl/scenes/straight-walk.js +22 -0
- package/dist/frqtl/scenes/sun.js +39 -0
- package/dist/frqtl/scenes/two-source.js +37 -0
- package/dist/frqtl/scenes/wave.js +26 -0
- package/dist/shim/bundle/frqnb.js +112 -0
- package/dist/shim/bundle/index.js +121 -0
- package/dist/shim/bundle/indexHtml.js +107 -0
- package/dist/shim/bundle/manifest.js +95 -0
- package/dist/shim/bundle/zip.js +243 -0
- package/dist/shim/bus.js +67 -0
- package/dist/shim/controls/index.js +627 -0
- package/dist/shim/controls/registry.js +274 -0
- package/dist/shim/engine/artifact-shell.js +211 -0
- package/dist/shim/engine/boot-phases.js +44 -0
- package/dist/shim/engine/engine-stack-boot.js +59 -0
- package/dist/shim/engine/router.js +690 -0
- package/dist/shim/experiment-frame/index.js +296 -0
- package/dist/shim/expr/ast-schema.js +369 -0
- package/dist/shim/field-descriptor/index.js +325 -0
- package/dist/shim/frame-data/index.js +224 -0
- package/dist/shim/index.js +67 -0
- package/dist/shim/notebook/canvas-guard.js +82 -0
- package/dist/shim/notebook/catalog.js +35 -0
- package/dist/shim/notebook/format.js +736 -0
- package/dist/shim/notebook/frqtl-setups-importmap.js +81 -0
- package/dist/shim/notebook/kernel.js +671 -0
- package/dist/shim/notebook/knob.js +150 -0
- package/dist/shim/notebook/module-resolver.js +260 -0
- package/dist/shim/notebook/notebook-knobs.js +65 -0
- package/dist/shim/notebook/produced-bindings.js +67 -0
- package/dist/shim/notebook/realm-registry.js +121 -0
- package/dist/shim/notebook/realm-transport.js +73 -0
- package/dist/shim/notebook/setup-builder.js +507 -0
- package/dist/shim/notebook/store.js +159 -0
- package/dist/shim/notebook/vendor-importmap.js +134 -0
- package/dist/shim/notebook/view-builder.js +189 -0
- package/dist/shim/notebook/view-ctx.js +100 -0
- package/dist/shim/notebook/view-handle.js +202 -0
- package/dist/shim/notebook/warmup.js +102 -0
- package/dist/shim/package.json +4 -0
- package/dist/shim/page-params/index.js +213 -0
- package/dist/shim/project/identity.js +112 -0
- package/dist/shim/project/index.js +19 -0
- package/dist/shim/project/link.js +402 -0
- package/dist/shim/project/node-specifier-hook.mjs +35 -0
- package/dist/shim/project/register-node.mjs +17 -0
- package/dist/shim/project/specifiers.js +106 -0
- package/dist/shim/registry/copy-gate.js +110 -0
- package/dist/shim/registry/exhibits.js +455 -0
- package/dist/shim/registry/experiments.js +215 -0
- package/dist/shim/registry/index.js +19 -0
- package/dist/shim/registry/scene-source.js +157 -0
- package/dist/shim/registry/walkthrough.js +804 -0
- package/dist/shim/render/capture-envelope.js +279 -0
- package/dist/shim/render/heat-colormap.js +92 -0
- package/dist/shim/render/render-stages.js +855 -0
- package/dist/shim/render/sun-look.js +33 -0
- package/dist/shim/render-state/apply.js +262 -0
- package/dist/shim/render-state/index.js +74 -0
- package/dist/shim/rpc/index.js +207 -0
- package/dist/shim/runtime/index.js +1023 -0
- package/dist/shim/storage/boot.js +69 -0
- package/dist/shim/storage/index.js +169 -0
- package/dist/shim/storage/local-storage-provider.js +230 -0
- package/dist/shim/storage/make-namespace-store.js +132 -0
- package/dist/shim/storage/modules.js +249 -0
- package/dist/shim/storage/projects.js +150 -0
- package/llms.txt +12 -0
- package/package.json +63 -4
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/* Copyright 2023-2026 by Essam Abadir */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* three-camera-contract.js — the three.js camera's DECLARATIVE contract: the
|
|
5
|
+
* view PRESETS and the POSE AXES its `getCameraControl()` handle publishes.
|
|
6
|
+
*
|
|
7
|
+
* ## Why this is its own file
|
|
8
|
+
*
|
|
9
|
+
* It is the pure, declarative half of the camera authority: two functions of
|
|
10
|
+
* `(width, height)` returning plain data, with no THREE, no WebGL, and no live
|
|
11
|
+
* provider state. `three-provider.js` (the live half) resolves it and publishes
|
|
12
|
+
* the results on the handle as `ctl.presets` / `ctl.poseFields`; every host —
|
|
13
|
+
* STUDIO's camera strip, the GYM's camera row, an experiment page's own preset
|
|
14
|
+
* buttons — FERRIES those and re-lists nothing. One declaration, N consumers.
|
|
15
|
+
*
|
|
16
|
+
* Keeping it separate also holds `three-provider.js` under the per-file size
|
|
17
|
+
* ceiling that `sdk/_build/verify-publish-surface.mjs` enforces on
|
|
18
|
+
* the copied-verbatim dist directories — that gate's own instruction is to
|
|
19
|
+
* SPLIT at a natural seam rather than raise the ceiling, and "declarative
|
|
20
|
+
* contract vs live renderer" is that seam.
|
|
21
|
+
*
|
|
22
|
+
* ## Node
|
|
23
|
+
*
|
|
24
|
+
* Named ES-module exports, imported by `three-provider.js`; both halves of the contract are testable
|
|
25
|
+
* in plain Node with no THREE instance — see
|
|
26
|
+
* `lib/frqtl/compat/renderer/providers/test/camera-handle-single-source.test.mjs`,
|
|
27
|
+
* which drives every assertion off these two functions.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import * as FieldDescriptorSchema from '../../../../shim/field-descriptor/index.js';
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The ONE camera-preset table — the SINGLE SOURCE for both the preset NAMES
|
|
37
|
+
* and the orbit pose each name resolves to. `getCameraControl()` publishes
|
|
38
|
+
* `Object.keys()` of it as `ctl.presets` and resolves `setPreset(name)`
|
|
39
|
+
* through it, so a preset name is written in exactly one place in the repo.
|
|
40
|
+
*
|
|
41
|
+
* Three pre-computed perspectives on the canonical world frame:
|
|
42
|
+
* X = down the barrel (+X = downrange, out the muzzle) · Y = vertical (grip −Y) ·
|
|
43
|
+
* Z = lateral. Azimuth is measured around the vertical so az=+90 puts the camera
|
|
44
|
+
* downrange (+X) looking back INTO the muzzle; az=0 puts it on +Z (side).
|
|
45
|
+
* down-barrel — DEFAULT: straight down the barrel, the bullet staring at you
|
|
46
|
+
* (zero-momentum air is invisible). Tight distance → big bullet.
|
|
47
|
+
* table-top — down-barrel rotated 90°: eye-level SIDE view (barrel horizontal).
|
|
48
|
+
* rooftop — looking down ~45° in both Y and Z: aerial 3/4.
|
|
49
|
+
* `distance` is relative to the scene size, so a preset frames any scene.
|
|
50
|
+
*
|
|
51
|
+
* @param {number} width scene width in engine pixels
|
|
52
|
+
* @param {number} height scene height in engine pixels
|
|
53
|
+
* @returns {Object<string,{azimuth:number,elevation:number,distance:number}>}
|
|
54
|
+
*/
|
|
55
|
+
function cameraPresets(width, height) {
|
|
56
|
+
var base = Math.max(width, height);
|
|
57
|
+
return {
|
|
58
|
+
'down-barrel': { azimuth: 90, elevation: 0, distance: base * 0.95 },
|
|
59
|
+
'table-top': { azimuth: 0, elevation: 0, distance: base * 1.30 },
|
|
60
|
+
'rooftop': { azimuth: 45, elevation: 45, distance: base * 1.50 }
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The ONE declaration of the camera's POSE AXES — the sliders a host builds.
|
|
66
|
+
*
|
|
67
|
+
* Each entry is a `lib/shim/field-descriptor` descriptor (REUSED, never
|
|
68
|
+
* re-derived). `name` is the `getOrbit()` / `setOrbit()` key, so a host builds
|
|
69
|
+
* one slider per entry and writes back through the key it was handed: it
|
|
70
|
+
* enumerates no axis and invents no range, and a newly declared axis appears
|
|
71
|
+
* in every host with zero host edits.
|
|
72
|
+
*
|
|
73
|
+
* Bounds live HERE because they are the PROVIDER's knowledge, not a host's:
|
|
74
|
+
* azimuth [-180, 180]° — the full turn.
|
|
75
|
+
* elevation [-90, 90]° — pole to pole. (The hosts' old ±85 was a pole
|
|
76
|
+
* guard hand-copied into two files.)
|
|
77
|
+
* distance SCENE-SCALED off `base = max(width,height)` — the same base the
|
|
78
|
+
* preset table frames with: [base/3, base*4], step base/30. A host
|
|
79
|
+
* cannot compute this (it does not know the scene size), which is
|
|
80
|
+
* why the old fixed 200–2400 was a guess that happened to be right
|
|
81
|
+
* only for a 600×400 scene, where this formula reproduces it exactly.
|
|
82
|
+
* roll [-180, 180]° — the full turn. Roll has NO pole, so its bound is a
|
|
83
|
+
* WRAP point, not a clamp: `setOrbit` wraps a roll write mod 360.
|
|
84
|
+
* `default` is the factory's own start pose (azimuth 0, elevation 0 —
|
|
85
|
+
* straight-on-z; distance = base*1.6, what `_init` derives from canvas size;
|
|
86
|
+
* roll 0 — the horizon level).
|
|
87
|
+
*
|
|
88
|
+
* @param {number} width scene width in engine pixels
|
|
89
|
+
* @param {number} height scene height in engine pixels
|
|
90
|
+
* @returns {Array<object>} normalized field descriptors, one per pose axis.
|
|
91
|
+
*/
|
|
92
|
+
function cameraPoseFields(width, height) {
|
|
93
|
+
var normalizeFieldDescriptor = FieldDescriptorSchema.normalizeFieldDescriptor;
|
|
94
|
+
var base = Math.max(width, height);
|
|
95
|
+
return [
|
|
96
|
+
normalizeFieldDescriptor({
|
|
97
|
+
name: 'azimuth', label: 'az', type: 'number', unit: 'deg', default: 0,
|
|
98
|
+
// `wrap: 360` DECLARES the value space is periodic with that period — the
|
|
99
|
+
// axis is a circle, not a segment. Consumers that must interpolate (CameraPath)
|
|
100
|
+
// FERRY this instead of hand-listing which axes are angular; a new wrapping
|
|
101
|
+
// axis therefore gets shortest-arc interpolation with zero consumer edits.
|
|
102
|
+
// It describes the VALUE SPACE, not a storage normalisation (setOrbit wraps
|
|
103
|
+
// roll's stored value; azimuth is periodic without being renormalised).
|
|
104
|
+
constraint: { min: -180, max: 180, integer: false, wrap: 360 },
|
|
105
|
+
widgetConfig: { step: 1 },
|
|
106
|
+
description: 'Orbit angle around the vertical axis, in degrees. az=0 looks straight ' +
|
|
107
|
+
'at the x/y plane from +z; az=+90 puts the camera on +x looking back along it.'
|
|
108
|
+
}),
|
|
109
|
+
normalizeFieldDescriptor({
|
|
110
|
+
name: 'elevation', label: 'el', type: 'number', unit: 'deg', default: 0,
|
|
111
|
+
constraint: { min: -90, max: 90, integer: false },
|
|
112
|
+
widgetConfig: { step: 1 },
|
|
113
|
+
description: 'Orbit angle above (+) / below (−) the horizontal, in degrees. ' +
|
|
114
|
+
'±90 is straight down / straight up the vertical axis.'
|
|
115
|
+
}),
|
|
116
|
+
normalizeFieldDescriptor({
|
|
117
|
+
name: 'distance', label: 'dist', type: 'number', unit: 'px', default: base * 1.6,
|
|
118
|
+
constraint: { min: Math.round(base / 3), max: base * 4, integer: false },
|
|
119
|
+
widgetConfig: { step: Math.max(1, Math.round(base / 30)) },
|
|
120
|
+
description: 'Camera distance from the orbit centre, in engine pixels. Bounds are ' +
|
|
121
|
+
'relative to the scene size (base = max(width,height)) so the slider frames any scene.'
|
|
122
|
+
}),
|
|
123
|
+
normalizeFieldDescriptor({
|
|
124
|
+
name: 'roll', label: 'roll', type: 'number', unit: 'deg', default: 0,
|
|
125
|
+
constraint: { min: -180, max: 180, integer: false, wrap: 360 },
|
|
126
|
+
widgetConfig: { step: 1 },
|
|
127
|
+
description: 'Rotation about the view axis — the horizon tilt, in degrees. It spins ' +
|
|
128
|
+
'the picture in the screen plane without moving the eye: roll=90 puts what was ' +
|
|
129
|
+
'screen-vertical onto the screen horizontal. Unlike elevation it has NO pole, so ' +
|
|
130
|
+
'the range is a WRAP point (mod 360), never a clamp.'
|
|
131
|
+
})
|
|
132
|
+
,
|
|
133
|
+
normalizeFieldDescriptor({
|
|
134
|
+
name: 'target', label: 'centre', type: 'object', unit: 'px', default: null,
|
|
135
|
+
// DECLARED (2026-07-30): `target` is a fully legal settable axis of this
|
|
136
|
+
// camera — `setOrbit({target})` applies it, `getOrbit()` returns it, and
|
|
137
|
+
// `setPreset` pans with it. Omitting it from this list made the DECLARATION
|
|
138
|
+
// disagree with the SURFACE, and anything that validates a pose against the
|
|
139
|
+
// declared axes (CameraPath) therefore rejected `target` waypoints: a 3D
|
|
140
|
+
// camera path could orbit but never dolly/track, which kills any path that follows
|
|
141
|
+
// a moving region.
|
|
142
|
+
//
|
|
143
|
+
// Deliberately carries NO numeric constraint: it is a {x,y,z} POINT, not a
|
|
144
|
+
// scalar. The shared `poseSliderBounds` helper returns null for a descriptor
|
|
145
|
+
// with no range and both slider hosts already skip it ("incomplete range ⇒
|
|
146
|
+
// hide, never a 0–100 default"), so declaring it adds an axis to the CONTRACT
|
|
147
|
+
// without inventing a slider that could not work. Same shape as the 2D
|
|
148
|
+
// camera's own `target` descriptor — one vocabulary, both modes.
|
|
149
|
+
description: 'The world point {x,y,z} the orbit revolves around; null = the ' +
|
|
150
|
+
'scene centre. Pan/track IS target — the same key the 2D camera uses.'
|
|
151
|
+
})
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ── Export ──────────────────────────────────────────────────────────────
|
|
156
|
+
|
|
157
|
+
export {
|
|
158
|
+
cameraPresets,
|
|
159
|
+
cameraPoseFields
|
|
160
|
+
};
|