@descix/frqtl-node 0.6.0-p0.1 → 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 +1 -1
- package/LICENSE.md +664 -0
- package/README.md +1 -1
- package/dist/dist-manifest.json +125 -125
- package/dist/fat/pkg-node/egpt_wasm.js +7 -7
- package/dist/fat/pkg-node/egpt_wasm_bg.wasm +0 -0
- package/dist/fat/pkg-node/package.json +1 -1
- package/dist/frqtl/compat/providers/wasm-engine.js +29 -31
- package/dist/frqtl/compat/providers/wasm-load-browser.js +2 -2
- package/dist/frqtl/compat/renderer/RenderFamily.js +1 -2
- package/dist/frqtl/compat/renderer/RenderMesh.js +2 -3
- package/dist/frqtl/compat/renderer/RenderShape.js +1 -1
- package/dist/frqtl/compat/renderer/captureStill-common.js +1 -2
- package/dist/frqtl/compat/renderer/display-slot.js +1 -1
- package/dist/frqtl/compat/renderer/providers/p5-provider.js +5 -5
- package/dist/frqtl/compat/renderer/providers/three-camera-contract.js +1 -1
- package/dist/frqtl/compat/renderer/providers/three-camera-geometry.js +4 -4
- package/dist/frqtl/compat/renderer/providers/three-provider.js +23 -27
- package/dist/frqtl/compat/renderer/renderCapabilities-common.js +2 -2
- package/dist/frqtl/compat/renderer/renderer-provider-contract.js +1 -1
- package/dist/frqtl/compat/vendor.js +2 -2
- package/dist/frqtl/objects/FrqtlApp.js +22 -24
- package/dist/frqtl/objects/ObjectFactory.js +1 -2
- package/dist/frqtl/objects/constants/WallBehaviors.js +5 -5
- package/dist/frqtl/objects/geometry/SlabFace.js +6 -6
- package/dist/frqtl/objects/instruments/capture-host.js +2 -2
- package/dist/frqtl/objects/instruments/capture.js +4 -5
- package/dist/frqtl/objects/instruments/hosted-eyes.js +3 -4
- package/dist/frqtl/objects/objects/DirectedTunnel.js +10 -11
- package/dist/frqtl/objects/objects/LightSource.js +22 -25
- package/dist/frqtl/objects/objects/QuantumEmitter.js +14 -14
- package/dist/frqtl/objects/objects/Tube.js +14 -14
- package/dist/frqtl/objects/objects/absorbRadiation.js +12 -13
- package/dist/frqtl/objects/objects/actionCompiler.js +52 -52
- package/dist/frqtl/objects/objects/controlAction.js +2 -2
- package/dist/frqtl/objects/objects/controlBind.js +2 -2
- package/dist/frqtl/objects/objects/directedRedirectProgram.js +3 -3
- package/dist/frqtl/objects/objects/emitterProgram.js +9 -9
- package/dist/frqtl/objects/objects/frqtl-control-slider.js +3 -3
- package/dist/frqtl/objects/objects/frqtl-control-sync.js +9 -9
- package/dist/frqtl/objects/objects/frqtl-control-widgets.js +2 -2
- package/dist/frqtl/objects/objects/frqtl-control-write-queue.js +2 -2
- package/dist/frqtl/objects/objects/makeControlsForObject.js +25 -29
- package/dist/frqtl/objects/objects/makeControlsForRenderSurface.js +2 -2
- package/dist/frqtl/objects/objects/slitLinerScatter.js +8 -10
- package/dist/frqtl/objects/objects/sustainedSource.js +15 -16
- package/dist/frqtl/objects/objects/tagger.js +2 -2
- package/dist/frqtl/objects/schema/engine-scopes.js +11 -12
- package/dist/frqtl/objects/schema/index.js +6 -6
- package/dist/frqtl/objects/schema/scopes.js +10 -10
- package/dist/frqtl/objects/setup/_collisionMatrixLanes.js +1 -1
- package/dist/frqtl/objects/setup/setupBlackbodySubstrate.js +1 -1
- package/dist/frqtl/objects/setup/setupCollisionMatrix.js +3 -3
- package/dist/frqtl/objects/setup/setupConeEmitter3D.js +7 -8
- package/dist/frqtl/objects/setup/setupDoubleSlit.js +20 -21
- package/dist/frqtl/objects/setup/setupFxSmoke.js +1 -1
- package/dist/frqtl/objects/setup/setupLightSourceLab.js +23 -26
- package/dist/frqtl/objects/setup/setupSphereEmitter3D.js +39 -40
- package/dist/frqtl/objects/setup/setupTunnelLab.js +17 -19
- package/dist/frqtl/objects/setup/setupTunnelPointExit.js +1 -1
- package/dist/frqtl/objects/setup/setupWaveInterference.js +4 -5
- package/dist/frqtl/objects/v1-replacements.js +0 -1
- package/dist/frqtl/parts/CameraControls.js +5 -5
- package/dist/frqtl/parts/CameraPath.js +1 -1
- package/dist/frqtl/parts/CollisionActions.js +2 -3
- package/dist/frqtl/parts/CollisionTypes.js +1 -2
- package/dist/frqtl/parts/DetectorWall.js +10 -10
- package/dist/frqtl/parts/FrqtlControlsPanel.js +11 -11
- package/dist/frqtl/parts/FrqtlVision.js +1 -1
- package/dist/frqtl/parts/GraphingDetectorWall.js +3 -4
- package/dist/frqtl/parts/LargeObject.js +7 -8
- package/dist/frqtl/parts/LightColor.js +2 -2
- package/dist/frqtl/parts/LiveChart.js +1 -1
- package/dist/frqtl/parts/LogicGate.js +4 -7
- package/dist/frqtl/parts/OvenBox.js +1 -2
- package/dist/frqtl/parts/PointSource.js +10 -11
- package/dist/frqtl/parts/SlitLightSource.js +6 -6
- package/dist/frqtl/parts/SlitScreen.js +14 -14
- package/dist/frqtl/parts/SphereEmitter.js +24 -24
- package/dist/frqtl/parts/Tunnel.js +17 -17
- package/dist/frqtl/parts/Wall.js +17 -17
- package/dist/frqtl/scenes/dse-one-emitter.js +1 -1
- package/dist/frqtl/scenes/dse-one-slit.js +2 -2
- package/dist/frqtl/scenes/dse-photoelectric.js +3 -3
- package/dist/frqtl/scenes/dse-tunnel-rebuild.js +5 -6
- package/dist/frqtl/scenes/dse-two-emitters.js +1 -1
- package/dist/frqtl/scenes/dse-two-slits.js +2 -2
- package/dist/frqtl/scenes/laser-buildup.js +1 -1
- package/dist/frqtl/scenes/mirror-3d.js +4 -4
- package/dist/frqtl/scenes/mirror-route.js +9 -9
- package/dist/frqtl/scenes/mirror.js +1 -1
- package/dist/frqtl/scenes/self-interference.js +1 -1
- package/dist/frqtl/scenes/smoking-gun.js +1 -1
- package/dist/frqtl/scenes/sun.js +2 -2
- package/dist/shim/bundle/frqnb.js +3 -3
- package/dist/shim/bundle/index.js +1 -1
- package/dist/shim/bundle/manifest.js +2 -2
- package/dist/shim/bundle/zip.js +1 -1
- package/dist/shim/controls/index.js +14 -14
- package/dist/shim/controls/registry.js +3 -3
- package/dist/shim/engine/artifact-shell.js +1 -2
- package/dist/shim/engine/router.js +15 -17
- package/dist/shim/expr/ast-schema.js +5 -5
- package/dist/shim/field-descriptor/index.js +7 -8
- package/dist/shim/frame-data/index.js +3 -3
- package/dist/shim/index.js +4 -4
- package/dist/shim/notebook/canvas-guard.js +1 -1
- package/dist/shim/notebook/catalog.js +2 -2
- package/dist/shim/notebook/format.js +26 -26
- package/dist/shim/notebook/kernel.js +3 -4
- package/dist/shim/notebook/knob.js +0 -1
- package/dist/shim/notebook/module-resolver.js +6 -6
- package/dist/shim/notebook/produced-bindings.js +1 -1
- package/dist/shim/notebook/setup-builder.js +9 -12
- package/dist/shim/notebook/vendor-importmap.js +1 -1
- package/dist/shim/notebook/view-builder.js +1 -1
- package/dist/shim/notebook/view-ctx.js +1 -1
- package/dist/shim/notebook/warmup.js +2 -2
- package/dist/shim/page-params/index.js +8 -9
- package/dist/shim/registry/copy-gate.js +1 -1
- package/dist/shim/registry/exhibits.js +4 -4
- package/dist/shim/registry/experiments.js +3 -3
- package/dist/shim/registry/walkthrough.js +21 -24
- package/dist/shim/render/render-stages.js +2 -2
- package/dist/shim/render/sun-look.js +2 -2
- package/dist/shim/rpc/index.js +2 -2
- package/dist/shim/runtime/index.js +12 -12
- package/dist/shim/storage/modules.js +8 -8
- package/llms.txt +2 -2
- package/package.json +4 -3
|
@@ -38,12 +38,12 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
38
38
|
this.collidedId = collidedId;
|
|
39
39
|
this.vx = vx;
|
|
40
40
|
this.vy = vy;
|
|
41
|
-
// 3D depth
|
|
41
|
+
// 3D depth: z position + vz velocity, carried alongside the 2D
|
|
42
42
|
// rect (which stays x,y,w,h). For A={x,y} (2D) experiments z stays 0 — the
|
|
43
43
|
// three.js provider populates _posArr z from this; p5 renders the z=0 slice.
|
|
44
44
|
this.z = z != null ? z : 0;
|
|
45
45
|
this.vz = vz != null ? vz : 0;
|
|
46
|
-
// Phase-D COLLECT data bubble
|
|
46
|
+
// Phase-D COLLECT data bubble.
|
|
47
47
|
// Canonical shape: { detection: { detector_name }|null, string_map: { ... }|null }
|
|
48
48
|
// detection — engine MARK/DETECT writes; string_map — opaque user-space data (render.color,
|
|
49
49
|
// render.outline, …) carried verbatim (I1). The typed render section is RETIRED.
|
|
@@ -80,7 +80,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
80
80
|
// into the WASM Rust ABI wire format (PascalCase, Pascal-string charge, null).
|
|
81
81
|
//
|
|
82
82
|
// Relocated from lib/frqtl/objects/constants/CollisionTypes.js and
|
|
83
|
-
// QuantumEmitter.js per
|
|
83
|
+
// QuantumEmitter.js per §13.3 (no engine-sniffing above the shim).
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
86
|
* FRQTL-MAINT (2026-07-01) — normalize an OBJECT-shaped LO rect ({left,top,w,h}
|
|
@@ -459,7 +459,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
459
459
|
* conformance scenario, test) calls this. Published as `EGPTUniverse.create`,
|
|
460
460
|
* so it is reachable wherever the class is — `engine().EGPTUniverse.create` after the
|
|
461
461
|
* boot door (`compat/engine.js`) — with NO host in the way
|
|
462
|
-
* (
|
|
462
|
+
* (the minimal sim's primitive #1).
|
|
463
463
|
*
|
|
464
464
|
* ── Layer 1: API contract ────────────────────────────────────────────────
|
|
465
465
|
*
|
|
@@ -804,7 +804,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
804
804
|
// `_params.iframe_interval_seconds` stayed at 1, and init() passed
|
|
805
805
|
// `iframe_interval_seconds: 1` to the WASM config. Phase B fired every 60 ticks
|
|
806
806
|
// instead of every tick, producing a "flat leaf cloud" for the first second with
|
|
807
|
-
// no emergent composite frames visible.
|
|
807
|
+
// no emergent composite frames visible.
|
|
808
808
|
//
|
|
809
809
|
// Pre-init: the setter updates _params.iframe_interval_seconds, which init()
|
|
810
810
|
// reads to populate the WASM config (the only path to set the WASM interval).
|
|
@@ -878,8 +878,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
878
878
|
// WHAT each option means, its default, and its physics effect live in the
|
|
879
879
|
// INIT_OPTIONS table at the top of this file — the SAME table the unknown-key
|
|
880
880
|
// check above validates against, so the documentation and the check cannot
|
|
881
|
-
// drift apart. Restating them here would be that drift.
|
|
882
|
-
// docs/internal/physics-lab/intuition/engine-globals.md.
|
|
881
|
+
// drift apart. Restating them here would be that drift.
|
|
883
882
|
var wavelengthScale = options.wavelengthScale;
|
|
884
883
|
var stepping = options.stepping; // 'fixed' | 'average' | undefined
|
|
885
884
|
var noEscape = options.noEscape;
|
|
@@ -906,8 +905,8 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
906
905
|
// the dimensionality of the emergent motion. {x} → a 1D oscillator/walk (y,z frozen);
|
|
907
906
|
// {x,y,z} → a 3D isotropic emission (sphere, not cube — see the §6.10 isotropy
|
|
908
907
|
// oracle). capacity()/wavelength scale as the product over active axes. This is the
|
|
909
|
-
// browser-facing entry point for the 1D/3D discrete walk landed in the Rust engine
|
|
910
|
-
//
|
|
908
|
+
// browser-facing entry point for the 1D/3D discrete walk landed in the Rust engine;
|
|
909
|
+
// 2D experiments never set it.
|
|
911
910
|
// stepping — FAIL LOUD on anything that is not one of the two legal samplers. The engine
|
|
912
911
|
// would also reject it (serde names both variants in its unknown-variant error), but
|
|
913
912
|
// catching it here names the option the caller actually typed.
|
|
@@ -991,12 +990,12 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
991
990
|
// serde default ({x,y} 2D) apply, keeping every existing experiment's config
|
|
992
991
|
// (and thus its golden recording) byte-identical.
|
|
993
992
|
//
|
|
994
|
-
// NOTE
|
|
993
|
+
// NOTE: "omission ⇒ byte-identical" is a property of
|
|
995
994
|
// active_axes' default, NOT a general rule for omitted keys. `stepping` below defaults
|
|
996
995
|
// to 'fixed', which is a DELIBERATE behavior change for every caller that omits it —
|
|
997
996
|
// the walk sampler moved. Axis-aligned and stationary scenes are still bit-identical
|
|
998
997
|
// (the two samplers coincide there); off-axis scenes are expected to move, and that
|
|
999
|
-
// movement is the point of the
|
|
998
|
+
// movement is the point of the change, not a regression.
|
|
1000
999
|
if (activeAxes !== undefined && activeAxes !== null) {
|
|
1001
1000
|
config.active_axes = { x: activeAxes.x, y: activeAxes.y, z: activeAxes.z };
|
|
1002
1001
|
}
|
|
@@ -1069,7 +1068,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1069
1068
|
// NO brownian read-back here. The universe that just consumed the config bag IS the
|
|
1070
1069
|
// answer, and `universe.brownianMotion` asks it on every read — so there is nothing to
|
|
1071
1070
|
// copy out at init time and nothing that could go stale afterwards. (A read-back
|
|
1072
|
-
// assignment lived here
|
|
1071
|
+
// assignment lived here once; it was a better-SOURCED cache, not engine truth.)
|
|
1073
1072
|
// Register this universe as the active one so BoundaryFrame.makeLeafFrame
|
|
1074
1073
|
// can forward through its makeLeafFrame door without holding an explicit reference.
|
|
1075
1074
|
_activeUniverse = this;
|
|
@@ -1078,7 +1077,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1078
1077
|
this._capTick = null;
|
|
1079
1078
|
|
|
1080
1079
|
if (this._withInterQuantumCollisions) this._wasm.set_with_inter_quantum_collisions(this._withInterQuantumCollisions);
|
|
1081
|
-
//
|
|
1080
|
+
// When noEscape is set, hard-trap children inside parent rects.
|
|
1082
1081
|
if (noEscape) this._wasm.set_no_escape(true);
|
|
1083
1082
|
};
|
|
1084
1083
|
|
|
@@ -1171,7 +1170,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1171
1170
|
};
|
|
1172
1171
|
|
|
1173
1172
|
/**
|
|
1174
|
-
* Render-intent MERGE stamp (
|
|
1173
|
+
* Render-intent MERGE stamp (provider-side output-boundary marshalling).
|
|
1175
1174
|
*
|
|
1176
1175
|
* READ the frame's CURRENT engine-opaque data bag → MERGE the given render-intent
|
|
1177
1176
|
* string_map keys into its `string_map` (preserving `detection` + any pre-existing
|
|
@@ -1179,10 +1178,10 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1179
1178
|
* BOUNDARY (zero physics, no engine change): a render-intent stamp NEVER clobbers
|
|
1180
1179
|
* other string_map data, and the provider is correct on its OWN — it does not
|
|
1181
1180
|
* depend on the engine's `set_frame_property('data')` happening to merge string_map
|
|
1182
|
-
* (
|
|
1181
|
+
* (Q-A3). Additional render-intent keys (a future `render.shape`,
|
|
1183
1182
|
* `render.outline`, …) drop in by extending `keys` — one seam, no color special-case.
|
|
1184
1183
|
*
|
|
1185
|
-
* NOTE (
|
|
1184
|
+
* NOTE (empirical finding, pkg-node dump): the engine ALREADY merges
|
|
1186
1185
|
* string_map keys and carries `render.color` verbatim across ticks (a live-set
|
|
1187
1186
|
* color persists) — this get→merge→set does not FIX a persistence bug (there is
|
|
1188
1187
|
* none on the emitter path); it DECOUPLES the provider from the engine's merge
|
|
@@ -1221,10 +1220,10 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1221
1220
|
* generic string_map render-intent MERGE (_stampRenderIntentMerge) so it never clobbers other
|
|
1222
1221
|
* bubble keys and additional render-intent keys drop in at the SAME seam.
|
|
1223
1222
|
*
|
|
1224
|
-
* WASM-ONLY render-intent positionals (
|
|
1223
|
+
* WASM-ONLY render-intent positionals (R3-1, DECLARED per the JS-ref-is-a-live-oracle
|
|
1225
1224
|
* rule): `color` (9th), `shape` (10th), `outline` (11th) are OUTPUT-BOUNDARY render marshalling —
|
|
1226
1225
|
* they are stamped onto the engine-opaque string_map here, WASM-side. The frozen JS reference
|
|
1227
|
-
* engine's makeLeafFrame
|
|
1226
|
+
* engine's makeLeafFrame has ONLY the `color` positional (color_override); it
|
|
1228
1227
|
* ignores the shape/outline args (extra JS args = no-op) BY DESIGN — the JS reference is a frozen
|
|
1229
1228
|
* visual fixture (never edited; CLAUDE.md §Engine discipline) and the realm is WASM. This is a
|
|
1230
1229
|
* DOCUMENTED no-op on the JS twin, NOT a silent drop — covered by the render-intent-merge test
|
|
@@ -1247,8 +1246,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1247
1246
|
// allocated (add_dimension), so it is read through the one `fundamentalDimension`
|
|
1248
1247
|
// getter on every mint, never snapshotted.
|
|
1249
1248
|
var lvl = (level != null) ? level : this.fundamentalDimension;
|
|
1250
|
-
// I2 BUGFIX (
|
|
1251
|
-
// oracle — docs/internal/physics-lab/directed-tunnel-scale-sweep/source-invariance.cjs):
|
|
1249
|
+
// I2 BUGFIX (discovered by the LightSource source-invariance oracle):
|
|
1252
1250
|
// the Rust wasm binding's `charge: i32` contract is "0=Positive, 1=Negative,
|
|
1253
1251
|
// ANY OTHER VALUE (canonically -1)=random draw inside make_leaf_frame"
|
|
1254
1252
|
// (egpt_wasm/src/lib.rs make_leaf_frame doc comment) — but this wrapper
|
|
@@ -1271,7 +1269,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1271
1269
|
var chargeArg = (chargeInt === null || chargeInt === undefined) ? -1 : chargeInt;
|
|
1272
1270
|
var handle = this._wasm.make_leaf_frame(
|
|
1273
1271
|
left, top, lvl, (wavelength != null ? wavelength : 0), vx, vy, !!wrap, chargeArg);
|
|
1274
|
-
// Render-intent stamp
|
|
1272
|
+
// Render-intent stamp: color AND/OR shape ride the SAME provider-side
|
|
1275
1273
|
// MERGE seam (get→merge→set) so multiple keys coexist and neither clobbers the
|
|
1276
1274
|
// engine-opaque bubble. Both omitted ⇒ 0 draws, no stamp → byte-identical.
|
|
1277
1275
|
var _intent = null;
|
|
@@ -1387,7 +1385,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1387
1385
|
};
|
|
1388
1386
|
|
|
1389
1387
|
/**
|
|
1390
|
-
* MANDATORY BACKING
|
|
1388
|
+
* MANDATORY BACKING — RE-ATTACH a LargeObject to a (moving)
|
|
1391
1389
|
* backing Frame (a make_leaf_frame handle / FrameId): Bullet-style move-by-frame. Each tick
|
|
1392
1390
|
* the engine re-centers the LO's rect on that frame's position (keeping the LO's own w/h/d).
|
|
1393
1391
|
* Every LO is ALREADY frame-backed at registration; this RE-POINTS it (e.g. Gun / setupG2Sweep
|
|
@@ -1646,7 +1644,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1646
1644
|
/**
|
|
1647
1645
|
* SLICE 3 — set the writable integer counter for a registered LargeObject.
|
|
1648
1646
|
*
|
|
1649
|
-
* B2.1 (Gate-2
|
|
1647
|
+
* B2.1 (Gate-2 binding): count is read from
|
|
1650
1648
|
* TickData.objects[handle].count (the ONE read authority). The pull
|
|
1651
1649
|
* getLargeObjectCount is DELETED — count has a single marshalling path.
|
|
1652
1650
|
*
|
|
@@ -1664,7 +1662,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1664
1662
|
*
|
|
1665
1663
|
* Returns an array of canonical FrameData objects — the SAME shape as
|
|
1666
1664
|
* doTick() already emits (marshalled via _wrapTickData's FrameData path).
|
|
1667
|
-
* NOT a parallel DTO
|
|
1665
|
+
* NOT a parallel DTO.
|
|
1668
1666
|
*
|
|
1669
1667
|
* The WASM ABI returns a JSON-encoded FrameData array. We deserialize and
|
|
1670
1668
|
* pass each frame through the same FrameData constructor used by _wrapTickData
|
|
@@ -1690,7 +1688,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1690
1688
|
|
|
1691
1689
|
// Marshal each raw frame through the canonical _wrapRawFrame() — the SAME
|
|
1692
1690
|
// path _wrapTickData uses for do_tick() output. No parallel DTO: a single
|
|
1693
|
-
// marshaller means z/vz
|
|
1691
|
+
// marshaller means z/vz and the string_map Map→obj normalization
|
|
1694
1692
|
// are inherited here for free instead of being hand-mirrored.
|
|
1695
1693
|
var result = [];
|
|
1696
1694
|
for (var j = 0; j < rawFrames.length; j++) {
|
|
@@ -1708,7 +1706,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
1708
1706
|
* FrameData[] via the SAME marshaller as queryRectFrames (no parallel DTO). DRY: the same
|
|
1709
1707
|
* region.rs evaluator the LO narrow-phase filter uses.
|
|
1710
1708
|
*
|
|
1711
|
-
* WASM-ONLY: the frozen 2D JS reference has no OBB primitive (
|
|
1709
|
+
* WASM-ONLY: the frozen 2D JS reference has no OBB primitive (the fixture
|
|
1712
1710
|
* is never edited); the JS provider FAILS LOUD instead of silently returning [].
|
|
1713
1711
|
*
|
|
1714
1712
|
* @param {number} cx center X (physics px)
|
|
@@ -2055,7 +2053,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
2055
2053
|
// Handle order: 0, 1, 2, ... matches LargeObjectSpec Vec index (same as JS).
|
|
2056
2054
|
// B2.1 — ONE read authority: user space reads count from tickData.objects[handle].count.
|
|
2057
2055
|
// get_large_object_count() (WASM pull) is DELETED (Dispatch C2, 2026-06-21) — this
|
|
2058
|
-
// section is the sole marshalling path for count (
|
|
2056
|
+
// section is the sole marshalling path for count (§10.8 B2.1).
|
|
2059
2057
|
// B2.2 — shape { handle, count } is the canonical key list owned by ObjectCollectedState.
|
|
2060
2058
|
if (raw.objects && Array.isArray(raw.objects) && raw.objects.length > 0) {
|
|
2061
2059
|
if (!td.objects) { td.objects = []; }
|
|
@@ -2084,7 +2082,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
2084
2082
|
/**
|
|
2085
2083
|
* Unregister a large object by handle (SLICE 3, B1).
|
|
2086
2084
|
*
|
|
2087
|
-
* Gate-2
|
|
2085
|
+
* Gate-2 binding (§10.8 B1):
|
|
2088
2086
|
* B1.1 — FAIL-LOUD on unknown handle: throws (propagates Rust Err → JsValue).
|
|
2089
2087
|
* B1.2 — Reuses the ONE integer handle table; handle slot is tombstoned.
|
|
2090
2088
|
* B1.3 — Must be called between ticks.
|
|
@@ -2328,8 +2326,8 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
2328
2326
|
// get_frame_quantum_id first (same as the emitter color stamp).
|
|
2329
2327
|
if (string_map && typeof w.get_frame_quantum_id === 'function') {
|
|
2330
2328
|
var fqid = w.get_frame_quantum_id(frameId);
|
|
2331
|
-
// MERGE (get→merge→set) via the SAME render-intent seam (
|
|
2332
|
-
//
|
|
2329
|
+
// MERGE (get→merge→set) via the SAME render-intent seam (Q-A3 (a):
|
|
2330
|
+
// this stamp previously replace-wrote {string_map}).
|
|
2333
2331
|
if (fqid > 0) { _stampRenderIntentMerge(w, fqid, string_map); }
|
|
2334
2332
|
}
|
|
2335
2333
|
return f;
|
|
@@ -2486,7 +2484,7 @@ import { Rectangle } from '../../parts/Rectangle.js';
|
|
|
2486
2484
|
};
|
|
2487
2485
|
}
|
|
2488
2486
|
|
|
2489
|
-
// _stampRenderIntentMerge is exported for the
|
|
2487
|
+
// _stampRenderIntentMerge is exported for the merge-semantics unit test (mock-wasm, sweep-safe —
|
|
2490
2488
|
// the real WASM color-persistence is verified via pkg-node, like all engine behavior).
|
|
2491
2489
|
export {
|
|
2492
2490
|
makeProvider,
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* probe list (a probe list is a silent search). `load(glueUrl)` takes an explicit URL only for a
|
|
14
14
|
* test that must cache-bust the glue.
|
|
15
15
|
*
|
|
16
|
-
* Artifact-safe init
|
|
16
|
+
* Artifact-safe init:
|
|
17
17
|
* We NEVER call the wasm-pack glue's `default()`/`__wbg_init()` bare (no
|
|
18
18
|
* args) — bare, it builds its own `new URL('egpt_wasm_bg.wasm', import.meta.url)`
|
|
19
19
|
* and does `fetch(urlObject)` internally, which throws `DataCloneError`
|
|
@@ -84,7 +84,7 @@ export async function load(glueUrl) {
|
|
|
84
84
|
// and does `fetch(thatUrlObject)` internally (verified against
|
|
85
85
|
// fat/pkg-web/egpt_wasm.js's own __wbg_init/__wbg_load source).
|
|
86
86
|
//
|
|
87
|
-
// ARTIFACT-SAFE INIT
|
|
87
|
+
// ARTIFACT-SAFE INIT: a claude.ai
|
|
88
88
|
// Artifact runs inside a sandboxed iframe whose `window.fetch` is not
|
|
89
89
|
// a direct network fetch — it is PROXIED to the parent frame via
|
|
90
90
|
// `postMessage`, and every postMessage argument must be structured-
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* RenderFamily — the ONE per-frame render-FAMILY decode authority for the 3D provider.
|
|
5
5
|
*
|
|
6
|
-
* WHY (Red-Team R2-4 §6;
|
|
7
|
-
* §per-frame render-intent resolution): the three.js tick loop used to
|
|
6
|
+
* WHY (Red-Team R2-4 §6; per-frame render-intent resolution): the three.js tick loop used to
|
|
8
7
|
* decide the render path (mesh vs cube vs sphere vs point-sprite) ONCE per tick from a
|
|
9
8
|
* `RenderShape.resolve(null, opts)` / `RenderMesh.resolve(null, opts)` call — frame hard-coded
|
|
10
9
|
* `null`, so a correctly-stamped PER-FRAME `render.shape` / `render.mesh` was silently ignored
|
|
@@ -13,11 +13,10 @@
|
|
|
13
13
|
* + FAIL-LOUD-on-failure live in the renderer provider (three GLTFLoader path). Keeping the
|
|
14
14
|
* resolver pure (no three import) means it runs in pkg-node/conformance unchanged.
|
|
15
15
|
*
|
|
16
|
-
* CANONICAL-STACK NOTE
|
|
16
|
+
* CANONICAL-STACK NOTE: WHICH mesh a frame maps to is a
|
|
17
17
|
* renderer/sugar/user-space CHOICE derived from FrameData (a frame's layer/mass/fullness,
|
|
18
18
|
* or an explicit per-frame `render.mesh` string_map key written by sugar). The engine emits
|
|
19
|
-
* primitives and carries `render.mesh` OPAQUE (I1) — it never interprets it.
|
|
20
|
-
* docs/internal/engine/RENDERER_CONTRACT.md §9.
|
|
19
|
+
* primitives and carries `render.mesh` OPAQUE (I1) — it never interprets it.
|
|
21
20
|
*
|
|
22
21
|
* Priority chain (same shape as RenderShape.resolve):
|
|
23
22
|
* 1. render.mesh key in a FRAME's string_map (per-quantum override; highest priority)
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
* Single-source: the shape VALUE set is owned by lib/shim/frame-data (the foundational
|
|
53
53
|
* cross-engine render-intent contract). RenderShape is the DECODE authority (resolve/
|
|
54
54
|
* isCubeMesh/toUniform) but re-exports the value list rather than re-listing it, so adding
|
|
55
|
-
* a shape is one edit at frame-data
|
|
55
|
+
* a shape is one edit at frame-data.
|
|
56
56
|
*/
|
|
57
57
|
|
|
58
58
|
import * as FrameDataSchema from '../../../shim/frame-data/index.js';
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* captureStill-common.js — the SHARED pixel-readback + bag-assembly owner for every
|
|
5
|
-
* `RendererProvider.captureStill()` implementation (the `composite`-stage tap executor
|
|
6
|
-
* docs/internal/engine/RENDERER_CONTRACT.md §1a.4).
|
|
5
|
+
* `RendererProvider.captureStill()` implementation (the `composite`-stage tap executor).
|
|
7
6
|
*
|
|
8
7
|
* Peer of `renderCapabilities-common.js` in this directory, and it exists for the same
|
|
9
8
|
* reason: without it, `p5-provider.js` and `three-provider.js` would each carry their own
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* display-slot.js — THE DISPLAY SLOT: the ONE answer to "which provider owns the display".
|
|
5
5
|
*
|
|
6
|
-
* ── The
|
|
6
|
+
* ── The rule (RENDERER_CONTRACT §9 + §1a.5) ──────────────────────────────────
|
|
7
7
|
*
|
|
8
8
|
* The DISPLAY provider is boot-fixed; OBSERVERS are live.
|
|
9
9
|
*
|
|
@@ -107,10 +107,10 @@ import * as RendererProviderContract from '../renderer-provider-contract.js';
|
|
|
107
107
|
|
|
108
108
|
// ── renderCapabilities() (OPTIONAL contract method — S5a) ────────────────
|
|
109
109
|
//
|
|
110
|
-
//
|
|
110
|
+
// Studio Controls Realignment §7 r2 item 2/4: renderCapabilities() is an
|
|
111
111
|
// OPTIONAL RendererProvider method (the getCameraControl() precedent — absent
|
|
112
112
|
// ⇒ makeControlsForRenderSurface emits no render controls, never an error).
|
|
113
|
-
// Declares ONLY what THIS provider actually supports (
|
|
113
|
+
// Declares ONLY what THIS provider actually supports (condition
|
|
114
114
|
// "per-provider truth" — no schema-mirror registry claiming a capability a
|
|
115
115
|
// given backend can't honor). p5 supports the THREE universal knobs
|
|
116
116
|
// (shape/colorScheme/renderBaseCanvas — README §3: "both p5 and three
|
|
@@ -124,7 +124,7 @@ import * as RendererProviderContract from '../renderer-provider-contract.js';
|
|
|
124
124
|
// DESCRIPTORS are static metadata (name/type/constraint/unit/default);
|
|
125
125
|
// live VALUES are read separately via FrqtlApp.getRenderOption /
|
|
126
126
|
// isFilterActive. This is what makes it unit-testable in plain Node.
|
|
127
|
-
// S5b DRY tidy (
|
|
127
|
+
// S5b DRY tidy (the 3
|
|
128
128
|
// universal descriptors + the filter loop were hand-copied between this
|
|
129
129
|
// file and three-provider.js): the ONE shared owner is now
|
|
130
130
|
// `renderCapabilities-common.js` — see that file's own docstring.
|
|
@@ -276,7 +276,7 @@ import * as RendererProviderContract from '../renderer-provider-contract.js';
|
|
|
276
276
|
pop();
|
|
277
277
|
continue;
|
|
278
278
|
}
|
|
279
|
-
// Shell SHAPE (
|
|
279
|
+
// Shell SHAPE (R2-3, capability-based, zero engine change): a per-LO
|
|
280
280
|
// shellShape (ferried render.shape vocab) picks the drawn primitive — box/cube →
|
|
281
281
|
// rect, ball/circle/sphere → ellipse (cube/sphere degrade to box/ball in 2D).
|
|
282
282
|
// Absent → the legacy drawAsCircle boolean (byte-identical for every prior LO).
|
|
@@ -329,7 +329,7 @@ import * as RendererProviderContract from '../renderer-provider-contract.js';
|
|
|
329
329
|
if (!tickData || !tickData.frameData) return;
|
|
330
330
|
// LightColor + RenderShape are MANDATORY canonical contracts (the single color/shape
|
|
331
331
|
// sources). A missing one is a hard load-order/packaging error — FAIL LOUD, never a
|
|
332
|
-
// silent fallback to white/'ball' (Invariant 2
|
|
332
|
+
// silent fallback to white/'ball' (Invariant 2).
|
|
333
333
|
var lc = LightColor;
|
|
334
334
|
var rs = RenderShape;
|
|
335
335
|
|
|
@@ -38,7 +38,7 @@ import * as FieldDescriptorSchema from '../../../../shim/field-descriptor/index.
|
|
|
38
38
|
* `Object.keys()` of it as `ctl.presets` and resolves `setPreset(name)`
|
|
39
39
|
* through it, so a preset name is written in exactly one place in the repo.
|
|
40
40
|
*
|
|
41
|
-
* Three pre-computed perspectives on the canonical world frame
|
|
41
|
+
* Three pre-computed perspectives on the canonical world frame:
|
|
42
42
|
* X = down the barrel (+X = downrange, out the muzzle) · Y = vertical (grip −Y) ·
|
|
43
43
|
* Z = lateral. Azimuth is measured around the vertical so az=+90 puts the camera
|
|
44
44
|
* downrange (+X) looking back INTO the muzzle; az=0 puts it on +Z (side).
|
|
@@ -325,8 +325,8 @@
|
|
|
325
325
|
* Successive screen-relative rotations do NOT compose the way three Euler
|
|
326
326
|
* angles applied in a fixed order do — which is exactly why this goes through
|
|
327
327
|
* the orthonormal frame: compose the bag into a basis, rotate the FRAME, then
|
|
328
|
-
* decompose back. `azimuth` is an OUTPUT of that decomposition (
|
|
329
|
-
*
|
|
328
|
+
* decompose back. `azimuth` is an OUTPUT of that decomposition (azimuth is
|
|
329
|
+
* computed as a function of the two), while remaining a
|
|
330
330
|
* writable declarative coordinate through `setOrbit`. `distance` and `target`
|
|
331
331
|
* ride through untouched — a LOOK is never a translation.
|
|
332
332
|
*
|
|
@@ -383,7 +383,7 @@
|
|
|
383
383
|
* the ONE basis, so a positive strafe reads as rightward on screen at every
|
|
384
384
|
* azimuth AND at every roll.
|
|
385
385
|
*
|
|
386
|
-
* **MOVE is ALWAYS screen-relative
|
|
386
|
+
* **MOVE is ALWAYS screen-relative**. The walk is NOT pinned
|
|
387
387
|
* to a ground plane: walking forward while pitched down DESCENDS — this is a
|
|
388
388
|
* fly control, not an FPS ground walk. (The earlier `y: centre.y` pin was the
|
|
389
389
|
* algebraic residue of a retired ground-plane promise; keeping it would have
|
|
@@ -432,7 +432,7 @@
|
|
|
432
432
|
|
|
433
433
|
// ── screenToWorld() analytic camera math (OPTIONAL capability, S5b) ──────
|
|
434
434
|
//
|
|
435
|
-
//
|
|
435
|
+
// Studio Controls Realignment §7 r2 item 4 / §2.5.7 "3D drag": "three:
|
|
436
436
|
// raycast against the object's plane [at its z]". Rather than reach for a
|
|
437
437
|
// LIVE `THREE.Raycaster`/`THREE.Plane` (which would make this untestable in
|
|
438
438
|
// plain Node — makeThreeProvider() itself throws fail-loud without a real
|
|
@@ -215,7 +215,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
215
215
|
|
|
216
216
|
// ── renderCapabilities() (OPTIONAL contract method — S5a) ────────────────
|
|
217
217
|
//
|
|
218
|
-
//
|
|
218
|
+
// Studio Controls Realignment §7 r2 item 2/4 — see p5-provider.js's
|
|
219
219
|
// identical-purpose block for the full rationale (getCameraControl()
|
|
220
220
|
// optional-capability precedent; per-provider truth; module-level free
|
|
221
221
|
// function so no live WebGL/THREE context is required to call it —
|
|
@@ -224,7 +224,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
224
224
|
// declares the R4/R5 effect-layer knobs (godrays/godrayDensity/
|
|
225
225
|
// glowIntensity/heat/smoke) — p5 has no such render path (grep confirms;
|
|
226
226
|
// see p5-provider.js's own capability list, which omits them).
|
|
227
|
-
// S5b DRY tidy (
|
|
227
|
+
// S5b DRY tidy (the 3
|
|
228
228
|
// universal descriptors + the filter loop were hand-copied between this
|
|
229
229
|
// file and p5-provider.js): the ONE shared owner is now
|
|
230
230
|
// `renderCapabilities-common.js` — see that file's own docstring.
|
|
@@ -323,7 +323,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
323
323
|
// construction-time only and had no p5 parity. RenderShape.js is the one shape authority.
|
|
324
324
|
// _currentShapeUniform is set in _renderTick from the experiment's render options.
|
|
325
325
|
var _currentShapeUniform = 0.0; // 0 = ball (default), 1 = box
|
|
326
|
-
// Default orientation convention (STAGE 2
|
|
326
|
+
// Default orientation convention (STAGE 2): x/y = the vertical screen plane,
|
|
327
327
|
// z toward the viewer (right-handed). The scene initially orients with the camera looking
|
|
328
328
|
// STRAIGHT AT the x/y plane from the +z edge of the canvas cube — that is az=0, el=0
|
|
329
329
|
// (pos = (cx, cy, cz+d), forward = (0,0,-1) into the screen). Scene setup = moving the
|
|
@@ -387,13 +387,12 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
387
387
|
// handle getCameraControl() returns shares it. Created on the first subscription.
|
|
388
388
|
var _poseNotice = null;
|
|
389
389
|
|
|
390
|
-
// ── Per-dim render layers (R4-GEO,
|
|
391
|
-
// the "smoke design SETTLED" ruling) ────────────────────────────────────────
|
|
390
|
+
// ── Per-dim render layers (R4-GEO, the geometry-aware effects design) ──────────
|
|
392
391
|
// Replaces the old single _quantaMesh (all non-flash dims merged) + _flashMesh
|
|
393
392
|
// (all flash-eligible dims merged) pair with ONE THREE.Points object per
|
|
394
393
|
// POPULATED (dim, family) bucket — family 'A' (additive, the flash/hot family)
|
|
395
394
|
// or 'N' (normal-blend, everything else). "Dim decides APPEARANCE, position
|
|
396
|
-
// decides OCCLUSION"
|
|
395
|
+
// decides OCCLUSION": a frame's dim and the glow/smoke options pick
|
|
397
396
|
// its color/alpha/blend/paint; every bucket depth-READS (so walls occlude quanta
|
|
398
397
|
// for real — the root-cause fix) but does NOT depth-write (translucent layers
|
|
399
398
|
// never occlude each other via the z-buffer alone — that ordering is the
|
|
@@ -463,7 +462,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
463
462
|
fragmentShader: QUANTA_FRAG,
|
|
464
463
|
transparent: true,
|
|
465
464
|
// depth-READ (walls/any depth-writing geometry occludes quanta for
|
|
466
|
-
// real); depth-WRITE stays OFF ("read not write"
|
|
465
|
+
// real); depth-WRITE stays OFF ("read not write"). Layer
|
|
467
466
|
// vs layer visual ordering is the explicit renderOrder sort below.
|
|
468
467
|
depthTest: true,
|
|
469
468
|
depthWrite: false,
|
|
@@ -564,7 +563,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
564
563
|
var _feedbackScene = null; // SEPARATE scene drawn as a final overlay pass AFTER all FX
|
|
565
564
|
// composites so bloom/god-rays can never wash it out (G2)
|
|
566
565
|
|
|
567
|
-
// ── Sphere InstancedMesh — per-dim baseline (R6,
|
|
566
|
+
// ── Sphere InstancedMesh — per-dim baseline (R6, the in-page ───────────────
|
|
568
567
|
// per-dim matrix drawing: Effect=None -> paint:'sphere', "the 2D coloring
|
|
569
568
|
// extended to 3D"). Mirrors the cube InstancedMesh precedent immediately above
|
|
570
569
|
// (SAME pre-created-white-instanceColor / frustumCulled=false / MeshLambertMaterial-
|
|
@@ -732,7 +731,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
732
731
|
function _loSig(lo, opts) {
|
|
733
732
|
var meshAsset = RenderMesh.resolve(lo, opts);
|
|
734
733
|
var meshStatus = (meshAsset && _meshCache[meshAsset]) ? _meshCache[meshAsset].status : '';
|
|
735
|
-
// lo.rect.d included (
|
|
734
|
+
// lo.rect.d included (structural fix): box-vs-
|
|
736
735
|
// plane can now be DERIVED from rect.d alone (see _buildLoMesh below) —
|
|
737
736
|
// an LO that never sets the explicit lo.shape/lo.depth hint pair still
|
|
738
737
|
// needs its signature sensitive to rect.d so a depth change rebuilds it.
|
|
@@ -854,15 +853,14 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
854
853
|
// become one too). The engine/physics never see this — it is a renderer-only field.
|
|
855
854
|
function _buildLoMesh(lo, opts) {
|
|
856
855
|
var alpha = (lo.alpha !== undefined) ? lo.alpha / 255 : 1.0;
|
|
857
|
-
// Deterministic translucency
|
|
858
|
-
// prerequisite): "translucent LOs read-not-write, opaque LOs write" — the
|
|
856
|
+
// Deterministic translucency: "translucent LOs read-not-write, opaque LOs write" — the
|
|
859
857
|
// SAME depthTest:true/depthWrite:false convention the per-dim quanta layers
|
|
860
858
|
// already follow (see _ensureDimLayer above). Previously EVERY LO material
|
|
861
859
|
// left depthWrite at its THREE default (true) regardless of opacity, so a
|
|
862
860
|
// translucent LO (e.g. a Tube wall at wallOpacity<1) WROTE depth — whether an
|
|
863
861
|
// interior sprite then read as occluded or visible depended on draw/insertion
|
|
864
|
-
// order, not true 3D position (the wall-occlusion inconsistency:
|
|
865
|
-
// see-through where
|
|
862
|
+
// order, not true 3D position (the wall-occlusion inconsistency: one look saw
|
|
863
|
+
// see-through where another saw near-black — both real, nondeterministic).
|
|
866
864
|
// Generalized here for ANY LO (not a Tube special-case): opaque (alpha>=1, the
|
|
867
865
|
// default when lo.alpha is unset) still writes depth as before — zero change
|
|
868
866
|
// for every existing opaque LO (detector walls, source bodies, etc).
|
|
@@ -977,14 +975,13 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
977
975
|
return liveMesh;
|
|
978
976
|
}
|
|
979
977
|
|
|
980
|
-
// BOX-VS-PLANE DERIVATION (
|
|
981
|
-
// _DSE_lab.png", 2026-07-14): "engine emits primitives; renderer
|
|
978
|
+
// BOX-VS-PLANE DERIVATION (structural fix): "engine emits primitives; renderer
|
|
982
979
|
// DERIVES" — a 6-element LO rect (rect.d present and >0) is a real
|
|
983
980
|
// z-slab at the ENGINE level; the renderer should not require a
|
|
984
981
|
// SEPARATE, easy-to-forget lo.shape='box' hint to reflect that (the DSE
|
|
985
982
|
// slabs shipped with correct 6-element rects but no hint, rendering as
|
|
986
983
|
// flat planes while the tunnels next to them correctly rendered as
|
|
987
|
-
// boxes — the SECOND instance of the exact bug
|
|
984
|
+
// boxes — the SECOND instance of the exact bug fixed earlier for
|
|
988
985
|
// SlitScreen/DetectorWall/setupDoubleSlit's walls). Ground-truthed: EVERY
|
|
989
986
|
// current rect.d-bearing LO in this tree (Tube, SlitScreen, DetectorWall,
|
|
990
987
|
// setupDoubleSlit's startWall, the pierced-wall slabs) already explicitly sets
|
|
@@ -1171,7 +1168,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
1171
1168
|
// per-instance transforms and would otherwise cull the WHOLE mesh.
|
|
1172
1169
|
function _buildSphereInstancedMesh(capacity) {
|
|
1173
1170
|
if (!_sphereGeo) {
|
|
1174
|
-
// Low-poly
|
|
1171
|
+
// Low-poly unit sphere — radius 0.5 so a per-instance scale of
|
|
1175
1172
|
// (size,size,size) gives an exact `size`-px diameter, matching the crisp/
|
|
1176
1173
|
// soft Points path's `aSize` (frame.rect.w) convention.
|
|
1177
1174
|
_sphereGeo = new THREE.SphereGeometry(0.5, 8, 6);
|
|
@@ -1360,7 +1357,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
1360
1357
|
// (its quaternion is camera-driven below). The drawn face is the wall: a rotated
|
|
1361
1358
|
// wall draws NO outline of its un-rotated engine rect.
|
|
1362
1359
|
var _deg = (typeof lo.orientationDeg === 'number') ? (((lo.orientationDeg % 360) + 360) % 360) : 0;
|
|
1363
|
-
// R2AX — PITCH (two-axis mirror
|
|
1360
|
+
// R2AX — PITCH (two-axis mirror): tip the plate about
|
|
1364
1361
|
// its OWN long axis (the geometry's local Y after the z-rotation) by the
|
|
1365
1362
|
// ferried pitchDeg. Euler order 'ZYX' = intrinsic z-then-local-y — exactly
|
|
1366
1363
|
// "yaw about world z, then pitch about the plate's own long axis" (the same
|
|
@@ -1369,7 +1366,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
1369
1366
|
var _pitch = (typeof lo.pitchDeg === 'number') ? lo.pitchDeg : 0;
|
|
1370
1367
|
if (!lo.billboard) {
|
|
1371
1368
|
rec.mesh.rotation.order = 'ZYX';
|
|
1372
|
-
// SIGN (3D-loop orientation-inversion fix
|
|
1369
|
+
// SIGN (3D-loop orientation-inversion fix — drawn face
|
|
1373
1370
|
// is truth IN WORLD SPACE): the THREE world holds RAW physics coordinates
|
|
1374
1371
|
// (y-down VALUES; only camera.up is flipped, see _applyOrbit) — the world is
|
|
1375
1372
|
// NOT y-flipped, so yaw draws as +deg, exactly the p5/SlabFace convention
|
|
@@ -1540,7 +1537,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
1540
1537
|
_godrays.lightUV(tickData, _camera, opts.godraySource), opts.godrayDensity, opts.godrays);
|
|
1541
1538
|
}
|
|
1542
1539
|
|
|
1543
|
-
// ── Aim feedback layer update
|
|
1540
|
+
// ── Aim feedback layer update ─────────────────────────────────────────────────
|
|
1544
1541
|
// Gated on opts.aimFeedback (runner-fed, live per frame). 3D-only. Draws, in a SEPARATE
|
|
1545
1542
|
// _feedbackScene rendered as a FINAL overlay pass (see _renderAimFeedbackPass) AFTER every
|
|
1546
1543
|
// FX composite so bloom/god-rays cannot wash it out:
|
|
@@ -1759,7 +1756,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
1759
1756
|
// EXPERIMENTS use false → ZERO change to their render path.
|
|
1760
1757
|
// LightColor + RenderShape are MANDATORY canonical contracts (the single color/shape
|
|
1761
1758
|
// sources). A missing one is a hard load-order/packaging error — FAIL LOUD, never a
|
|
1762
|
-
// silent fallback to a default color/shape (Invariant 2
|
|
1759
|
+
// silent fallback to a default color/shape (Invariant 2).
|
|
1763
1760
|
var lc2 = LightColor;
|
|
1764
1761
|
var rs2 = RenderShape;
|
|
1765
1762
|
// SCENE-DEFAULT shape (opts only, no frame): the scene-wide cube gate below + the default
|
|
@@ -1881,8 +1878,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
1881
1878
|
// additive blend mode.
|
|
1882
1879
|
var plainWantAdditive = (typeof glow === 'number' && glow > 0);
|
|
1883
1880
|
|
|
1884
|
-
// Per-frame render FAMILY (
|
|
1885
|
-
// §per-frame render-intent resolution): each frame's
|
|
1881
|
+
// Per-frame render FAMILY (per-frame render-intent resolution): each frame's
|
|
1886
1882
|
// shape/mesh is resolved PER-FRAME via RenderFamily.resolveRenderFamily(f, opts,
|
|
1887
1883
|
// _is3D) inside the loop below (never the old scene-wide `resolve(null,opts)`).
|
|
1888
1884
|
// The resolved family is folded into the bucket KEY so per-frame ball / box /
|
|
@@ -1898,7 +1894,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
1898
1894
|
var meshByAsset = {}; // assetId -> [frame] (per-frame render.mesh siphon)
|
|
1899
1895
|
|
|
1900
1896
|
// ── Bucket rows into (dim, family) groups — ONE THREE object per bucket.
|
|
1901
|
-
// "Dim decides APPEARANCE, position decides OCCLUSION"
|
|
1897
|
+
// "Dim decides APPEARANCE, position decides OCCLUSION": no
|
|
1902
1898
|
// parent/leaf distinction — a frame is classified by its OWN dim using its
|
|
1903
1899
|
// OWN fullness/box size.
|
|
1904
1900
|
var buckets = {}; // key -> { additive, paint, uShape?, list:[{x,y,z,full,r,g,b,a,size}] }
|
|
@@ -2046,7 +2042,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
2046
2042
|
entry.mesh.visible = drawParticles;
|
|
2047
2043
|
}
|
|
2048
2044
|
|
|
2049
|
-
// ── Camera-distance sort (painter's algorithm
|
|
2045
|
+
// ── Camera-distance sort (painter's algorithm) — farthest
|
|
2050
2046
|
// drawn FIRST so a nearer translucent bucket visually occludes (dims) a
|
|
2051
2047
|
// farther one, exactly like real depth would (only meaningful in 3D; the
|
|
2052
2048
|
// 2D ortho camera has no orbit/depth axis quanta actually vary along). ──
|
|
@@ -2390,7 +2386,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
2390
2386
|
// screen-right. NEITHER changes azimuth, elevation, roll or distance —
|
|
2391
2387
|
// a walk is never a rotation.
|
|
2392
2388
|
//
|
|
2393
|
-
// MOVE is ALWAYS screen-relative
|
|
2389
|
+
// MOVE is ALWAYS screen-relative: the walk is NOT
|
|
2394
2390
|
// pinned to a ground plane, so walking forward while pitched down
|
|
2395
2391
|
// DESCENDS. This is a fly control, not an FPS ground walk — and it is
|
|
2396
2392
|
// what keeps "positive strafe reads as rightward on screen" true at
|
|
@@ -2448,7 +2444,7 @@ import * as ThreeCameraGeometry from './three-camera-geometry.js';
|
|
|
2448
2444
|
renderCapabilities: _renderCapabilitiesThree,
|
|
2449
2445
|
|
|
2450
2446
|
// ── screenToWorld (OPTIONAL convenience capability, S5b) ────────────
|
|
2451
|
-
//
|
|
2447
|
+
// Studio Controls Realignment §7 r2 item 4/§2.5.7 "3D drag":
|
|
2452
2448
|
// "three: raycast against the object's plane [at its z]". Returns
|
|
2453
2449
|
// `null` in 2D mode (no orbit camera to raycast from — mirrors
|
|
2454
2450
|
// `getCameraControl`'s own 2D-mode null) or when the ray is parallel
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* renderCapabilities-common.js — the SHARED universal + filter capability
|
|
5
5
|
* descriptors every `RendererProvider.renderCapabilities()` implementation
|
|
6
|
-
* declares (
|
|
6
|
+
* declares (Studio Controls Realignment S5b — the S5a gate
|
|
7
7
|
* "minor DRY recommendation": `p5-provider.js` and `three-provider.js` had
|
|
8
8
|
* byte-identical `_universalRenderCapabilities` bodies + an identical
|
|
9
9
|
* per-Filters-entry toggle loop, hand-copied across two legitimately-
|
|
@@ -77,7 +77,7 @@ function universalRenderCapabilities(normalizeFieldDescriptor, RenderShapeRef, F
|
|
|
77
77
|
return [
|
|
78
78
|
normalizeFieldDescriptor({
|
|
79
79
|
name: 'shape', type: 'enum', default: 'ball',
|
|
80
|
-
//
|
|
80
|
+
// This is the render-LEVEL DEFAULT shape (per-object sugar like a
|
|
81
81
|
// SphereEmitter's `renderShape` field overrides it per-leaf via render.shape) —
|
|
82
82
|
// labelled "Default Shape" so the scoping reads true. `label` overrides the shown
|
|
83
83
|
// control label only; the capability key stays `shape` (setRenderOption('shape',…)).
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* `RendererProvider` is duck-typed: a BYO renderer is a plain object from a
|
|
7
7
|
* `makeProvider()` factory, registered through the boot-fixed display slot. Nothing is
|
|
8
8
|
* imported to implement it — which is exactly why the METHOD LISTS need one owner. Before
|
|
9
|
-
* this module they existed only as prose in
|
|
9
|
+
* this module they existed only as prose in the renderer contract (§1)
|
|
10
10
|
* and as scattered `typeof provider.X === 'function'` checks in the hosts; a BYO author
|
|
11
11
|
* checking their own object had to hand-copy the list, which is the schema-mirror
|
|
12
12
|
* anti-pattern with the doc as the mirror. THIS FILE is now the owner; the doc cites it.
|