@opsydyn/effect-three 0.3.0 → 0.6.4
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 +56 -0
- package/README.md +15 -1
- package/dist/{index-8cf8t6by.js → index-re3rrfwd.js} +2935 -104
- package/dist/index-re3rrfwd.js.map +56 -0
- package/dist/index-ttwy0znv.js +145 -0
- package/dist/index-ttwy0znv.js.map +12 -0
- package/dist/index.js +557 -147
- package/dist/index.js.map +8 -6
- package/dist/kernel/bodies.d.ts +20 -1
- package/dist/kernel/bodies.d.ts.map +1 -1
- package/dist/kernel/boxSelect.d.ts +22 -0
- package/dist/kernel/boxSelect.d.ts.map +1 -0
- package/dist/kernel/build.d.ts +165 -7
- package/dist/kernel/build.d.ts.map +1 -1
- package/dist/kernel/cameraShake.d.ts.map +1 -1
- package/dist/kernel/describeScene.d.ts +50 -0
- package/dist/kernel/describeScene.d.ts.map +1 -0
- package/dist/kernel/description.d.ts +223 -1
- package/dist/kernel/description.d.ts.map +1 -1
- package/dist/kernel/diff.d.ts +15 -0
- package/dist/kernel/diff.d.ts.map +1 -1
- package/dist/kernel/equality.d.ts +11 -1
- package/dist/kernel/equality.d.ts.map +1 -1
- package/dist/kernel/gizmo.d.ts +69 -0
- package/dist/kernel/gizmo.d.ts.map +1 -0
- package/dist/kernel/history.d.ts +61 -0
- package/dist/kernel/history.d.ts.map +1 -0
- package/dist/kernel/index.d.ts +19 -6
- package/dist/kernel/index.d.ts.map +1 -1
- package/dist/kernel/index.js +124 -3
- package/dist/kernel/index.js.map +1 -1
- package/dist/kernel/inspect.d.ts +85 -0
- package/dist/kernel/inspect.d.ts.map +1 -0
- package/dist/kernel/lineGeometry.d.ts +25 -0
- package/dist/kernel/lineGeometry.d.ts.map +1 -0
- package/dist/kernel/lockstep.d.ts +114 -0
- package/dist/kernel/lockstep.d.ts.map +1 -0
- package/dist/kernel/loop.d.ts.map +1 -1
- package/dist/kernel/materials.d.ts.map +1 -1
- package/dist/kernel/paintOrder.d.ts +53 -0
- package/dist/kernel/paintOrder.d.ts.map +1 -0
- package/dist/kernel/physics.d.ts +39 -0
- package/dist/kernel/physics.d.ts.map +1 -1
- package/dist/kernel/pivot.d.ts +54 -0
- package/dist/kernel/pivot.d.ts.map +1 -0
- package/dist/kernel/pointBuffers.d.ts +17 -0
- package/dist/kernel/pointBuffers.d.ts.map +1 -0
- package/dist/kernel/pointer.d.ts +31 -1
- package/dist/kernel/pointer.d.ts.map +1 -1
- package/dist/kernel/preview.d.ts +32 -0
- package/dist/kernel/preview.d.ts.map +1 -0
- package/dist/kernel/renderKit.d.ts +21 -1
- package/dist/kernel/renderKit.d.ts.map +1 -1
- package/dist/kernel/renderer.d.ts +6 -0
- package/dist/kernel/renderer.d.ts.map +1 -1
- package/dist/kernel/sceneChanges.d.ts +87 -0
- package/dist/kernel/sceneChanges.d.ts.map +1 -0
- package/dist/kernel/sceneGraph.d.ts +9 -1
- package/dist/kernel/sceneGraph.d.ts.map +1 -1
- package/dist/kernel/sceneIndex.d.ts +5 -0
- package/dist/kernel/sceneIndex.d.ts.map +1 -1
- package/dist/kernel/seeded.d.ts +9 -0
- package/dist/kernel/seeded.d.ts.map +1 -0
- package/dist/kernel/shots.d.ts +26 -0
- package/dist/kernel/shots.d.ts.map +1 -0
- package/dist/kernel/tape.d.ts +38 -0
- package/dist/kernel/tape.d.ts.map +1 -0
- package/dist/kernel/timeline.d.ts +60 -0
- package/dist/kernel/timeline.d.ts.map +1 -0
- package/dist/kernel/trail.d.ts +31 -0
- package/dist/kernel/trail.d.ts.map +1 -0
- package/dist/kernel/viewportGizmo.d.ts +25 -0
- package/dist/kernel/viewportGizmo.d.ts.map +1 -0
- package/dist/runtime/Inspector.d.ts +20 -0
- package/dist/runtime/Inspector.d.ts.map +1 -0
- package/dist/runtime/SceneFile.d.ts +462 -0
- package/dist/runtime/SceneFile.d.ts.map +1 -0
- package/dist/runtime/SceneSchema.d.ts +404 -0
- package/dist/runtime/SceneSchema.d.ts.map +1 -1
- package/dist/runtime/errors.d.ts +9 -0
- package/dist/runtime/errors.d.ts.map +1 -1
- package/dist/runtime/index.d.ts +3 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/webgl/index.d.ts.map +1 -1
- package/dist/webgl/index.js +228 -3
- package/dist/webgl/index.js.map +6 -4
- package/dist/webgl/line.d.ts +4 -0
- package/dist/webgl/line.d.ts.map +1 -0
- package/dist/webgl/points.d.ts +4 -0
- package/dist/webgl/points.d.ts.map +1 -0
- package/dist/webgpu/index.d.ts.map +1 -1
- package/dist/webgpu/index.js +206 -26
- package/dist/webgpu/index.js.map +6 -4
- package/dist/webgpu/line.d.ts +4 -0
- package/dist/webgpu/line.d.ts.map +1 -0
- package/dist/webgpu/points.d.ts +4 -0
- package/dist/webgpu/points.d.ts.map +1 -0
- package/package.json +4 -2
- package/src/kernel/bodies.ts +299 -17
- package/src/kernel/boxSelect.ts +73 -0
- package/src/kernel/build.ts +374 -1
- package/src/kernel/cameraShake.ts +3 -13
- package/src/kernel/describeScene.ts +224 -0
- package/src/kernel/description.ts +243 -0
- package/src/kernel/diff.ts +39 -0
- package/src/kernel/equality.ts +123 -0
- package/src/kernel/gizmo.ts +478 -0
- package/src/kernel/history.ts +118 -0
- package/src/kernel/index.ts +110 -1
- package/src/kernel/inspect.ts +214 -0
- package/src/kernel/lineGeometry.ts +75 -0
- package/src/kernel/lockstep.ts +237 -0
- package/src/kernel/loop.ts +7 -0
- package/src/kernel/materials.ts +3 -0
- package/src/kernel/paintOrder.ts +274 -0
- package/src/kernel/physics.ts +86 -1
- package/src/kernel/pivot.ts +418 -0
- package/src/kernel/pointBuffers.ts +115 -0
- package/src/kernel/pointer.ts +98 -17
- package/src/kernel/preview.ts +467 -0
- package/src/kernel/renderKit.ts +23 -1
- package/src/kernel/renderer.ts +6 -0
- package/src/kernel/sceneChanges.ts +265 -0
- package/src/kernel/sceneGraph.ts +354 -11
- package/src/kernel/sceneIndex.ts +8 -0
- package/src/kernel/seeded.ts +18 -0
- package/src/kernel/shots.ts +167 -0
- package/src/kernel/tape.ts +124 -0
- package/src/kernel/timeline.ts +93 -0
- package/src/kernel/trail.ts +170 -0
- package/src/kernel/viewportGizmo.ts +194 -0
- package/src/runtime/Inspector.ts +43 -0
- package/src/runtime/SceneFile.ts +46 -0
- package/src/runtime/SceneSchema.ts +319 -0
- package/src/runtime/errors.ts +6 -0
- package/src/runtime/index.ts +3 -1
- package/src/webgl/index.ts +4 -0
- package/src/webgl/line.ts +66 -0
- package/src/webgl/points.ts +205 -0
- package/src/webgpu/index.ts +4 -0
- package/src/webgpu/line.ts +67 -0
- package/src/webgpu/points.ts +193 -0
- package/dist/index-8cf8t6by.js.map +0 -41
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,61 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.6.4](https://github.com/opsydyn/fold-kit-experiments/compare/effect-three-v0.6.3...effect-three-v0.6.4) (2026-10-30)
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
- **infra:** run the tech radar's Alchemy CLI on its own Effect 4.0.7 again ([6adea0a](https://github.com/opsydyn/fold-kit-experiments/commit/6adea0a8d6ce21eb28cc203c64e95c236cf04220))
|
|
8
|
+
|
|
9
|
+
## [0.6.3](https://github.com/opsydyn/fold-kit-experiments/compare/effect-three-v0.6.2...effect-three-v0.6.3) (2026-10-29)
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
- **deps:** move to FoldKit 0.170 and Effect 4.1 with one Effect throughout ([ef2f8c2](https://github.com/opsydyn/fold-kit-experiments/commit/ef2f8c28215cf4d497b6483e3e3acc12f7a33496))
|
|
14
|
+
|
|
15
|
+
## [0.6.2](https://github.com/opsydyn/fold-kit-experiments/compare/effect-three-v0.6.1...effect-three-v0.6.2) (2026-10-28)
|
|
16
|
+
|
|
17
|
+
### Bug Fixes
|
|
18
|
+
|
|
19
|
+
- **effect-three:** face nested billboards parent first ([094b520](https://github.com/opsydyn/fold-kit-experiments/commit/094b520307fae4b25d41fae3d6d9f0af72d6e103))
|
|
20
|
+
|
|
21
|
+
## [0.6.1](https://github.com/opsydyn/fold-kit-experiments/compare/effect-three-v0.6.0...effect-three-v0.6.1) (2026-10-27)
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
- **effect-three:** let a finger's tap on nothing wander a little ([db9e070](https://github.com/opsydyn/fold-kit-experiments/commit/db9e07046baed1f3e61ba0730e085497d52ba0e1))
|
|
26
|
+
|
|
27
|
+
## [0.6.0](https://github.com/opsydyn/fold-kit-experiments/compare/effect-three-v0.5.0...effect-three-v0.6.0) (2026-10-21)
|
|
28
|
+
|
|
29
|
+
### Features
|
|
30
|
+
|
|
31
|
+
- **effect-three:** snapshot a world on until, and start a run from one ([881d520](https://github.com/opsydyn/fold-kit-experiments/commit/881d5206531c8f0a42fce1e1428034a41e558656))
|
|
32
|
+
- **effect-three:** worlds keep their latest stops, and a run goes back to one ([fef50ab](https://github.com/opsydyn/fold-kit-experiments/commit/fef50abcb7974c8e67242537d8fc38ceb294cb3e))
|
|
33
|
+
|
|
34
|
+
## [0.5.0](https://github.com/opsydyn/fold-kit-experiments/compare/effect-three-v0.4.0...effect-three-v0.5.0) (2026-10-20)
|
|
35
|
+
|
|
36
|
+
### Features
|
|
37
|
+
|
|
38
|
+
- **effect-three:** a scene says which assets it asks for ([219db07](https://github.com/opsydyn/fold-kit-experiments/commit/219db071c91d3f2048610deac68ede3467b5e6d9))
|
|
39
|
+
- **effect-three:** coarser levels of detail on an asset ([ee6929e](https://github.com/opsydyn/fold-kit-experiments/commit/ee6929e4822bad60e705cf3ab4893f07a6d320a8))
|
|
40
|
+
- **effect-three:** physics on the Model's clock, for worlds that must agree ([e91612c](https://github.com/opsydyn/fold-kit-experiments/commit/e91612c50b20be408df2e6e287203456ae45fe1b))
|
|
41
|
+
- **effect-three:** previewSvg draws a scene as SVG without a browser ([c731d12](https://github.com/opsydyn/fold-kit-experiments/commit/c731d1248c5924574fa2dbc3ed343518fa328cba))
|
|
42
|
+
- **effect-three:** worlds that step elsewhere report until once answered ([009a60f](https://github.com/opsydyn/fold-kit-experiments/commit/009a60f2f25acd77071c9e288ba5d6fcd8dfa248))
|
|
43
|
+
|
|
44
|
+
## [0.4.0](https://github.com/opsydyn/fold-kit-experiments/compare/effect-three-v0.3.0...effect-three-v0.4.0) (2026-10-20)
|
|
45
|
+
|
|
46
|
+
### Features
|
|
47
|
+
|
|
48
|
+
- **effect-three:** a HUD, and the viewport gizmo in it ([a1d99d4](https://github.com/opsydyn/fold-kit-experiments/commit/a1d99d477d80744652237c0718fe0f2418490ea8))
|
|
49
|
+
- **effect-three:** a measuring tape, the last widget of Beyond parity 5 ([0a05ae0](https://github.com/opsydyn/fold-kit-experiments/commit/0a05ae04b0ccfd616f945f26429b27acbe79f108))
|
|
50
|
+
- **effect-three:** a scene vocabulary for assistants ([a138ccb](https://github.com/opsydyn/fold-kit-experiments/commit/a138ccb3c38226149b44d7b56ce488be8ebbcd89))
|
|
51
|
+
- **effect-three:** a transform gizmo as data, and as a Foldkit submodel ([3b1e585](https://github.com/opsydyn/fold-kit-experiments/commit/3b1e58535b35669917c3325214199f9264fb314c))
|
|
52
|
+
- **effect-three:** an inspector generated from schemas ([64d1d3b](https://github.com/opsydyn/fold-kit-experiments/commit/64d1d3b8bf9991c57c1cf56b94a8b3f1c773b17d))
|
|
53
|
+
- **effect-three:** box select as data, and as a Foldkit submodel ([498a2ec](https://github.com/opsydyn/fold-kit-experiments/commit/498a2ecd7763208c17b54b85f5cc8af294c7ce9b))
|
|
54
|
+
- **effect-three:** edges, trails, points, sparkles and stars ([f976907](https://github.com/opsydyn/fold-kit-experiments/commit/f9769078724c7ef405728581574d50001f338e81))
|
|
55
|
+
- **effect-three:** lockstep, and the editor edited together across tabs ([b416557](https://github.com/opsydyn/fold-kit-experiments/commit/b416557da1e5b5c0d2669891c41e365f48ca818c))
|
|
56
|
+
- **effect-three:** pivot controls as data, and as a Foldkit submodel ([4284921](https://github.com/opsydyn/fold-kit-experiments/commit/42849211eed2b745c4a43ad42682e2508829901b))
|
|
57
|
+
- **effect-three:** scene files, branching history and review diffs ([ce2c54e](https://github.com/opsydyn/fold-kit-experiments/commit/ce2c54ef7cefa77ab07ee7126782b9abccb15adc))
|
|
58
|
+
|
|
3
59
|
## [0.3.0](https://github.com/opsydyn/fold-kit-experiments/compare/effect-three-v0.2.0...effect-three-v0.3.0) (2026-10-19)
|
|
4
60
|
|
|
5
61
|
### Features
|
package/README.md
CHANGED
|
@@ -47,12 +47,25 @@ const description = scene({
|
|
|
47
47
|
- **Keys are unique across the whole scene.** A node keeps its three.js object while its key and kind stay the same, including when it moves to another group. A different kind under the same key replaces the object in place.
|
|
48
48
|
- **Descriptions are fully specified data.** The constructors fill in defaults, and nothing in a description is a closure or a three.js object.
|
|
49
49
|
- **Shapes:** `box`, `sphere`, `plane`, `cylinder`, `torus`, `cone`, `capsule`, `ring` and `circle`, owned by one mesh or shared through `resources`. Parameter names and defaults are three.js's own. `roundedBox` and `backdrop` are Drei's `RoundedBox` and `Backdrop`, with Drei's defaults.
|
|
50
|
+
- **Lines:** `line({ key, points, width: 3, dashed: true })` is Drei's `Line` (three's fat lines, drawn by the render kit): pixels wide, or scene units with `worldUnits`; one colour or `vertexColors`; `segments: true` for pairs of points (Drei's `Segments`). `catmullRomPoints`, `cubicBezierPoints` and `quadraticBezierPoints` give the points of Drei's curve lines. `mesh({ edges: edges() })` outlines a mesh's hard edges (Drei's `Edges`), and `trail()` on a group or mesh leaves a ribbon behind it (Drei's `Trail`).
|
|
51
|
+
- **Points:** `points({ key, positions, size: 6 })` draws round dots (Drei's `Points` and `PointMaterial`), with a colour and size factor a point if you like; `sparkles()` and `stars()` are Drei's `Sparkles` and `Stars`, seeded so they are the same on every load, moving in scene time. The render kit draws them.
|
|
52
|
+
- **Transform gizmo:** `gizmoNodes(key, gizmo, placement, camera)` draws three's `TransformControls` handles (move, turn, scale; world or local; snaps) as scene nodes, and `pressGizmo` and `dragGizmo` turn the press and drag rays into the next placement, as three's controls would; the Foldkit adapter's `TransformGizmo` is it as a submodel. `basic({ depthTest: false })` draws over everything. `movedAlike(from, to, other)` moves the rest of a selection as the gizmo moved the first. `pivotNodes`, `pressPivot` and `dragPivot` are Drei's `PivotControls` the same way (every handle at once, sized in scene units); the adapter's `PivotControls` is the submodel.
|
|
53
|
+
- **Measuring tape:** `placeTapeEnd(tape(), point)` places a tape's ends where clicks hit the scene, `pointTape` runs it to the pointer while the second is placed, `tapeLength` measures it and `tapeNodes` draws it; the Foldkit adapter's `MeasuringTape` is it as a submodel, its length an overlay at the middle.
|
|
54
|
+
- **Lockstep:** `Lockstep.make`, `submit`, `send`, `receive` and `advance` keep peers that run the same `update` in step: each sends one packet a turn, a turn applies when all are in, inputs in peer order; `admit`, `welcomeDue`, `leave` and `remove` change who is in. The transport is yours (a `BroadcastChannel`, a socket); `SceneSchema.Lockstep(schema)` puts a session in a Model. The editor sample edits together with it, across tabs or through a relay between machines (ADR-013); the tabletop sample shares a physics world with it (ADR-014).
|
|
55
|
+
- **Scene files:** `SceneFile.save(scene)` writes a description as indented JSON in a versioned envelope; `SceneFile.read(text)` reads one back as a `Result`, failing with `UnreadableScene` and where. Fields added since a file was written read at their defaults.
|
|
56
|
+
- **History:** `History.make(value)`, `History.record(history, next, label)`, `undo`, `redo`, `branches`, `chooseBranch` and `jumpTo` keep every Model value as a tree, so a change after an undo starts a branch instead of losing the old future; `SceneSchema.History(schema)` puts one in a Model.
|
|
57
|
+
- **Describing and staging, for assistants:** `describeScene(scene)` lists what a scene contains (camera, things with kind, size, colour and place, lights, bounds, staging) and `formatSummary` writes it as a few lines to read before acting; `shotCamera(camera, box, 'three-quarter')` frames a box from a named angle, and `moodStaging('sunset')` gives a mood's lights, environment and sky.
|
|
58
|
+
- **Inspector:** `Inspector.fields(schema, value)` lists any value's fields from its schema (numbers, text, switches, choices, colours, vectors; kinds and lists read-only), and `Inspector.edit(schema, value, path, next)` sets one and checks the result with the schema, as a `Result`. The Foldkit adapter's `inspectorView` draws them as a form.
|
|
59
|
+
- **Review diffs:** `sceneChanges(before, after)` lists what changed (the kernel's own operations, the scene's settings, its HUD and render textures) and `formatChanges` writes a line for each; `bun run scene:diff a.json b.json` prints them for two scene files.
|
|
60
|
+
- **Previews without a browser:** `previewSvg(description, { width, height, at })` draws a flat-shaded SVG still of a scene anywhere JavaScript runs, for a pull request, a gallery card or a server-rendered placeholder: projected with three's `Projector`, lit by three's diffuse term and painted in the order a binary space partition gives, so a floor never covers what stands on it. No textures, shadows or labels; borrowed models and text show when you pass the `store` that lends them. `bun run scene:preview scene.json preview.svg` draws a scene file ([ADR-016](../../docs/effect-three/adr/016-previews-without-a-browser.md)).
|
|
61
|
+
- **Box select:** `boxSelect(camera, size, from, to, selectable)` returns the keys whose points fall in a box on the canvas, as three's `SelectionBox` (which Drei's `Select` wraps) would select them; the `GestureEnd` event ends a drag that began on nothing. The Foldkit adapter's `BoxSelect` is it as a submodel.
|
|
50
62
|
- **Facing, detail and shake:** `rotation: billboard()` turns a node to face the camera every frame (Drei's `Billboard`, with `lockX`/`lockY`/`lockZ`); `group({ detail: detailed({ distances: [0, 10, 20] }) })` shows one child at a time by the camera's distance (Drei's `Detailed`); and a camera's `shake: cameraShake({ decay: true })` shakes it (Drei's `CameraShake`), a pure function of scene time that reduced motion holds still. A `borrowed` model shown under several keys is cloned, skinned models included (Drei's `Clone`).
|
|
51
63
|
- **Materials:** `basic`, `lambert`, `phong`, `standard`, `physical` and `normalMaterial`, each with opacity, transparency, `side`, wireframe and (lit kinds) flat shading and emission. Defaults are three.js's own. Changing a material within its kind updates it in place; changing its kind replaces it.
|
|
52
64
|
- **Shadows and render settings:** `scene({ render: renderSettings({ shadows: 'soft', toneMapping: 'aces' }) })`, then `castShadow`/`receiveShadow` on meshes and `castShadow` on directional, point and spot lights. Tone mapping defaults to `none` (React Three Fiber defaults to ACES) so colours render exactly as given.
|
|
53
65
|
- **Instancing:** `instances({ key, geometry, material, instances: [instance({ key, position, color })] })` draws many copies in one call. Updates rewrite only the instances that changed, and hits name the instance (`instance` on the event).
|
|
54
66
|
- **Views:** `scene({ views: [view({ key: 'front', camera, rect: { width: 0.5 } }), ...] })` draws several cameras into parts of one canvas; picks use the view under the pointer and report it as `view`.
|
|
55
67
|
- **Post-processing:** `renderSettings({ effects: [bloom({ strength: 1.5 }), vignette()] })` applies three.js's composer passes in order (`bloom`, `vignette`, `film`); with no effects the scene renders straight to the screen.
|
|
68
|
+
- **HUD:** `scene({ hud: hud({ alignment: 'bottom-right', margin: [80, 80], children }) })` draws nodes over the scene (Drei's `Hud`), through a camera measured in CSS pixels whose origin sits `margin` in from the aligned edges; its interactive meshes are picked before the scene. `viewportGizmoNodes(key, camera)` is Drei's `GizmoViewport` for it, and `cameraAlong(camera, axis)` turns a camera to look from an axis; the Foldkit adapter's `ViewportGizmo` is both as a submodel.
|
|
56
69
|
- **Render textures:** `scene({ renderTextures: [renderTexture({ id: 'screen', camera, children })] })` draws a little scene of its own into a texture that any material uses with `map: 'screen'`; it redraws only when its scene changes.
|
|
57
70
|
- **Orbit controls:** `scene({ gestures: 'scene', camera: model.camera })` claims drags, wheel and pinches from the page and reports each as a `Gesture`; `orbit(model.camera, gesture)` returns the next camera, as three.js's `OrbitControls` would move it. A camera's `damping` eases the rendered camera there (a view's too), and `autoRotate` turns it round its target until a gesture, which an `AutoRotated` event precedes: keep it with `autoRotated(model.camera, detail)`. See [ADR-006](../../docs/effect-three/adr/006-controls-as-data.md).
|
|
58
71
|
- **Fitting:** `scene({ measure: ['model'] })` reports the node's world box as a `Measured` event whenever it changes; `fitCamera(camera, box, area)` frames it as Drei's `Bounds` does, and `orbitKey` moves the camera for arrow keys.
|
|
@@ -63,6 +76,7 @@ const description = scene({
|
|
|
63
76
|
- **Stage:** `const { lights, contactShadows, environment } = stage({ radius: 1.2, height: 2 })` is Drei's `Stage` lighting (presets `rembrandt`, `portrait`, `upfront`, `soft`) for content centred on the origin; spread the parts into `scene`. Measure the content (`scene({ measure })`), place it at `centerOffset(box)` (Drei's `Center`), light it with `stage(stageBounds(box))` and frame it with `fitCamera`.
|
|
64
77
|
- **Grids and presets:** `shaderGrid({ key, infinite: true })` is Drei's fading shader `Grid`; `environmentPresetUrl('sunset')` is one of Drei's ten environment HDRs, for `assets.loadEnvironment`.
|
|
65
78
|
- **Physics:** `mesh({ body: body({ collider: 'ball', restitution: 0.6 }) })` under `scene({ physics: physics() })` makes a rigid body the simulation moves; kicks are `impulse: { id, impulse }`, applied once per id, and collisions arrive as `Collision` events. Bodies sit on groups, models and instances too, take colliders of their own (`colliders: [capsuleCollider(…)]`) and report `ContactForce` over a threshold; joints (with motors) go in `physics({ joints })`, and `physics({ debug: true })` draws the colliders. Pass an engine (`loadRapier()` from `@opsydyn/effect-three-rapier`) to the scene graph or the Foldkit environment. See [ADR-007](../../docs/effect-three/adr/007-physics-as-a-pose-source.md).
|
|
79
|
+
- **Physics on the Model's clock:** `physics({ until })` steps the world toward a step and stops there, reporting `PhysicsReached { run, step, checksum }` (after that step's collisions); what the description changes while it waits lands at that step, however the frames fell, so peers and replays get the same world. `Timeline` keeps inputs stamped with their step (`schedule`, `extend`, `reach`, `due`, `until`), and `physics({ run })` starts a world over. The tabletop sample plays physics in lockstep with it ([ADR-014](../../docs/effect-three/adr/014-physics-in-lockstep.md)). `physics({ snapshotAt })` reports a snapshot of the world there, and `physics({ from: { step, snapshot } })` starts a run from one, so a newcomer need not replay the game ([ADR-018](../../docs/effect-three/adr/018-snapshot-welcome.md)). `physics({ keep })` keeps the world's latest stops itself, and `from: { step, snapshot: null }` goes back to one: rollback for an input that came late ([ADR-019](../../docs/effect-three/adr/019-rollback.md)).
|
|
66
80
|
- **XR:** `scene({ xr: xr({ origin: [0, 0, 4] }) })` lets a scene be presented in a WebXR session; in Foldkit, run `environment.xr.enter('immersive-vr')` from a click's Command. The session drives frames, the player stands at `origin`, and controllers and hands hover, click and drag along their rays. Thumbsticks arrive as `XrStick` events (`locomote(model.xr, stick)` snap-turns and steps), buttons as `XrButton`, and in AR with `xr({ hitTest: true })` a select reports the real surface it met (`XrSurface`). `xr({ glide })` glides with the sticks and reports `XrMoved`. `group({ follow: jointSpace('right', 'index-finger-tip') })` rides a tracked space (also `headSpace()`, `controllerSpace(hand)`, `anchorSpace(id)`, `planeSpace(id)`), hidden while it is not tracked; `xr({ anchors: [xrAnchor({ id, position })] })` anchors places in the room, `xr({ planes: true })` reports detected planes as `XrPlanes`, `xr({ meshes: true })` detected meshes as `XrMeshes` (draw one with `mesh({ geometry: xrMesh(id) })` in a group following `meshSpace(id)`), and `xr({ domOverlay: true })` overlays the scene's element. See [ADR-008](../../docs/effect-three/adr/008-immersive-sessions.md).
|
|
67
81
|
- **Cameras:** `perspectiveCamera({ fov })` or `orthographicCamera({ zoom })`. As in React Three Fiber, an orthographic frustum follows the viewport in CSS pixels, with `zoom` in pixels per world unit.
|
|
68
82
|
- **Lights:** `ambientLight`, `directionalLight`, `pointLight`, `spotLight` (aimed at a world-space `target`) and `hemisphereLight`, with three.js defaults.
|
|
@@ -96,7 +110,7 @@ const environment = Layer.mergeAll(ResourceRegistry.layer, FrameSource.layer(sch
|
|
|
96
110
|
| Owned | `geometry: box(...)`, `material: standard(...)` | Created for one mesh, disposed with it. Owned material changes are applied in place. |
|
|
97
111
|
| Shared | `sharedGeometry(id)`, `sharedMaterial(id)` plus a `resources` definition | Created on first use, reference-counted across every scene using the same `ResourceRegistry`, disposed when the last user releases it. Changing a shared material updates it in place; changing a shared geometry swaps a new one onto every user and disposes the old one. |
|
|
98
112
|
|
|
99
|
-
Borrowed objects, textures and geometries are the application's own: lend them to the store and the library shows them but never disposes them.
|
|
113
|
+
Borrowed objects, textures and geometries are the application's own: lend them to the store and the library shows them but never disposes them. Or let a scene ask for them: `scene({ assets: [modelAsset({ id: 'car', url: 'car.glb' })] })` names what it needs, and the host (the Foldkit adapter's environment) loads each once, cancels a load no scene asks for any more, and frees it when the last scene stops asking ([ADR-015](../../docs/effect-three/adr/015-assets-a-scene-asks-for.md)); `textureAsset`, `environmentAsset` and `fontAsset` are the others. Coarser `levels` (`modelAsset({ id, url, levels: ['car-low.glb'] })`) stream in first: each is shown as it arrives until the finest replaces it.
|
|
100
114
|
|
|
101
115
|
```ts
|
|
102
116
|
const withdraw = store.lend('car', gltf.scene); // then: borrowed({ key: 'car', id: 'car' })
|