@opsydyn/effect-three 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/LICENSE +21 -0
- package/README.md +191 -2
- package/dist/index-4045wme0.js +129 -0
- package/dist/index-4045wme0.js.map +10 -0
- package/dist/index-ef8pbv9g.js +5118 -0
- package/dist/index-ef8pbv9g.js.map +40 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1361 -0
- package/dist/index.js.map +14 -0
- package/dist/kernel/animation.d.ts +14 -0
- package/dist/kernel/animation.d.ts.map +1 -0
- package/dist/kernel/behaviours.d.ts +16 -0
- package/dist/kernel/behaviours.d.ts.map +1 -0
- package/dist/kernel/bodies.d.ts +60 -0
- package/dist/kernel/bodies.d.ts.map +1 -0
- package/dist/kernel/bodySources.d.ts +47 -0
- package/dist/kernel/bodySources.d.ts.map +1 -0
- package/dist/kernel/build.d.ts +564 -0
- package/dist/kernel/build.d.ts.map +1 -0
- package/dist/kernel/cameraMotion.d.ts +39 -0
- package/dist/kernel/cameraMotion.d.ts.map +1 -0
- package/dist/kernel/clock.d.ts +17 -0
- package/dist/kernel/clock.d.ts.map +1 -0
- package/dist/kernel/contactShadowPasses.d.ts +47 -0
- package/dist/kernel/contactShadowPasses.d.ts.map +1 -0
- package/dist/kernel/description.d.ts +1120 -0
- package/dist/kernel/description.d.ts.map +1 -0
- package/dist/kernel/diff.d.ts +90 -0
- package/dist/kernel/diff.d.ts.map +1 -0
- package/dist/kernel/environmentPresets.d.ts +30 -0
- package/dist/kernel/environmentPresets.d.ts.map +1 -0
- package/dist/kernel/equality.d.ts +64 -0
- package/dist/kernel/equality.d.ts.map +1 -0
- package/dist/kernel/frames.d.ts +55 -0
- package/dist/kernel/frames.d.ts.map +1 -0
- package/dist/kernel/index.d.ts +37 -0
- package/dist/kernel/index.d.ts.map +1 -0
- package/dist/kernel/index.js +335 -0
- package/dist/kernel/index.js.map +9 -0
- package/dist/kernel/instances.d.ts +26 -0
- package/dist/kernel/instances.d.ts.map +1 -0
- package/dist/kernel/labels.d.ts +45 -0
- package/dist/kernel/labels.d.ts.map +1 -0
- package/dist/kernel/loop.d.ts +49 -0
- package/dist/kernel/loop.d.ts.map +1 -0
- package/dist/kernel/materials.d.ts +24 -0
- package/dist/kernel/materials.d.ts.map +1 -0
- package/dist/kernel/motion.d.ts +36 -0
- package/dist/kernel/motion.d.ts.map +1 -0
- package/dist/kernel/orbit.d.ts +127 -0
- package/dist/kernel/orbit.d.ts.map +1 -0
- package/dist/kernel/overlays.d.ts +16 -0
- package/dist/kernel/overlays.d.ts.map +1 -0
- package/dist/kernel/performance.d.ts +41 -0
- package/dist/kernel/performance.d.ts.map +1 -0
- package/dist/kernel/physics.d.ts +166 -0
- package/dist/kernel/physics.d.ts.map +1 -0
- package/dist/kernel/physicsDebug.d.ts +18 -0
- package/dist/kernel/physicsDebug.d.ts.map +1 -0
- package/dist/kernel/pointer.d.ts +357 -0
- package/dist/kernel/pointer.d.ts.map +1 -0
- package/dist/kernel/renderKit.d.ts +48 -0
- package/dist/kernel/renderKit.d.ts.map +1 -0
- package/dist/kernel/renderer.d.ts +83 -0
- package/dist/kernel/renderer.d.ts.map +1 -0
- package/dist/kernel/resources.d.ts +112 -0
- package/dist/kernel/resources.d.ts.map +1 -0
- package/dist/kernel/sceneGraph.d.ts +155 -0
- package/dist/kernel/sceneGraph.d.ts.map +1 -0
- package/dist/kernel/sceneIndex.d.ts +90 -0
- package/dist/kernel/sceneIndex.d.ts.map +1 -0
- package/dist/kernel/stage.d.ts +87 -0
- package/dist/kernel/stage.d.ts.map +1 -0
- package/dist/kernel/textLayout.d.ts +29 -0
- package/dist/kernel/textLayout.d.ts.map +1 -0
- package/dist/kernel/tween.d.ts +35 -0
- package/dist/kernel/tween.d.ts.map +1 -0
- package/dist/kernel/xrInput.d.ts +107 -0
- package/dist/kernel/xrInput.d.ts.map +1 -0
- package/dist/kernel/xrLocomotion.d.ts +38 -0
- package/dist/kernel/xrLocomotion.d.ts.map +1 -0
- package/dist/runtime/FrameSource.d.ts +29 -0
- package/dist/runtime/FrameSource.d.ts.map +1 -0
- package/dist/runtime/ResourceRegistry.d.ts +18 -0
- package/dist/runtime/ResourceRegistry.d.ts.map +1 -0
- package/dist/runtime/SceneRuntime.d.ts +68 -0
- package/dist/runtime/SceneRuntime.d.ts.map +1 -0
- package/dist/runtime/SceneSchema.d.ts +2536 -0
- package/dist/runtime/SceneSchema.d.ts.map +1 -0
- package/dist/runtime/errors.d.ts +19 -0
- package/dist/runtime/errors.d.ts.map +1 -0
- package/dist/runtime/index.d.ts +11 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/webgl/contactShadows.d.ts +5 -0
- package/dist/webgl/contactShadows.d.ts.map +1 -0
- package/dist/webgl/index.d.ts +11 -0
- package/dist/webgl/index.d.ts.map +1 -0
- package/dist/webgl/index.js +239 -0
- package/dist/webgl/index.js.map +13 -0
- package/dist/webgl/shaderGrid.d.ts +27 -0
- package/dist/webgl/shaderGrid.d.ts.map +1 -0
- package/dist/webgl/sky.d.ts +4 -0
- package/dist/webgl/sky.d.ts.map +1 -0
- package/dist/webgpu/contactShadows.d.ts +5 -0
- package/dist/webgpu/contactShadows.d.ts.map +1 -0
- package/dist/webgpu/index.d.ts +10 -0
- package/dist/webgpu/index.d.ts.map +1 -0
- package/dist/webgpu/index.js +216 -0
- package/dist/webgpu/index.js.map +13 -0
- package/dist/webgpu/shaderGrid.d.ts +5 -0
- package/dist/webgpu/shaderGrid.d.ts.map +1 -0
- package/dist/webgpu/sky.d.ts +4 -0
- package/dist/webgpu/sky.d.ts.map +1 -0
- package/package.json +82 -4
- package/src/index.ts +11 -0
- package/src/kernel/animation.ts +24 -0
- package/src/kernel/behaviours.ts +36 -0
- package/src/kernel/bodies.ts +338 -0
- package/src/kernel/bodySources.ts +203 -0
- package/src/kernel/build.ts +1325 -0
- package/src/kernel/cameraMotion.ts +202 -0
- package/src/kernel/clock.ts +35 -0
- package/src/kernel/contactShadowPasses.ts +207 -0
- package/src/kernel/description.ts +1197 -0
- package/src/kernel/diff.ts +383 -0
- package/src/kernel/environmentPresets.ts +38 -0
- package/src/kernel/equality.ts +604 -0
- package/src/kernel/frames.ts +124 -0
- package/src/kernel/index.ts +274 -0
- package/src/kernel/instances.ts +97 -0
- package/src/kernel/labels.ts +48 -0
- package/src/kernel/loop.ts +248 -0
- package/src/kernel/materials.ts +258 -0
- package/src/kernel/motion.ts +75 -0
- package/src/kernel/orbit.ts +554 -0
- package/src/kernel/overlays.ts +130 -0
- package/src/kernel/performance.ts +101 -0
- package/src/kernel/physics.ts +361 -0
- package/src/kernel/physicsDebug.ts +68 -0
- package/src/kernel/pointer.ts +785 -0
- package/src/kernel/renderKit.ts +53 -0
- package/src/kernel/renderer.ts +136 -0
- package/src/kernel/resources.ts +504 -0
- package/src/kernel/sceneGraph.ts +1440 -0
- package/src/kernel/sceneIndex.ts +219 -0
- package/src/kernel/stage.ts +157 -0
- package/src/kernel/textLayout.ts +102 -0
- package/src/kernel/tween.ts +80 -0
- package/src/kernel/xrInput.ts +230 -0
- package/src/kernel/xrLocomotion.ts +72 -0
- package/src/runtime/FrameSource.ts +41 -0
- package/src/runtime/ResourceRegistry.ts +24 -0
- package/src/runtime/SceneRuntime.ts +229 -0
- package/src/runtime/SceneSchema.ts +983 -0
- package/src/runtime/errors.ts +18 -0
- package/src/runtime/index.ts +10 -0
- package/src/webgl/contactShadows.ts +67 -0
- package/src/webgl/index.ts +19 -0
- package/src/webgl/shaderGrid.ts +196 -0
- package/src/webgl/sky.ts +42 -0
- package/src/webgpu/contactShadows.ts +83 -0
- package/src/webgpu/index.ts +19 -0
- package/src/webgpu/shaderGrid.ts +158 -0
- package/src/webgpu/sky.ts +35 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/kernel/description.ts", "../src/kernel/animation.ts", "../src/kernel/motion.ts", "../src/kernel/behaviours.ts", "../src/kernel/materials.ts", "../src/kernel/instances.ts", "../src/kernel/equality.ts", "../src/kernel/performance.ts", "../src/kernel/tween.ts", "../src/kernel/build.ts", "../src/kernel/sceneIndex.ts", "../src/kernel/diff.ts", "../src/kernel/resources.ts", "../src/kernel/textLayout.ts", "../src/kernel/clock.ts", "../src/kernel/frames.ts", "../src/kernel/orbit.ts", "../src/kernel/overlays.ts", "../src/kernel/physics.ts", "../src/kernel/xrLocomotion.ts", "../src/kernel/xrInput.ts", "../src/kernel/environmentPresets.ts", "../src/kernel/stage.ts", "../src/kernel/loop.ts", "../src/kernel/pointer.ts", "../src/kernel/renderer.ts", "../src/kernel/sceneGraph.ts", "../src/kernel/bodies.ts", "../src/kernel/bodySources.ts", "../src/kernel/physicsDebug.ts", "../src/kernel/cameraMotion.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Scene descriptions: plain, immutable data with no closures and no three.js objects.\n *\n * Descriptions are fully specified (normalised). Defaults are filled in by the public\n * constructors and the runtime Schema, so the kernel can diff without guessing.\n *\n * @module\n */\n\n/** A three-component vector `[x, y, z]`. */\nexport type Vec3 = readonly [x: number, y: number, z: number];\n\n/** A rotation axis for behaviours. */\nexport type Axis = 'x' | 'y' | 'z';\n\n/** A colour as a 24-bit RGB integer, for example `0x3366ff`. */\nexport type Rgb = number;\n\n/**\n * Rotation is owned by exactly one source (ADR: D4).\n *\n * - `Fixed`: the model owns the Euler angles.\n * - `Spin`: a behaviour owns them. The angle is a pure function of elapsed scene time:\n * `phase + radiansPerSecond * elapsedSeconds` about `axis`, other axes zero.\n */\nexport type Rotation =\n | { readonly _tag: 'Fixed'; readonly euler: Vec3 }\n | {\n readonly _tag: 'Spin';\n readonly axis: Axis;\n readonly radiansPerSecond: number;\n readonly phase: number;\n };\n\n/** Box geometry parameters. */\nexport type BoxGeometry = {\n readonly _tag: 'Box';\n readonly width: number;\n readonly height: number;\n readonly depth: number;\n};\n\n/** UV sphere geometry parameters. */\nexport type SphereGeometry = {\n readonly _tag: 'Sphere';\n readonly radius: number;\n readonly widthSegments: number;\n readonly heightSegments: number;\n};\n\n/** A flat rectangle in the XY plane, facing +Z. */\nexport type PlaneGeometry = {\n readonly _tag: 'Plane';\n readonly width: number;\n readonly height: number;\n};\n\n/** Cylinder (or cone, with one radius zero) along the Y axis. */\nexport type CylinderGeometry = {\n readonly _tag: 'Cylinder';\n readonly radiusTop: number;\n readonly radiusBottom: number;\n readonly height: number;\n readonly radialSegments: number;\n};\n\n/** A torus (ring doughnut) in the XY plane, around the Z axis. */\nexport type TorusGeometry = {\n readonly _tag: 'Torus';\n readonly radius: number;\n readonly tube: number;\n readonly radialSegments: number;\n readonly tubularSegments: number;\n};\n\n/** A cone along the Y axis, point up. */\nexport type ConeGeometry = {\n readonly _tag: 'Cone';\n readonly radius: number;\n readonly height: number;\n readonly radialSegments: number;\n};\n\n/** A capsule along the Y axis: a cylinder of `height` with hemispherical caps. */\nexport type CapsuleGeometry = {\n readonly _tag: 'Capsule';\n readonly radius: number;\n readonly height: number;\n readonly capSegments: number;\n readonly radialSegments: number;\n};\n\n/** A flat ring (annulus) in the XY plane, facing +Z. */\nexport type RingGeometry = {\n readonly _tag: 'Ring';\n readonly innerRadius: number;\n readonly outerRadius: number;\n readonly thetaSegments: number;\n};\n\n/** A flat disc in the XY plane, facing +Z. */\nexport type CircleGeometry = {\n readonly _tag: 'Circle';\n readonly radius: number;\n readonly segments: number;\n};\n\n/** Any geometry shape the kernel can build. */\n/** A bevel on extruded text, as three.js's `TextGeometry` options. */\nexport type TextBevel = {\n readonly thickness: number;\n readonly size: number;\n readonly offset: number;\n readonly segments: number;\n};\n\n/**\n * Text drawn from a typeface font lent to the store under `font`, as Drei's `Text3D`\n * (three.js's `TextGeometry`). Flat (`ShapeGeometry`) when `depth` is 0 with no bevel.\n * Until the font is lent the geometry is empty; lending it builds the text.\n */\nexport type TextGeometry = {\n readonly _tag: 'Text';\n readonly text: string;\n readonly font: string;\n readonly size: number;\n readonly depth: number;\n readonly curveSegments: number;\n readonly bevel: TextBevel | null;\n /** Centre the text on its origin, as `geometry.center()`; otherwise it starts there. */\n readonly center: boolean;\n /** Extra space after each letter, in ems (multiples of `size`). */\n readonly letterSpacing: number;\n /** Line spacing as a multiple of the font's own. */\n readonly lineHeight: number;\n /** Where each line sits within the widest. */\n readonly align: TextAlign;\n};\n\n/** Where each line of text sits within the widest: troika's `textAlign`. */\nexport type TextAlign = 'left' | 'center' | 'right';\n\nexport type ShapeGeometry =\n | TextGeometry\n | BoxGeometry\n | SphereGeometry\n | PlaneGeometry\n | CylinderGeometry\n | TorusGeometry\n | ConeGeometry\n | CapsuleGeometry\n | RingGeometry\n | CircleGeometry;\n\n/** Which faces a material draws. */\nexport type MaterialSide = 'front' | 'back' | 'double';\n\n/** An unlit material: flat colour, unaffected by lights. */\nexport type BasicMaterial = {\n readonly _tag: 'Basic';\n readonly color: Rgb;\n /** Id of a texture lent to the store for the colour map, or `null` for none. */\n readonly map: string | null;\n readonly opacity: number;\n readonly transparent: boolean;\n readonly side: MaterialSide;\n readonly wireframe: boolean;\n};\n\n/** A matte (Lambertian) material: cheap per-vertex lighting, no highlights. */\nexport type LambertMaterial = {\n readonly _tag: 'Lambert';\n readonly color: Rgb;\n /** Id of a texture lent to the store for the colour map, or `null` for none. */\n readonly map: string | null;\n readonly emissive: Rgb;\n readonly opacity: number;\n readonly transparent: boolean;\n readonly side: MaterialSide;\n readonly wireframe: boolean;\n readonly flatShading: boolean;\n};\n\n/** A shiny (Blinn-Phong) material with specular highlights. */\nexport type PhongMaterial = {\n readonly _tag: 'Phong';\n readonly color: Rgb;\n /** Id of a texture lent to the store for the colour map, or `null` for none. */\n readonly map: string | null;\n readonly emissive: Rgb;\n readonly specular: Rgb;\n readonly shininess: number;\n readonly opacity: number;\n readonly transparent: boolean;\n readonly side: MaterialSide;\n readonly wireframe: boolean;\n readonly flatShading: boolean;\n};\n\n/** A physically based (metallic-roughness) material. */\nexport type StandardMaterial = {\n readonly _tag: 'Standard';\n readonly color: Rgb;\n /** Id of a texture lent to the store for the colour map, or `null` for none. */\n readonly map: string | null;\n readonly roughness: number;\n readonly metalness: number;\n readonly emissive: Rgb;\n readonly emissiveIntensity: number;\n readonly opacity: number;\n readonly transparent: boolean;\n readonly side: MaterialSide;\n readonly wireframe: boolean;\n readonly flatShading: boolean;\n};\n\n/** A standard material plus clearcoat, transmission (glass-like) and index of refraction. */\nexport type PhysicalMaterial = {\n readonly _tag: 'Physical';\n readonly color: Rgb;\n /** Id of a texture lent to the store for the colour map, or `null` for none. */\n readonly map: string | null;\n readonly roughness: number;\n readonly metalness: number;\n readonly emissive: Rgb;\n readonly emissiveIntensity: number;\n readonly clearcoat: number;\n readonly clearcoatRoughness: number;\n readonly transmission: number;\n readonly ior: number;\n readonly opacity: number;\n readonly transparent: boolean;\n readonly side: MaterialSide;\n readonly wireframe: boolean;\n readonly flatShading: boolean;\n};\n\n/** Colours each face by its normal: useful for debugging geometry. */\nexport type NormalMaterial = {\n readonly _tag: 'Normal';\n readonly opacity: number;\n readonly transparent: boolean;\n readonly side: MaterialSide;\n readonly wireframe: boolean;\n readonly flatShading: boolean;\n};\n\n/**\n * Draws only the shadows falling on it, transparent elsewhere: three.js's\n * `ShadowMaterial`, for grounding objects on a floor that is not drawn.\n */\nexport type ShadowMaterial = {\n readonly _tag: 'Shadow';\n readonly color: Rgb;\n readonly opacity: number;\n};\n\n/** Any material the kernel can build. */\nexport type SurfaceMaterial =\n | ShadowMaterial\n | BasicMaterial\n | LambertMaterial\n | PhongMaterial\n | StandardMaterial\n | PhysicalMaterial\n | NormalMaterial;\n\n/** A geometry owned by one mesh (a shape) or shared by id (`SharedGeometry`). */\nexport type GeometryRef =\n | ShapeGeometry\n | { readonly _tag: 'SharedGeometry'; readonly id: string }\n /**\n * A geometry the application (or an adapter) lends under `id` with\n * `store.lendGeometry`: drawn while lent, empty until then. Never disposed by the scene.\n */\n | { readonly _tag: 'LentGeometry'; readonly id: string };\n\n/** A material owned by one mesh, or shared by id (`SharedMaterial`). */\nexport type MaterialRef =\n | SurfaceMaterial\n | { readonly _tag: 'SharedMaterial'; readonly id: string };\n\n/** A shared geometry definition. */\nexport type GeometryDefinition = { readonly id: string; readonly geometry: ShapeGeometry };\n\n/** A shared material definition. */\nexport type MaterialDefinition = { readonly id: string; readonly material: SurfaceMaterial };\n\n/** Shared resource definitions referenced by `SharedGeometry` and `SharedMaterial`. */\nexport type ResourceDefinitions = {\n readonly geometries: ReadonlyArray<GeometryDefinition>;\n readonly materials: ReadonlyArray<MaterialDefinition>;\n};\n\n/**\n * Names a behaviour registered with the scene, with its numeric parameters: React Three\n * Fiber's `useFrame` animation, as data. The behaviour is a pure function of scene time\n * and these parameters, adding a position offset, a rotation and a scale factor on top\n * of the node's own transform (eased or not), as Drei's `Float` does with an inner group.\n */\nexport type Behave = {\n readonly name: string;\n readonly params: Readonly<Record<string, number>>;\n};\n\n/** How a transition progresses from 0 to 1. */\nexport type Easing = 'linear' | 'easeInOutCubic' | 'easeOutCubic' | 'easeOutBack';\n\n/**\n * How `position` and `scale` reach new values. The Model always owns the target; a\n * transition only decides how the rendered value travels there.\n *\n * - `Instant`: jump to the new value.\n * - `Ease`: travel over `seconds` of scene time. A new target mid-flight restarts the\n * transition from the pose at the last frame, so nothing jumps.\n */\nexport type Transition =\n | { readonly _tag: 'Instant' }\n | { readonly _tag: 'Ease'; readonly seconds: number; readonly easing: Easing };\n\n/** A transform node that may contain children. */\nexport type GroupNode = {\n readonly _tag: 'Group';\n readonly key: string;\n readonly position: Vec3;\n readonly rotation: Rotation;\n readonly scale: Vec3;\n readonly transition: Transition;\n /** A registered behaviour moving the node on top of its transform, or `null`. */\n readonly behaviour: Behave | null;\n /**\n * Makes every mesh inside the group pickable, interactive or not. Events still report\n * the mesh hit; its `path` names this group, so one handler can serve the whole group.\n */\n readonly interactive: boolean;\n readonly children: ReadonlyArray<SceneNode>;\n /** A rigid body whose colliders are every mesh inside the group, or `null`. */\n readonly body: Body | null;\n /**\n * A tracked space the group follows while a session presents the scene (pmndrs/xr's\n * `XRSpace`): it sits where the space is each frame, and is hidden while the space is\n * not tracked (or no session presents). `null` for the group's own transform.\n */\n readonly follow: XrSpace | null;\n};\n\n/** The joints of a tracked hand, as WebXR names them (`XRHandJoint`). */\nexport const handJoints = [\n 'wrist',\n 'thumb-metacarpal',\n 'thumb-phalanx-proximal',\n 'thumb-phalanx-distal',\n 'thumb-tip',\n 'index-finger-metacarpal',\n 'index-finger-phalanx-proximal',\n 'index-finger-phalanx-intermediate',\n 'index-finger-phalanx-distal',\n 'index-finger-tip',\n 'middle-finger-metacarpal',\n 'middle-finger-phalanx-proximal',\n 'middle-finger-phalanx-intermediate',\n 'middle-finger-phalanx-distal',\n 'middle-finger-tip',\n 'ring-finger-metacarpal',\n 'ring-finger-phalanx-proximal',\n 'ring-finger-phalanx-intermediate',\n 'ring-finger-phalanx-distal',\n 'ring-finger-tip',\n 'pinky-finger-metacarpal',\n 'pinky-finger-phalanx-proximal',\n 'pinky-finger-phalanx-intermediate',\n 'pinky-finger-phalanx-distal',\n 'pinky-finger-tip',\n] as const;\n\nexport type HandJoint = (typeof handJoints)[number];\n\n/** Which hand: a tracked hand's, or the controller held in it. */\nexport type Handedness = 'left' | 'right';\n\n/**\n * A space an immersive session tracks: the head, a hand's joint, a controller's grip or\n * pointing ray, an anchor the scene placed (`xr({ anchors })`), a detected plane\n * (`xr({ planes: true })`, ids from `XrPlanes` events) or a detected mesh\n * (`xr({ meshes: true })`, ids from `XrMeshes` events).\n */\nexport type XrSpace =\n | { readonly _tag: 'Head' }\n | { readonly _tag: 'Joint'; readonly hand: Handedness; readonly joint: HandJoint }\n | { readonly _tag: 'Controller'; readonly hand: Handedness; readonly space: 'grip' | 'ray' }\n | { readonly _tag: 'Anchor'; readonly id: string }\n | { readonly _tag: 'Plane'; readonly id: string }\n | { readonly _tag: 'Mesh'; readonly id: string };\n\n/** A renderable mesh. `interactive` meshes take part in pointer hit testing. */\nexport type MeshNode = {\n readonly _tag: 'Mesh';\n readonly key: string;\n readonly position: Vec3;\n readonly rotation: Rotation;\n readonly scale: Vec3;\n readonly transition: Transition;\n /** A registered behaviour moving the node on top of its transform, or `null`. */\n readonly behaviour: Behave | null;\n readonly geometry: GeometryRef;\n readonly material: MaterialRef;\n readonly interactive: boolean;\n /** Casts shadows from lights with `castShadow`, when the scene enables shadows. */\n readonly castShadow: boolean;\n /** Receives shadows, when the scene enables shadows. */\n readonly receiveShadow: boolean;\n /** A rigid body simulating the mesh, when the scene has `physics`; `null` for none. */\n readonly body: Body | null;\n};\n\n/**\n * How a body moves, as react-three-rapier's `RigidBody` `type`:\n *\n * - `dynamic`: the simulation owns its pose from its starting transform.\n * - `fixed`: it never moves; other bodies hit it.\n * - `kinematic`: it follows the node's own transform (with its transition and behaviour),\n * pushing dynamic bodies out of the way.\n */\nexport type BodyType = 'dynamic' | 'fixed' | 'kinematic';\n\n/**\n * The collider made from the mesh's geometry (react-three-rapier's `colliders`):\n * `cuboid` its bounding box, `ball` its bounding sphere, `hull` the convex hull of its\n * vertices, `trimesh` its triangles (for fixed bodies).\n */\nexport type BodyCollider = 'cuboid' | 'ball' | 'hull' | 'trimesh';\n\n/**\n * A collider's own shape, as react-three-rapier's collider components take one\n * (`CuboidCollider`, `BallCollider`, `CapsuleCollider`, `CylinderCollider`,\n * `ConeCollider`): sizes in the body's units. Capsules, cylinders and cones stand along y.\n */\nexport type ColliderShapeDescription =\n | { readonly _tag: 'Cuboid'; readonly halfExtents: Vec3 }\n | { readonly _tag: 'Ball'; readonly radius: number }\n | { readonly _tag: 'Capsule'; readonly halfHeight: number; readonly radius: number }\n | { readonly _tag: 'Cylinder'; readonly halfHeight: number; readonly radius: number }\n | { readonly _tag: 'Cone'; readonly halfHeight: number; readonly radius: number };\n\n/**\n * A collider placed in its body: where its middle is and how it is turned (Euler), and a\n * name collisions report it by (`null` for none).\n */\nexport type ColliderDescription = {\n readonly shape: ColliderShapeDescription;\n readonly position: Vec3;\n readonly rotation: Vec3;\n readonly name: string | null;\n};\n\n/**\n * A rigid body (react-three-rapier `RigidBody` at `ae5c3fe`). The node's transform is\n * where a dynamic body starts; changing its position or rotation later teleports it there\n * at rest. An `impulse` is applied once, when its `id` is new.\n */\nexport type Body = {\n readonly type: BodyType;\n readonly collider: BodyCollider;\n /** Total mass; `null` for density 1 over the collider's volume (Rapier's default). */\n readonly mass: number | null;\n readonly friction: number;\n readonly restitution: number;\n readonly linearDamping: number;\n readonly angularDamping: number;\n readonly gravityScale: number;\n /** Continuous collision detection, for fast small bodies. */\n readonly ccd: boolean;\n /** Reports overlaps as collisions without pushing anything. */\n readonly sensor: boolean;\n /** Velocities it starts with. */\n readonly linearVelocity: Vec3;\n readonly angularVelocity: Vec3;\n readonly impulse: { readonly id: number; readonly impulse: Vec3 } | null;\n /**\n * Colliders of its own, replacing those worked out from its geometry (`collider`), as\n * react-three-rapier's `colliders={false}` with collider children; `null` for those.\n * Sized in the body's units and scaled with it.\n */\n readonly colliders: ReadonlyArray<ColliderDescription> | null;\n /**\n * Report contact forces above this many newtons as `ContactForce` events\n * (react-three-rapier's `onContactForce`, Rapier's `contactForceEventThreshold`); `null`\n * for none. Rapier reports every step a contact pushes that hard, so set it high.\n */\n readonly contactForces: number | null;\n /**\n * Which bodies it collides with at all (react-three-rapier's `collisionGroups`); `null`\n * for every body. Two bodies collide when each is in a group the other's filters name.\n */\n readonly collisionGroups: InteractionGroups | null;\n /**\n * Which bodies push it back (`solverGroups`): contacts still happen and are reported,\n * but only these groups exert forces on each other; `null` for every body.\n */\n readonly solverGroups: InteractionGroups | null;\n};\n\n/**\n * Groups for collision filtering, as react-three-rapier's `interactionGroups`: the groups\n * (0 to 15) a body is in, and those it interacts with (`null` for all of them).\n */\nexport type InteractionGroups = {\n readonly memberships: ReadonlyArray<number>;\n readonly filters: ReadonlyArray<number> | null;\n};\n\n/**\n * The scene's physics world (react-three-rapier `Physics`): gravity, pausing, and the\n * fixed step it advances by, interpolating poses between steps.\n */\nexport type Physics = {\n readonly gravity: Vec3;\n readonly paused: boolean;\n readonly timeStep: number;\n readonly interpolate: boolean;\n /** Draw every collider and joint as lines, as react-three-rapier's `<Physics debug>`. */\n readonly debug: boolean;\n /** Joints between bodies, each active while both its bodies exist. */\n readonly joints: ReadonlyArray<Joint>;\n};\n\n/** A body a joint holds: a node's, or one instance's of an instances node. */\nexport type BodyRef = { readonly key: string; readonly instance: string | null };\n\n/** A joint's range of motion, `[min, max]`: radians for a revolute joint, units for a prismatic one. */\nexport type JointLimits = readonly [min: number, max: number];\n\n/**\n * Drives a hinge or slider toward `position` (radians or units) at `velocity`, as Rapier's\n * `configureMotor(targetPos, targetVel, stiffness, damping)`: a spring of `stiffness` pulls\n * toward the position, and `damping` toward the velocity. A velocity motor has stiffness 0;\n * a position motor, velocity 0.\n */\nexport type JointMotor = {\n readonly position: number;\n readonly velocity: number;\n readonly stiffness: number;\n readonly damping: number;\n};\n\n/**\n * How a joint holds its two bodies: Rapier's impulse joints, as react-three-rapier's\n * `useFixedJoint`, `useSphericalJoint`, `useRevoluteJoint`, `usePrismaticJoint`,\n * `useRopeJoint` and `useSpringJoint` make them (`ae5c3fe`, `src/hooks/joints.ts`).\n */\nexport type JointKind =\n /** No relative motion: each body's frame (Euler angles) at its anchor coincide. */\n | { readonly _tag: 'Fixed'; readonly frameA: Vec3; readonly frameB: Vec3 }\n /** The anchors coincide; any rotation about them (a ball and socket). */\n | { readonly _tag: 'Spherical' }\n /** The anchors coincide; rotation about `axis` only (a hinge), driven by `motor`. */\n | {\n readonly _tag: 'Revolute';\n readonly axis: Vec3;\n readonly limits: JointLimits | null;\n readonly motor: JointMotor | null;\n }\n /** Sliding along `axis` only, driven by `motor`. */\n | {\n readonly _tag: 'Prismatic';\n readonly axis: Vec3;\n readonly limits: JointLimits | null;\n readonly motor: JointMotor | null;\n }\n /** The anchors at most `length` apart. */\n | { readonly _tag: 'Rope'; readonly length: number }\n /** A force pulling the anchors towards `restLength` apart. */\n | {\n readonly _tag: 'Spring';\n readonly restLength: number;\n readonly stiffness: number;\n readonly damping: number;\n };\n\n/**\n * A joint between bodies `a` and `b`. Each anchor is in its body's own space: from the\n * node's origin, turned with it, unscaled.\n */\nexport type Joint = {\n readonly key: string;\n readonly a: BodyRef;\n readonly b: BodyRef;\n readonly anchorA: Vec3;\n readonly anchorB: Vec3;\n readonly kind: JointKind;\n /** Whether the two bodies still collide with each other (Rapier's default: they do). */\n readonly contacts: boolean;\n};\n\n/**\n * One copy of an instanced mesh. `key` is unique within its `instances` node and comes\n * back in hit events. `color` multiplies the material's colour, so use a white material\n * for exact per-instance colours. Rotation is fixed Euler angles: instances have no\n * behaviours or transitions of their own.\n */\nexport type Instance = {\n readonly key: string;\n readonly position: Vec3;\n readonly rotation: Vec3;\n readonly scale: Vec3;\n readonly color: Rgb;\n};\n\n/**\n * Many copies of one geometry and material in a single draw call (three.js's\n * `InstancedMesh`). The node itself is placed like a mesh; its instances are placed\n * inside it. Changing instances rewrites only the slots that changed.\n */\nexport type InstancesNode = {\n readonly _tag: 'Instances';\n readonly key: string;\n readonly position: Vec3;\n readonly rotation: Rotation;\n readonly scale: Vec3;\n readonly transition: Transition;\n /** A registered behaviour moving the node on top of its transform, or `null`. */\n readonly behaviour: Behave | null;\n readonly geometry: GeometryRef;\n readonly material: MaterialRef;\n readonly interactive: boolean;\n readonly castShadow: boolean;\n readonly receiveShadow: boolean;\n readonly instances: ReadonlyArray<Instance>;\n /**\n * A rigid body for every instance, all with these settings, or `null`: react-three-rapier's\n * `InstancedRigidBodies`. Each instance's collider is the geometry at its scale.\n */\n readonly body: Body | null;\n};\n\n/**\n * Shows a three.js object the application lent to the resource store under `id`: React\n * Three Fiber's `<primitive>`, by reference rather than by value, so descriptions stay\n * plain data. The node's transform applies to a wrapper, leaving the object's own as the\n * application set it. The object is never disposed. Until something is lent under `id`\n * the node is empty, so a description can name a model that is still loading.\n */\nexport type BorrowedNode = {\n readonly _tag: 'Borrowed';\n readonly key: string;\n readonly id: string;\n readonly position: Vec3;\n readonly rotation: Rotation;\n readonly scale: Vec3;\n readonly transition: Transition;\n /** A registered behaviour moving the node on top of its transform, or `null`. */\n readonly behaviour: Behave | null;\n /** Makes every mesh inside the object pickable; hits name the part by its `name`. */\n readonly interactive: boolean;\n /** An animation clip of the lent object to play, or `null` for none. */\n readonly animation: Animation | null;\n /** A rigid body whose colliders are the model's meshes, once it is lent; or `null`. */\n readonly body: Body | null;\n};\n\n/** Where a label's origin is along its width: an edge, the middle, or a fraction of it. */\nexport type LabelAnchorX = 'left' | 'center' | 'right' | number;\n\n/** Where a label's origin is along its height: an edge, a baseline, the middle, or a fraction. */\nexport type LabelAnchorY =\n | 'top'\n | 'top-baseline'\n | 'middle'\n | 'bottom-baseline'\n | 'bottom'\n | number;\n\n/** How a label's lines line up within its block. */\nexport type LabelAlign = 'left' | 'right' | 'center' | 'justify';\n\n/**\n * Crisp text at any size, drawn from glyph distance fields: Drei's `Text` (troika's\n * `Text`, `bf6f4ad` `src/core/Text.tsx`). `font` is the URL of a TTF, OTF or WOFF file,\n * or `null` for troika's default. A label is drawn by the scene graph's label engine (in\n * Foldkit, the environment's); without one it is empty. Fonts load and glyphs build in the\n * background, and the scene redraws when they are ready.\n */\nexport type LabelNode = {\n readonly _tag: 'Label';\n readonly key: string;\n readonly position: Vec3;\n readonly rotation: Rotation;\n readonly scale: Vec3;\n readonly transition: Transition;\n readonly behaviour: Behave | null;\n /** Makes the label pickable, over its glyphs' bounds. */\n readonly interactive: boolean;\n readonly text: string;\n readonly font: string | null;\n /** The em height, in scene units. */\n readonly fontSize: number;\n readonly color: Rgb;\n readonly fillOpacity: number;\n readonly anchorX: LabelAnchorX;\n readonly anchorY: LabelAnchorY;\n /** Wraps lines longer than this, in scene units; `null` never wraps. */\n readonly maxWidth: number | null;\n /** Line spacing as a multiple of `fontSize`; `null` for the font's own (\"normal\"). */\n readonly lineHeight: number | null;\n /** Extra space between letters, in ems. */\n readonly letterSpacing: number;\n readonly textAlign: LabelAlign;\n /** An outline around the glyphs, in scene units (0 for none), and its look. */\n readonly outlineWidth: number;\n readonly outlineColor: Rgb;\n readonly outlineOpacity: number;\n readonly outlineBlur: number;\n /**\n * Colours for runs of characters, overriding `color` from each `start` (a character\n * index) to the next: troika's `colorRanges`, as a list.\n */\n readonly colorRanges: ReadonlyArray<LabelColorRange>;\n /**\n * Curves the text round a vertical cylinder this far away, in scene units: positive in\n * front (concave), negative behind (convex), 0 flat. troika's `curveRadius`.\n */\n readonly curveRadius: number;\n /**\n * A material for the glyphs to be drawn with (lit by the scene, say), as troika takes a\n * base material and derives its text material from it; `color` still colours them.\n * `null` for troika's own unlit one.\n */\n readonly material: MaterialRef | null;\n};\n\n/** A run of a label's characters in another colour, from character index `start`. */\nexport type LabelColorRange = { readonly start: number; readonly color: Rgb };\n\n/**\n * Plays the clip named `clip` from the borrowed object's `animations`. Playback is a\n * function of scene time, like `spin`: it pauses with the scene and rewinds with it.\n * `speed` scales time (negative plays backwards); `loop: false` holds the last frame.\n * Changing the animation restarts it from the current scene time; removing it returns\n * the object to its rest pose.\n */\nexport type Animation = {\n readonly clip: string;\n readonly speed: number;\n readonly loop: boolean;\n};\n\n/** Uniform ambient light. */\nexport type AmbientLightNode = {\n readonly _tag: 'AmbientLight';\n readonly key: string;\n readonly color: Rgb;\n readonly intensity: number;\n};\n\n/** Directional light shining from `position` towards the origin. */\nexport type DirectionalLightNode = {\n readonly _tag: 'DirectionalLight';\n readonly key: string;\n readonly color: Rgb;\n readonly intensity: number;\n readonly position: Vec3;\n /** Renders a shadow map from this light, when the scene enables shadows. */\n readonly castShadow: boolean;\n /** Shadow map width and height in texels: a power of two. */\n readonly shadowMapSize: number;\n /** Depth offset that removes shadow acne; usually a small negative number. */\n readonly shadowBias: number;\n /** Half the width and height, in world units, of the area the shadow covers. */\n readonly shadowArea: number;\n};\n\n/**\n * A light shining in every direction from `position`. `distance` 0 means no cut-off;\n * `decay` 2 is physically correct.\n */\nexport type PointLightNode = {\n readonly _tag: 'PointLight';\n readonly key: string;\n readonly color: Rgb;\n readonly intensity: number;\n readonly position: Vec3;\n readonly distance: number;\n readonly decay: number /** Renders a shadow map from this light, when the scene enables shadows. */;\n readonly castShadow: boolean;\n /** Shadow map width and height in texels: a power of two. */\n readonly shadowMapSize: number;\n /** Depth offset that removes shadow acne; usually a small negative number. */\n readonly shadowBias: number;\n};\n\n/**\n * A cone of light from `position` towards `target`, both in world space. `angle` is the\n * cone's half-angle in radians; `penumbra` (0 to 1) softens its edge.\n */\nexport type SpotLightNode = {\n readonly _tag: 'SpotLight';\n readonly key: string;\n readonly color: Rgb;\n readonly intensity: number;\n readonly position: Vec3;\n readonly target: Vec3;\n readonly distance: number;\n readonly angle: number;\n readonly penumbra: number;\n readonly decay: number /** Renders a shadow map from this light, when the scene enables shadows. */;\n readonly castShadow: boolean;\n /** Shadow map width and height in texels: a power of two. */\n readonly shadowMapSize: number;\n /** Depth offset that removes shadow acne; usually a small negative number. */\n readonly shadowBias: number;\n};\n\n/** Sky-to-ground gradient light: `color` from above `position`, `groundColor` from below. */\nexport type HemisphereLightNode = {\n readonly _tag: 'HemisphereLight';\n readonly key: string;\n readonly color: Rgb;\n readonly groundColor: Rgb;\n readonly intensity: number;\n readonly position: Vec3;\n};\n\n/**\n * A square grid of lines on the XZ plane, three.js's `GridHelper`: `size` across, cut\n * into `divisions` cells, with the two middle lines in `centerColor`. (Drei's `Grid` is a\n * fading shader grid; this is the plain helper.)\n */\nexport type GridNode = {\n readonly _tag: 'Grid';\n readonly key: string;\n readonly position: Vec3;\n readonly size: number;\n readonly divisions: number;\n readonly color: Rgb;\n readonly centerColor: Rgb;\n};\n\n/**\n * Drei's `Grid`: a plane whose shader draws cell lines and section lines on the XZ plane,\n * fading with distance from the camera's foot on it. `size` is the plane's\n * `[width, height]`; `infinite` stretches it as far as the fade reaches, and\n * `followCamera` slides it under the camera. `fadeFrom` 1 fades from the camera, 0 from\n * the grid's origin. Its rotation is fixed Euler angles.\n */\nexport type ShaderGridNode = {\n readonly _tag: 'ShaderGrid';\n readonly key: string;\n readonly position: Vec3;\n readonly rotation: Vec3;\n readonly size: readonly [width: number, height: number];\n readonly cellSize: number;\n readonly cellThickness: number;\n readonly cellColor: Rgb;\n readonly sectionSize: number;\n readonly sectionThickness: number;\n readonly sectionColor: Rgb;\n readonly infinite: boolean;\n readonly followCamera: boolean;\n readonly fadeDistance: number;\n readonly fadeStrength: number;\n readonly fadeFrom: number;\n readonly side: MaterialSide;\n};\n\n/** Any node in a scene. Keys are unique across the whole scene. */\nexport type SceneNode =\n | GridNode\n | ShaderGridNode\n | GroupNode\n | MeshNode\n | InstancesNode\n | BorrowedNode\n | LabelNode\n | AmbientLightNode\n | DirectionalLightNode\n | PointLightNode\n | SpotLightNode\n | HemisphereLightNode;\n\n/** The node kinds the kernel knows how to host. */\nexport type NodeKind = SceneNode['_tag'];\n\n/** A perspective camera: `fov` is the vertical field of view in degrees. */\nexport type PerspectiveCamera = {\n readonly _tag: 'Perspective';\n readonly fov: number;\n readonly near: number;\n readonly far: number;\n readonly position: Vec3;\n readonly lookAt: Vec3 /**\n * How the rendered camera follows a new position, `lookAt` or zoom: 0 (the default)\n * jumps; above 0 eases there round the target, closing that fraction of the remaining\n * way every sixtieth of a second, as three.js's `OrbitControls.dampingFactor` (Drei's\n * default is 0.05). Field of view, near and far always apply at once.\n */;\n readonly damping: number;\n /**\n * Turns the rendered camera round its target, as three.js's `OrbitControls.autoRotate`\n * at `autoRotateSpeed`: 0 (the default) is still; 2 orbits once every 30 seconds of\n * scene time, positive clockwise seen from above. It holds still while a gesture is\n * pressed; before a gesture an `AutoRotated` event says where it got to, for the Model\n * (`autoRotated(camera, detail)`). A new position or `lookAt` turns on from there.\n */\n readonly autoRotate: number;\n};\n\n/**\n * An orthographic camera. As in React Three Fiber, the frustum follows the viewport in\n * CSS pixels and `zoom` is CSS pixels per world unit, so objects keep their on-screen\n * size when the viewport resizes.\n */\nexport type OrthographicCamera = {\n readonly _tag: 'Orthographic';\n readonly zoom: number;\n readonly near: number;\n readonly far: number;\n readonly position: Vec3;\n readonly lookAt: Vec3 /** As on `PerspectiveCamera`. */;\n readonly damping: number;\n /** As on `PerspectiveCamera`. */\n readonly autoRotate: number;\n};\n\n/** The single active camera. */\nexport type Camera = PerspectiveCamera | OrthographicCamera;\n\n/**\n * Shadow map filtering, as React Three Fiber names it: `basic` (hard), `percentage` (PCF),\n * `soft` (PCF soft) or `variance` (VSM). `off` disables shadows.\n */\nexport type ShadowMode = 'off' | 'basic' | 'percentage' | 'soft' | 'variance';\n\n/** How the renderer maps scene light to screen colour. */\nexport type ToneMapping = 'none' | 'linear' | 'reinhard' | 'cineon' | 'aces' | 'agx' | 'neutral';\n\n/**\n * When frames render, as React Three Fiber's `frameloop`: `always` every display frame,\n * `demand` only when something changed or is animating, `never` only on `advance`.\n */\nexport type FrameMode = 'always' | 'demand' | 'never';\n\n/**\n * A post-processing effect, applied in order after the scene renders (three.js's\n * `EffectComposer` passes).\n *\n * - `Bloom`: bright areas glow (`UnrealBloomPass`): `strength`, `radius`, and the\n * luminance `threshold` above which pixels bloom.\n * - `Vignette`: darkens the edges (`VignetteShader`): `offset` and `darkness`.\n * - `Film`: animated grain (`FilmPass`): `intensity`, optionally `grayscale`.\n */\nexport type PostEffect =\n | {\n readonly _tag: 'Bloom';\n readonly strength: number;\n readonly radius: number;\n readonly threshold: number;\n }\n | { readonly _tag: 'Vignette'; readonly offset: number; readonly darkness: number }\n | { readonly _tag: 'Film'; readonly intensity: number; readonly grayscale: boolean };\n\n/** Scene-wide rendering settings, changeable at any time. */\nexport type RenderSettings = {\n /** Post-processing, in order. Empty renders straight to the screen. */\n readonly effects: ReadonlyArray<PostEffect>;\n readonly frames: FrameMode;\n /**\n * Scales the drawing buffer's pixel ratio, from just above 0 to 1. Lower it when\n * frames are slow (see `PerformanceChanged`), as Drei's `AdaptiveDpr` does.\n */\n readonly resolution: number;\n readonly shadows: ShadowMode;\n readonly toneMapping: ToneMapping;\n /** Exposure for tone mapping. Ignored when `toneMapping` is `none`. */\n readonly exposure: number;\n /** The output colour space: `srgb` for displays, `linear` to skip the conversion. */\n readonly colorSpace: 'srgb' | 'linear';\n};\n\n/** Part of the canvas, as fractions (0 to 1) of its width and height from the top left. */\nexport type ViewRect = {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n};\n\n/**\n * Another camera drawing the scene into part of the canvas: Drei's `View` and R3F's\n * split-screen portals, as data. Views draw in order, later ones on top.\n */\nexport type View = { readonly key: string; readonly camera: Camera; readonly rect: ViewRect };\n\n/**\n * A small scene rendered into a texture that materials use as `map: id`: Drei's\n * `RenderTexture`, as data. Its nodes have their own key namespace and may use the\n * scene's shared resources. It redraws only when it changes or animates.\n */\nexport type RenderTexture = {\n readonly id: string;\n /** Texture size in pixels. */\n readonly width: number;\n readonly height: number;\n readonly camera: Camera;\n /** A clear colour, or `null` for transparent. */\n readonly background: Rgb | null;\n readonly children: ReadonlyArray<SceneNode>;\n};\n\n/** A complete scene: camera, render settings, shared resources and root nodes. */\n/**\n * Who owns the pointer's gestures on the canvas.\n *\n * - `'page'` (the default): the wheel scrolls the page, touch pans it, the right button\n * opens the browser's menu, and the scene reports only events on interactive meshes.\n * - `'scene'`: the scene claims them, as three.js's `OrbitControls` does when connected,\n * and reports every drag, wheel and pinch on the canvas as a `Gesture`, for controls\n * such as `orbit` to turn into a new camera.\n */\nexport type Gestures = 'page' | 'scene';\n\n/**\n * A point the application shows HTML at, as Drei's `Html` (`src/web/Html.tsx` at\n * `bf6f4ad`, without `transform`). The scene works out where the point is on the canvas\n * each frame it draws; the host moves the application's HTML there.\n */\nexport type Overlay = {\n readonly key: string;\n /** The node the position is relative to, moving with it; `null` for world space. */\n readonly node: string | null;\n readonly position: Vec3;\n /** Centre the HTML on the point (Drei's `center`); otherwise its top left is there. */\n readonly center: boolean;\n /**\n * Scale the HTML with distance, as Drei's `distanceFactor`: at a distance where the\n * view is `distanceFactor` units tall it shows at its own size. `null` keeps its size.\n */\n readonly distanceFactor: number | null;\n /** Hide the HTML while a mesh is in front of the point (Drei's `occlude`). */\n readonly occlude: boolean;\n /** z-index for points at the camera's near and far planes (Drei's `zIndexRange`). */\n readonly zIndexRange: readonly [near: number, far: number];\n /** With views: the view it is shown in. `null`: the camera, or the first view. */\n readonly view: string | null;\n};\n\n/**\n * Image-based lighting and background, as Drei's `Environment` (`src/core/Environment.tsx`\n * at `bf6f4ad`, `setEnvProps`). `map` names an equirectangular texture lent to the store;\n * `null` uses three.js's `RoomEnvironment`, a neutral studio built in code (no files).\n */\nexport type Environment = {\n readonly map: string | null;\n /** Drei's `background`: `false` lights only, `true` also shows it, `'only'` only shows it. */\n readonly background: boolean | 'only';\n readonly backgroundBlurriness: number;\n readonly backgroundIntensity: number;\n readonly environmentIntensity: number;\n};\n\n/**\n * A physically based daylight sky, three.js's `Sky` (Preetham), as Drei's `Sky`\n * (`src/core/Sky.tsx` at `bf6f4ad`). Drawn at the camera's far plane, never picked.\n */\nexport type Sky = {\n readonly sunPosition: Vec3;\n readonly turbidity: number;\n readonly rayleigh: number;\n readonly mieCoefficient: number;\n readonly mieDirectionalG: number;\n /** three.js 0.186's cloud cover, 0 to 1. Clouds hold still: scene time does not move them. */\n readonly clouds: number;\n /** The size of the sky box (Drei's `distance`). */\n readonly distance: number;\n};\n\n/**\n * Soft shadows on the ground under everything, as Drei's `ContactShadows`\n * (`src/core/ContactShadows.tsx` at `bf6f4ad`, after three.js's `webgl_shadow_contact`\n * example): the scene's depth seen from below, blurred, on a plane. Redrawn with every\n * frame the scene draws; needs no lights or shadow maps.\n */\nexport type ContactShadows = {\n /** The middle of the shadow plane; it lies flat, facing up. */\n readonly position: Vec3;\n /** Width and depth of the plane, in world units (Drei's `width × scale`, `height × scale`). */\n readonly size: readonly [width: number, depth: number];\n /**\n * Where the shadow camera starts seeing, above the plane (Drei's `near`). Negative takes\n * in faces just below it, such as the flat bottoms of objects resting on the plane.\n */\n readonly near: number;\n /** How far above the plane objects still cast a shadow (Drei's `far`). */\n readonly far: number;\n readonly blur: number;\n /** A second, finer blur pass (Drei's `smooth`). */\n readonly smooth: boolean;\n readonly opacity: number;\n readonly color: Rgb;\n /** Texels across the shadow texture. */\n readonly resolution: number;\n};\n\n/**\n * Immersive presentation (WebXR), as `@react-three/xr`'s store and `XROrigin`\n * (pmndrs/xr at `0e1acd8`). Data only: an application enters a session from a user\n * gesture through its host (the Foldkit environment's `xr.enter`), and the scene that\n * describes `xr` is the one presented.\n */\nexport type Xr = {\n /** Where the player stands: the reference space's origin in the scene, on the floor. */\n readonly origin: Vec3;\n /** Which way the player faces at the origin: radians about +y (0 looks down −z). */\n readonly heading: number;\n /** The reference space requested (pmndrs/xr's default is `local-floor`). */\n readonly referenceSpace: 'local-floor' | 'local' | 'bounded-floor';\n /** Framebuffer scale relative to the device's default (1); lower is faster. */\n readonly framebufferScale: number;\n /**\n * In AR, report where a select's ray meets a real surface (`XrSurface` events), from the\n * session's hit tests: tap to place, as pmndrs/xr's `useXRHitTest`.\n */\n readonly hitTest: boolean;\n /** Draw each input source's pointing ray and each tracked hand's joints. */\n readonly showInputs: boolean;\n /**\n * Places fixed in the real world, by id, where the description puts them (in the\n * scene's space): WebXR anchors, which the session keeps in place as it learns the room.\n * Groups follow them with `follow: anchorSpace(id)`.\n */\n readonly anchors: ReadonlyArray<XrAnchor>;\n /** Detect the room's planes (floors, walls, tables) and report them as `XrPlanes` events. */\n readonly planes: boolean;\n /**\n * Detect the room's meshes (furniture, walls, the room as a whole) and report them as\n * `XrMeshes` events; each one's geometry is lent for `xrMesh(id)`, followed with\n * `meshSpace(id)`.\n */\n readonly meshes: boolean;\n /** Keep the scene's HTML overlays shown during an AR session (WebXR's DOM overlay). */\n readonly domOverlay: boolean;\n /**\n * Glide the player with the thumbsticks while presenting, as pmndrs/xr's controller\n * locomotion does: the left stick moves where the head faces, the right turns. The\n * player's place is the session's while gliding; when the sticks come back to the\n * middle an `XrMoved` event says where it ended, for the Model's `origin` and\n * `heading`. `null` to leave the sticks to the application (`XrStick`, `locomote`).\n */\n readonly glide: XrGlide | null;\n};\n\n/** An anchor the description places: its id, and where in the scene (Euler rotation). */\nexport type XrAnchor = { readonly id: string; readonly position: Vec3; readonly rotation: Vec3 };\n\n/** How the sticks glide the player (pmndrs/xr's defaults: 2 m/s, a 45° snap turn). */\nexport type XrGlide = {\n /** Metres per second at full stick. */\n readonly speed: number;\n /** `smooth` turns while the stick is pushed; `snap` turns once per push. */\n readonly turn: 'smooth' | 'snap';\n /** Radians per second at full stick, for a smooth turn. */\n readonly turnSpeed: number;\n /** Degrees per push, for a snap turn. */\n readonly snapDegrees: number;\n};\n\nexport type SceneDescription = {\n readonly camera: Camera;\n /** Whether the scene claims the pointer's gestures from the page. */\n readonly gestures: Gestures;\n /**\n * Views to draw instead of `camera` filling the canvas. Empty (the default) draws one\n * full view with `camera`.\n */\n readonly views: ReadonlyArray<View>;\n /** Scenes rendered into textures for materials to use. */\n readonly renderTextures: ReadonlyArray<RenderTexture>;\n /** Points to show HTML at, placed every frame the scene draws. */\n readonly overlays: ReadonlyArray<Overlay>;\n /** Image-based lighting and background, or `null` for none. */\n readonly environment: Environment | null;\n /** A daylight sky behind everything, or `null` for none. */\n readonly sky: Sky | null;\n /** Soft shadows on the ground, or `null` for none. */\n readonly contactShadows: ContactShadows | null;\n /** A physics world for meshes with a `body`, or `null` for none. */\n readonly physics: Physics | null;\n /** How the scene is presented in an immersive session, or `null` if it never is. */\n readonly xr: Xr | null;\n /**\n * Nodes whose world bounding box the scene reports (`Measured` events) whenever it\n * changes: what Drei's `Bounds` measures, for `fitCamera`. Loaded models included.\n */\n readonly measure: ReadonlyArray<string>;\n readonly render: RenderSettings;\n readonly resources: ResourceDefinitions;\n readonly children: ReadonlyArray<SceneNode>;\n};\n",
|
|
6
|
+
"/**\n * Clip playback as a pure function of scene time.\n *\n * @module\n */\nimport type { Animation } from './description.ts';\n\n/** Just under the clip's end: three wraps a looping action at exactly its duration. */\nconst endEpsilon = 1e-6;\n\n/**\n * The clip time to show `elapsed` seconds after playback started: wrapped for looping\n * clips (backwards too, for negative speeds), held at the last frame otherwise.\n */\nexport const clipTime = (animation: Animation, duration: number, elapsed: number): number => {\n if (duration <= 0) return 0;\n const t = elapsed * animation.speed;\n if (animation.loop) return ((t % duration) + duration) % duration;\n return Math.min(Math.max(t, 0), duration - endEpsilon);\n};\n\n/** Whether playback still changes the pose: always for loops, until the end otherwise. */\nexport const clipRunning = (animation: Animation, duration: number, elapsed: number): boolean =>\n animation.loop || (animation.speed !== 0 && Math.abs(elapsed * animation.speed) < duration);\n",
|
|
7
|
+
"/**\n * Registered behaviours: application motion as pure functions of scene time.\n *\n * A behaviour writes a pose (a position offset, a rotation and a scale factor) into a\n * reused scratch value, so ticking allocates nothing. The scene graph composes that pose\n * on top of the node's own transform each frame: position added, rotation added, scale\n * multiplied. Because the pose depends only on time and parameters, behaviours pause,\n * rewind and replay with the scene, unlike `useFrame` callbacks that mutate state.\n *\n * @module\n */\nimport { Vector3 } from 'three';\n\n/** Where a behaviour writes its pose. Reset to no change before every call. */\nexport type BehaviourPose = {\n /** Added to the node's position, in its parent's space. */\n readonly offset: Vector3;\n /** Euler angles (radians) added to the node's rotation. */\n readonly rotation: Vector3;\n /** Multiplies the node's scale. */\n readonly scale: Vector3;\n};\n\n/** A behaviour: writes the pose for `seconds` of scene time and the node's parameters. */\nexport type Behaviour = (\n pose: BehaviourPose,\n seconds: number,\n params: Readonly<Record<string, number>>,\n) => void;\n\n/** A pose that changes nothing. */\nexport const createPose = (): BehaviourPose => ({\n offset: new Vector3(),\n rotation: new Vector3(),\n scale: new Vector3(1, 1, 1),\n});\n\nexport const resetPose = (pose: BehaviourPose): void => {\n pose.offset.set(0, 0, 0);\n pose.rotation.set(0, 0, 0);\n pose.scale.set(1, 1, 1);\n};\n\n/** Maps `value` from one range to another, as three's `MathUtils.mapLinear`. */\nconst mapLinear = (value: number, a1: number, a2: number, b1: number, b2: number): number =>\n b1 + ((value - a1) * (b2 - b1)) / (a2 - a1);\n\n/**\n * Drei's `Float` (`drei-main/src/core/Float.tsx` at `bf6f4ad`): a gentle bob and sway.\n * Parameters (Drei's defaults): `speed` 1, `rotationIntensity` 1, `floatIntensity` 1,\n * `low` -0.1 and `high` 0.1 (Drei's `floatingRange`), and `phase` 0 in place of Drei's\n * random start, so the motion is the same on every run.\n */\nexport const float: Behaviour = (pose, seconds, params) => {\n const speed = params['speed'] ?? 1;\n const turn = params['rotationIntensity'] ?? 1;\n const lift = params['floatIntensity'] ?? 1;\n const angle = (((params['phase'] ?? 0) + seconds) / 4) * speed;\n pose.rotation.set(\n (Math.cos(angle) / 8) * turn,\n (Math.sin(angle) / 8) * turn,\n (Math.sin(angle) / 20) * turn,\n );\n const y = mapLinear(\n Math.sin(angle) / 10,\n -0.1,\n 0.1,\n params['low'] ?? -0.1,\n params['high'] ?? 0.1,\n );\n pose.offset.set(0, y * lift, 0);\n};\n\n/** Behaviours every scene knows without registering them. */\nexport const builtinBehaviours: Readonly<Record<string, Behaviour>> = { float };\n",
|
|
8
|
+
"/**\n * Behaviours own animated properties (PLAN D4). Their output is a pure function of\n * elapsed scene time, so a frame's result doesn't depend on how many frames ran before\n * it: deterministic and frame-rate independent.\n *\n * @module\n */\nimport type { Euler } from 'three';\n\nimport type { Rotation } from './description.ts';\n\n/** The spin angle in radians after `elapsedSeconds`. */\nexport const spinAngle = (\n spin: Extract<Rotation, { readonly _tag: 'Spin' }>,\n elapsedSeconds: number,\n): number => spin.phase + spin.radiansPerSecond * elapsedSeconds;\n\n/** Writes a rotation into a three.js Euler without allocating. */\nexport const writeRotation = (target: Euler, rotation: Rotation, elapsedSeconds: number): void => {\n if (rotation._tag === 'Fixed') {\n target.set(rotation.euler[0], rotation.euler[1], rotation.euler[2]);\n return;\n }\n const angle = spinAngle(rotation, elapsedSeconds);\n switch (rotation.axis) {\n case 'x':\n target.set(angle, 0, 0);\n return;\n case 'y':\n target.set(0, angle, 0);\n return;\n case 'z':\n target.set(0, 0, angle);\n return;\n }\n};\n",
|
|
9
|
+
"/**\n * Building and updating three.js materials from descriptions.\n *\n * Kinds and defaults follow three.js's mesh materials (`three/src/materials`). A change\n * within one kind is applied in place; when it touches something compiled into the shader\n * (transparency, side, flat shading) the material is flagged for recompilation, as three\n * requires. A change of kind needs a new material, which the resource store handles.\n *\n * @module\n */\nimport {\n BackSide,\n DoubleSide,\n FrontSide,\n MeshBasicMaterial,\n MeshLambertMaterial,\n MeshNormalMaterial,\n MeshPhongMaterial,\n MeshPhysicalMaterial,\n MeshStandardMaterial,\n ShadowMaterial as ThreeShadowMaterial,\n type Side,\n type Texture,\n} from 'three';\n\nimport type {\n BasicMaterial,\n LambertMaterial,\n MaterialSide,\n NormalMaterial,\n PhongMaterial,\n PhysicalMaterial,\n ShadowMaterial,\n StandardMaterial,\n SurfaceMaterial,\n} from './description.ts';\n\n/** Looks up a texture lent to the store. */\nexport type Textures = (id: string) => Texture | undefined;\n\nconst noTextures: Textures = () => undefined;\n\n/** Sets the colour map. Returns whether the shader must recompile (a map came or went). */\nconst applyMap = (\n material: Exclude<HostMaterial, MeshNormalMaterial | ThreeShadowMaterial>,\n id: string | null,\n textures: Textures,\n): boolean => {\n const map = id === null ? null : (textures(id) ?? null);\n const recompile = (material.map === null) !== (map === null);\n material.map = map;\n return recompile;\n};\n\n/** The three.js material kinds the kernel hosts. */\nexport type HostMaterial =\n | MeshBasicMaterial\n | MeshLambertMaterial\n | MeshPhongMaterial\n | MeshStandardMaterial\n | MeshPhysicalMaterial\n | MeshNormalMaterial\n | ThreeShadowMaterial;\n\nconst sides = { front: FrontSide, back: BackSide, double: DoubleSide } satisfies Record<\n MaterialSide,\n Side\n>;\n\ntype SurfaceFields = {\n readonly opacity: number;\n readonly transparent: boolean;\n readonly side: MaterialSide;\n readonly wireframe: boolean;\n};\n\ntype Shaded = SurfaceFields & { readonly flatShading: boolean };\n\n/** Applies the fields every kind shares. Returns whether the shader must recompile. */\nconst applySurface = (\n material: Exclude<HostMaterial, ThreeShadowMaterial>,\n description: SurfaceFields,\n): boolean => {\n const side = sides[description.side];\n const recompile = material.transparent !== description.transparent || material.side !== side;\n material.opacity = description.opacity;\n material.transparent = description.transparent;\n material.side = side;\n material.wireframe = description.wireframe;\n return recompile;\n};\n\nconst applyShaded = (\n material: Exclude<HostMaterial, MeshBasicMaterial | ThreeShadowMaterial>,\n description: Shaded,\n mapChanged = false,\n): void => {\n const flatChanged = material.flatShading !== description.flatShading;\n material.flatShading = description.flatShading;\n if (applySurface(material, description) || flatChanged || mapChanged) {\n material.needsUpdate = true;\n }\n};\n\nconst applyBasic = (\n material: MeshBasicMaterial,\n description: BasicMaterial,\n textures: Textures,\n): void => {\n material.color.setHex(description.color);\n const mapChanged = applyMap(material, description.map, textures);\n if (applySurface(material, description) || mapChanged) material.needsUpdate = true;\n};\n\nconst applyLambert = (\n material: MeshLambertMaterial,\n description: LambertMaterial,\n textures: Textures,\n): void => {\n material.color.setHex(description.color);\n material.emissive.setHex(description.emissive);\n applyShaded(material, description, applyMap(material, description.map, textures));\n};\n\nconst applyPhong = (\n material: MeshPhongMaterial,\n description: PhongMaterial,\n textures: Textures,\n): void => {\n material.color.setHex(description.color);\n material.emissive.setHex(description.emissive);\n material.specular.setHex(description.specular);\n material.shininess = description.shininess;\n applyShaded(material, description, applyMap(material, description.map, textures));\n};\n\nconst applyStandard = (\n material: MeshStandardMaterial,\n description: StandardMaterial | PhysicalMaterial,\n textures: Textures,\n): void => {\n material.color.setHex(description.color);\n material.roughness = description.roughness;\n material.metalness = description.metalness;\n material.emissive.setHex(description.emissive);\n material.emissiveIntensity = description.emissiveIntensity;\n applyShaded(material, description, applyMap(material, description.map, textures));\n};\n\nconst applyPhysical = (\n material: MeshPhysicalMaterial,\n description: PhysicalMaterial,\n textures: Textures,\n): void => {\n applyStandard(material, description, textures);\n // three's clearcoat and transmission setters recompile when crossing zero.\n material.clearcoat = description.clearcoat;\n material.clearcoatRoughness = description.clearcoatRoughness;\n material.transmission = description.transmission;\n material.ior = description.ior;\n};\n\nconst applyNormal = (material: MeshNormalMaterial, description: NormalMaterial): void => {\n applyShaded(material, description);\n};\n\nconst applyShadow = (material: ThreeShadowMaterial, description: ShadowMaterial): void => {\n material.color.setHex(description.color);\n material.opacity = description.opacity;\n};\n\n/** Builds a new material for a description. */\nexport const buildMaterial = (\n description: SurfaceMaterial,\n textures: Textures = noTextures,\n): HostMaterial => {\n switch (description._tag) {\n case 'Shadow': {\n const material = new ThreeShadowMaterial();\n applyShadow(material, description);\n return material;\n }\n case 'Basic': {\n const material = new MeshBasicMaterial();\n applyBasic(material, description, textures);\n return material;\n }\n case 'Lambert': {\n const material = new MeshLambertMaterial();\n applyLambert(material, description, textures);\n return material;\n }\n case 'Phong': {\n const material = new MeshPhongMaterial();\n applyPhong(material, description, textures);\n return material;\n }\n case 'Standard': {\n const material = new MeshStandardMaterial();\n applyStandard(material, description, textures);\n return material;\n }\n case 'Physical': {\n const material = new MeshPhysicalMaterial();\n applyPhysical(material, description, textures);\n return material;\n }\n case 'Normal': {\n const material = new MeshNormalMaterial();\n applyNormal(material, description);\n return material;\n }\n }\n};\n\n/**\n * Applies a description to an existing material in place. Returns `false`, changing\n * nothing, when the material is a different kind: the caller must build a new one.\n */\nexport const updateMaterial = (\n material: HostMaterial,\n description: SurfaceMaterial,\n textures: Textures = noTextures,\n): boolean => {\n // MeshPhysicalMaterial extends MeshStandardMaterial, so test the exact kind by type.\n switch (description._tag) {\n case 'Shadow':\n if (!(material instanceof ThreeShadowMaterial)) return false;\n applyShadow(material, description);\n return true;\n case 'Basic':\n if (!(material instanceof MeshBasicMaterial)) return false;\n applyBasic(material, description, textures);\n return true;\n case 'Lambert':\n if (!(material instanceof MeshLambertMaterial)) return false;\n applyLambert(material, description, textures);\n return true;\n case 'Phong':\n if (!(material instanceof MeshPhongMaterial)) return false;\n applyPhong(material, description, textures);\n return true;\n case 'Standard':\n if (material.type !== 'MeshStandardMaterial' || !(material instanceof MeshStandardMaterial)) {\n return false;\n }\n applyStandard(material, description, textures);\n return true;\n case 'Physical':\n if (!(material instanceof MeshPhysicalMaterial)) return false;\n applyPhysical(material, description, textures);\n return true;\n case 'Normal':\n if (!(material instanceof MeshNormalMaterial)) return false;\n applyNormal(material, description);\n return true;\n }\n};\n",
|
|
10
|
+
"/**\n * Writing instance descriptions into three.js's `InstancedMesh` buffers.\n *\n * Slots are positional: instance `i` of the description lives in slot `i`. An update\n * writes only the slots whose instance changed, so moving one of 10,000 instances writes\n * one matrix. Capacity grows by doubling, so adding instances rarely reallocates.\n *\n * @module\n */\nimport {\n type BufferGeometry,\n Color,\n DynamicDrawUsage,\n Euler,\n InstancedMesh,\n Matrix4,\n Quaternion,\n Vector3,\n} from 'three';\n\nimport type { Instance } from './description.ts';\nimport { instanceEquals } from './equality.ts';\nimport type { HostMaterial } from './materials.ts';\n\n/** The three.js object an `instances` node is hosted as. */\nexport type HostInstances = InstancedMesh<BufferGeometry, HostMaterial>;\n\nconst minimumCapacity = 16;\n\n/** Slots to allocate for `count` instances: the next power of two, at least 16. */\nexport const capacityFor = (count: number): number =>\n Math.max(minimumCapacity, 2 ** Math.ceil(Math.log2(Math.max(1, count))));\n\n// Scratch values, so writing instances allocates nothing.\nconst matrix = new Matrix4();\nconst position = new Vector3();\nconst euler = new Euler();\nconst quaternion = new Quaternion();\nconst scale = new Vector3();\nconst color = new Color();\n\nconst writeSlot = (mesh: HostInstances, slot: number, instance: Instance): void => {\n position.set(instance.position[0], instance.position[1], instance.position[2]);\n euler.set(instance.rotation[0], instance.rotation[1], instance.rotation[2]);\n quaternion.setFromEuler(euler);\n scale.set(instance.scale[0], instance.scale[1], instance.scale[2]);\n mesh.setMatrixAt(slot, matrix.compose(position, quaternion, scale));\n mesh.setColorAt(slot, color.setHex(instance.color));\n};\n\n/** Creates an instanced mesh with room for at least `count` instances. */\nexport const createInstances = (\n geometry: BufferGeometry,\n material: HostMaterial,\n count: number,\n): HostInstances => {\n const mesh: HostInstances = new InstancedMesh(geometry, material, capacityFor(count));\n mesh.instanceMatrix.setUsage(DynamicDrawUsage);\n // Allocate per-instance colours up front so the shader never changes as colours come and go.\n mesh.setColorAt(0, color.setHex(0xffffff));\n mesh.instanceColor?.setUsage(DynamicDrawUsage);\n mesh.count = 0;\n return mesh;\n};\n\n/** Whether `count` instances fit without reallocating. */\nexport const fits = (mesh: HostInstances, count: number): boolean =>\n count <= mesh.instanceMatrix.count;\n\n/**\n * Writes `next` into `mesh`, skipping slots whose instance is unchanged from `previous`\n * (pass an empty list to write every slot). `next` must fit. Returns the slots written.\n */\nexport const writeInstances = (\n mesh: HostInstances,\n previous: ReadonlyArray<Instance>,\n next: ReadonlyArray<Instance>,\n): number => {\n let written = 0;\n for (let slot = 0; slot < next.length; slot++) {\n const instance = next[slot];\n if (instance === undefined) continue;\n const before = previous[slot];\n if (before !== undefined && instanceEquals(before, instance)) continue;\n writeSlot(mesh, slot, instance);\n written++;\n }\n if (written > 0 || mesh.count !== next.length) {\n mesh.count = next.length;\n mesh.instanceMatrix.needsUpdate = true;\n if (mesh.instanceColor !== null) mesh.instanceColor.needsUpdate = true;\n // Picking and frustum culling recompute these lazily from the new instances.\n mesh.boundingSphere = null;\n mesh.boundingBox = null;\n }\n return written;\n};\n",
|
|
11
|
+
"/**\n * Structural equality for description values. Reference equality is checked first, so\n * unchanged subtrees reused between renders cost almost nothing.\n *\n * @module\n */\nimport type {\n Animation,\n Behave,\n Body,\n BodyRef,\n GeometryRef,\n Instance,\n Joint,\n JointKind,\n JointLimits,\n JointMotor,\n InteractionGroups,\n XrAnchor,\n XrSpace,\n ColliderDescription,\n ColliderShapeDescription,\n LabelColorRange,\n LabelNode,\n ShaderGridNode,\n MaterialRef,\n Overlay,\n Physics,\n Camera,\n ContactShadows,\n Environment,\n PostEffect,\n RenderSettings,\n ResourceDefinitions,\n Rotation,\n ShapeGeometry,\n Sky,\n Xr,\n TextBevel,\n Transition,\n Vec3,\n View,\n} from './description.ts';\n\n/** Component-wise equality using `Object.is`, so `NaN` equals `NaN` and `0` differs from `-0`. */\nexport const vec3Equals = (a: Vec3, b: Vec3): boolean =>\n a === b || (Object.is(a[0], b[0]) && Object.is(a[1], b[1]) && Object.is(a[2], b[2]));\n\n/** Rotation equality, including behaviour parameters. */\nexport const rotationEquals = (a: Rotation, b: Rotation): boolean => {\n if (a === b) return true;\n if (a._tag === 'Fixed' && b._tag === 'Fixed') return vec3Equals(a.euler, b.euler);\n if (a._tag === 'Spin' && b._tag === 'Spin') {\n return (\n a.axis === b.axis &&\n Object.is(a.radiansPerSecond, b.radiansPerSecond) &&\n Object.is(a.phase, b.phase)\n );\n }\n return false;\n};\n\n/** Shape equality: same kind and same parameters. */\nexport const shapeEquals = (a: ShapeGeometry, b: ShapeGeometry): boolean => {\n if (a === b) return true;\n switch (a._tag) {\n case 'Box':\n return (\n b._tag === 'Box' &&\n Object.is(a.width, b.width) &&\n Object.is(a.height, b.height) &&\n Object.is(a.depth, b.depth)\n );\n case 'Sphere':\n return (\n b._tag === 'Sphere' &&\n Object.is(a.radius, b.radius) &&\n a.widthSegments === b.widthSegments &&\n a.heightSegments === b.heightSegments\n );\n case 'Plane':\n return b._tag === 'Plane' && Object.is(a.width, b.width) && Object.is(a.height, b.height);\n case 'Cylinder':\n return (\n b._tag === 'Cylinder' &&\n Object.is(a.radiusTop, b.radiusTop) &&\n Object.is(a.radiusBottom, b.radiusBottom) &&\n Object.is(a.height, b.height) &&\n a.radialSegments === b.radialSegments\n );\n case 'Torus':\n return (\n b._tag === 'Torus' &&\n Object.is(a.radius, b.radius) &&\n Object.is(a.tube, b.tube) &&\n a.radialSegments === b.radialSegments &&\n a.tubularSegments === b.tubularSegments\n );\n case 'Cone':\n return (\n b._tag === 'Cone' &&\n Object.is(a.radius, b.radius) &&\n Object.is(a.height, b.height) &&\n a.radialSegments === b.radialSegments\n );\n case 'Capsule':\n return (\n b._tag === 'Capsule' &&\n Object.is(a.radius, b.radius) &&\n Object.is(a.height, b.height) &&\n a.capSegments === b.capSegments &&\n a.radialSegments === b.radialSegments\n );\n case 'Ring':\n return (\n b._tag === 'Ring' &&\n Object.is(a.innerRadius, b.innerRadius) &&\n Object.is(a.outerRadius, b.outerRadius) &&\n a.thetaSegments === b.thetaSegments\n );\n case 'Circle':\n return b._tag === 'Circle' && Object.is(a.radius, b.radius) && a.segments === b.segments;\n case 'Text':\n return (\n b._tag === 'Text' &&\n a.text === b.text &&\n a.font === b.font &&\n Object.is(a.size, b.size) &&\n Object.is(a.depth, b.depth) &&\n a.curveSegments === b.curveSegments &&\n a.center === b.center &&\n Object.is(a.letterSpacing, b.letterSpacing) &&\n Object.is(a.lineHeight, b.lineHeight) &&\n a.align === b.align &&\n bevelEquals(a.bevel, b.bevel)\n );\n }\n};\n\nconst bevelEquals = (a: TextBevel | null, b: TextBevel | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n Object.is(a.thickness, b.thickness) &&\n Object.is(a.size, b.size) &&\n Object.is(a.offset, b.offset) &&\n a.segments === b.segments);\n\n/** Geometry reference equality: same ownership mode and same shape or id. */\nexport const geometryRefEquals = (a: GeometryRef, b: GeometryRef): boolean => {\n if (a === b) return true;\n if (a._tag === 'SharedGeometry' || b._tag === 'SharedGeometry') {\n return a._tag === 'SharedGeometry' && b._tag === 'SharedGeometry' && a.id === b.id;\n }\n if (a._tag === 'LentGeometry' || b._tag === 'LentGeometry') {\n return a._tag === 'LentGeometry' && b._tag === 'LentGeometry' && a.id === b.id;\n }\n return shapeEquals(a, b);\n};\n\n/** Instance equality: same key, placement and colour. */\nexport const instanceEquals = (a: Instance, b: Instance): boolean =>\n a === b ||\n (a.key === b.key &&\n Object.is(a.color, b.color) &&\n vec3Equals(a.position, b.position) &&\n vec3Equals(a.rotation, b.rotation) &&\n vec3Equals(a.scale, b.scale));\n\n/** Instance list equality, slot by slot. */\nexport const instancesEqual = (a: ReadonlyArray<Instance>, b: ReadonlyArray<Instance>): boolean => {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const x = a[i];\n const y = b[i];\n if (x === undefined || y === undefined || !instanceEquals(x, y)) return false;\n }\n return true;\n};\n\n/** Behaviour equality: both none, or the same name and parameters. */\nexport const behaviourEquals = (a: Behave | null, b: Behave | null): boolean =>\n a === b || (a !== null && b !== null && a.name === b.name && sameFlatRecord(a.params, b.params));\n\n/** Animation equality: both none, or the same clip, speed and looping. */\nexport const animationEquals = (a: Animation | null, b: Animation | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n a.clip === b.clip &&\n Object.is(a.speed, b.speed) &&\n a.loop === b.loop);\n\n/** Transition equality. */\nexport const transitionEquals = (a: Transition, b: Transition): boolean => {\n if (a === b) return true;\n if (a._tag === 'Instant' || b._tag === 'Instant') return a._tag === b._tag;\n return Object.is(a.seconds, b.seconds) && a.easing === b.easing;\n};\n\n/**\n * Equality of two flat description records: same keys, each value `Object.is`-equal.\n * Material descriptions are flat (numbers, booleans and string literals), so this is\n * exact for them and needs no per-kind code.\n */\nconst sameFlatRecord = (a: object, b: object): boolean => {\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) return false;\n for (const key of keys) {\n if (!Object.is(Reflect.get(a, key), Reflect.get(b, key))) return false;\n }\n return true;\n};\n\n/** Material reference equality: same ownership mode and same kind and parameters, or id. */\nexport const materialRefEquals = (a: MaterialRef, b: MaterialRef): boolean => {\n if (a === b) return true;\n if (a._tag === 'SharedMaterial' || b._tag === 'SharedMaterial') {\n return a._tag === 'SharedMaterial' && b._tag === 'SharedMaterial' && a.id === b.id;\n }\n return sameFlatRecord(a, b);\n};\n\n/** Camera equality: same kind, same lens and same placement. */\nexport const cameraEquals = (a: Camera, b: Camera): boolean => {\n if (a === b) return true;\n const sameLens =\n (a._tag === 'Perspective' && b._tag === 'Perspective' && Object.is(a.fov, b.fov)) ||\n (a._tag === 'Orthographic' && b._tag === 'Orthographic' && Object.is(a.zoom, b.zoom));\n return (\n sameLens &&\n Object.is(a.near, b.near) &&\n Object.is(a.far, b.far) &&\n Object.is(a.damping, b.damping) &&\n Object.is(a.autoRotate, b.autoRotate) &&\n vec3Equals(a.position, b.position) &&\n vec3Equals(a.lookAt, b.lookAt)\n );\n};\n\n/** Render settings equality. */\nexport const renderSettingsEquals = (a: RenderSettings, b: RenderSettings): boolean =>\n a === b ||\n (a.frames === b.frames &&\n Object.is(a.resolution, b.resolution) &&\n a.shadows === b.shadows &&\n a.toneMapping === b.toneMapping &&\n Object.is(a.exposure, b.exposure) &&\n a.colorSpace === b.colorSpace &&\n effectsEqual(a.effects, b.effects));\n\n/** Post-processing equality: the same effects, in order, with the same parameters. */\nexport const effectsEqual = (\n a: ReadonlyArray<PostEffect>,\n b: ReadonlyArray<PostEffect>,\n): boolean => {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const x = a[i];\n const y = b[i];\n if (x === undefined || y === undefined || !sameFlatRecord(x, y)) return false;\n }\n return true;\n};\n\n/** View list equality: the same views, in order, with equal cameras and rects. */\nexport const viewsEqual = (a: ReadonlyArray<View>, b: ReadonlyArray<View>): boolean => {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const x = a[i];\n const y = b[i];\n if (x === undefined || y === undefined) return false;\n if (x.key !== y.key || !cameraEquals(x.camera, y.camera) || !sameFlatRecord(x.rect, y.rect)) {\n return false;\n }\n }\n return true;\n};\n\n/** Order-sensitive equality of shared resource definitions. */\nexport const resourcesEqual = (a: ResourceDefinitions, b: ResourceDefinitions): boolean => {\n if (a === b) return true;\n if (a.geometries.length !== b.geometries.length) return false;\n if (a.materials.length !== b.materials.length) return false;\n for (let i = 0; i < a.geometries.length; i++) {\n const x = a.geometries[i];\n const y = b.geometries[i];\n if (x === undefined || y === undefined) return false;\n if (x.id !== y.id || !geometryRefEquals(x.geometry, y.geometry)) return false;\n }\n for (let i = 0; i < a.materials.length; i++) {\n const x = a.materials[i];\n const y = b.materials[i];\n if (x === undefined || y === undefined) return false;\n if (x.id !== y.id || !materialRefEquals(x.material, y.material)) return false;\n }\n return true;\n};\n\n/** Overlay equality, field by field. */\nconst overlayEquals = (x: Overlay, y: Overlay): boolean =>\n x.key === y.key &&\n x.node === y.node &&\n vec3Equals(x.position, y.position) &&\n x.center === y.center &&\n Object.is(x.distanceFactor, y.distanceFactor) &&\n x.occlude === y.occlude &&\n x.zIndexRange[0] === y.zIndexRange[0] &&\n x.zIndexRange[1] === y.zIndexRange[1] &&\n x.view === y.view;\n\n/** Overlay list equality: the same overlays, in order, with equal fields. */\nexport const overlaysEqual = (a: ReadonlyArray<Overlay>, b: ReadonlyArray<Overlay>): boolean =>\n a === b ||\n (a.length === b.length && a.every((x, i) => b[i] !== undefined && overlayEquals(x, b[i])));\n\n/** Environment equality. */\nexport const environmentEquals = (a: Environment | null, b: Environment | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n a.map === b.map &&\n a.background === b.background &&\n Object.is(a.backgroundBlurriness, b.backgroundBlurriness) &&\n Object.is(a.backgroundIntensity, b.backgroundIntensity) &&\n Object.is(a.environmentIntensity, b.environmentIntensity));\n\n/** Sky equality. */\nexport const skyEquals = (a: Sky | null, b: Sky | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n vec3Equals(a.sunPosition, b.sunPosition) &&\n Object.is(a.turbidity, b.turbidity) &&\n Object.is(a.rayleigh, b.rayleigh) &&\n Object.is(a.mieCoefficient, b.mieCoefficient) &&\n Object.is(a.mieDirectionalG, b.mieDirectionalG) &&\n Object.is(a.clouds, b.clouds) &&\n Object.is(a.distance, b.distance));\n\n/** Contact shadow equality. */\nexport const contactShadowsEquals = (a: ContactShadows | null, b: ContactShadows | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n vec3Equals(a.position, b.position) &&\n a.size[0] === b.size[0] &&\n a.size[1] === b.size[1] &&\n Object.is(a.near, b.near) &&\n Object.is(a.far, b.far) &&\n Object.is(a.blur, b.blur) &&\n a.smooth === b.smooth &&\n Object.is(a.opacity, b.opacity) &&\n a.color === b.color &&\n a.resolution === b.resolution);\n\n/** Body equality, field by field. */\nexport const bodyEquals = (a: Body | null, b: Body | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n a.type === b.type &&\n a.collider === b.collider &&\n Object.is(a.mass, b.mass) &&\n Object.is(a.friction, b.friction) &&\n Object.is(a.restitution, b.restitution) &&\n Object.is(a.linearDamping, b.linearDamping) &&\n Object.is(a.angularDamping, b.angularDamping) &&\n Object.is(a.gravityScale, b.gravityScale) &&\n a.ccd === b.ccd &&\n a.sensor === b.sensor &&\n vec3Equals(a.linearVelocity, b.linearVelocity) &&\n vec3Equals(a.angularVelocity, b.angularVelocity) &&\n (a.impulse === b.impulse ||\n (a.impulse !== null &&\n b.impulse !== null &&\n a.impulse.id === b.impulse.id &&\n vec3Equals(a.impulse.impulse, b.impulse.impulse))) &&\n collidersEqual(a.colliders, b.colliders) &&\n Object.is(a.contactForces, b.contactForces) &&\n groupsEqual(a.collisionGroups, b.collisionGroups) &&\n groupsEqual(a.solverGroups, b.solverGroups));\n\nconst limitsEqual = (a: JointLimits | null, b: JointLimits | null): boolean =>\n a === b || (a !== null && b !== null && Object.is(a[0], b[0]) && Object.is(a[1], b[1]));\n\n/** Joint kind equality. */\nconst jointKindEquals = (a: JointKind, b: JointKind): boolean => {\n switch (a._tag) {\n case 'Fixed':\n return b._tag === 'Fixed' && vec3Equals(a.frameA, b.frameA) && vec3Equals(a.frameB, b.frameB);\n case 'Spherical':\n return b._tag === 'Spherical';\n case 'Revolute':\n case 'Prismatic':\n return (\n b._tag === a._tag &&\n vec3Equals(a.axis, b.axis) &&\n limitsEqual(a.limits, b.limits) &&\n motorEquals(a.motor, b.motor)\n );\n case 'Rope':\n return b._tag === 'Rope' && Object.is(a.length, b.length);\n case 'Spring':\n return (\n b._tag === 'Spring' &&\n Object.is(a.restLength, b.restLength) &&\n Object.is(a.stiffness, b.stiffness) &&\n Object.is(a.damping, b.damping)\n );\n }\n};\n\nconst numbersEqual = (a: ReadonlyArray<number> | null, b: ReadonlyArray<number> | null) =>\n a === b ||\n (a !== null && b !== null && a.length === b.length && a.every((value, i) => value === b[i]));\n\nconst groupsEqual = (a: InteractionGroups | null, b: InteractionGroups | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n numbersEqual(a.memberships, b.memberships) &&\n numbersEqual(a.filters, b.filters));\n\nconst motorEquals = (a: JointMotor | null, b: JointMotor | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n Object.is(a.position, b.position) &&\n Object.is(a.velocity, b.velocity) &&\n Object.is(a.stiffness, b.stiffness) &&\n Object.is(a.damping, b.damping));\n\nconst colliderShapeEquals = (a: ColliderShapeDescription, b: ColliderShapeDescription): boolean => {\n switch (a._tag) {\n case 'Cuboid':\n return b._tag === 'Cuboid' && vec3Equals(a.halfExtents, b.halfExtents);\n case 'Ball':\n return b._tag === 'Ball' && Object.is(a.radius, b.radius);\n case 'Capsule':\n case 'Cylinder':\n case 'Cone':\n return (\n b._tag === a._tag && Object.is(a.halfHeight, b.halfHeight) && Object.is(a.radius, b.radius)\n );\n }\n};\n\n/** Equality of a body's own colliders (`null` for colliders from its geometry). */\nexport const collidersEqual = (\n a: ReadonlyArray<ColliderDescription> | null,\n b: ReadonlyArray<ColliderDescription> | null,\n): boolean => {\n if (a === b) return true;\n if (a === null || b === null || a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const x = a[i];\n const y = b[i];\n if (\n x === undefined ||\n y === undefined ||\n !colliderShapeEquals(x.shape, y.shape) ||\n !vec3Equals(x.position, y.position) ||\n !vec3Equals(x.rotation, y.rotation) ||\n x.name !== y.name\n ) {\n return false;\n }\n }\n return true;\n};\n\nconst refEquals = (a: BodyRef, b: BodyRef): boolean => a.key === b.key && a.instance === b.instance;\n\n/** Joint equality. */\nexport const jointEquals = (a: Joint, b: Joint): boolean =>\n a === b ||\n (a.key === b.key &&\n refEquals(a.a, b.a) &&\n refEquals(a.b, b.b) &&\n vec3Equals(a.anchorA, b.anchorA) &&\n vec3Equals(a.anchorB, b.anchorB) &&\n jointKindEquals(a.kind, b.kind) &&\n a.contacts === b.contacts);\n\nconst jointsEqual = (a: ReadonlyArray<Joint>, b: ReadonlyArray<Joint>): boolean => {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const x = a[i];\n const y = b[i];\n if (x === undefined || y === undefined || !jointEquals(x, y)) return false;\n }\n return true;\n};\n\n/** Label text and type settings equality: everything but the transform and picking. */\nexport const labelTypeEquals = (a: LabelNode, b: LabelNode): boolean =>\n a.text === b.text &&\n a.font === b.font &&\n Object.is(a.fontSize, b.fontSize) &&\n a.color === b.color &&\n Object.is(a.fillOpacity, b.fillOpacity) &&\n Object.is(a.anchorX, b.anchorX) &&\n Object.is(a.anchorY, b.anchorY) &&\n Object.is(a.maxWidth, b.maxWidth) &&\n Object.is(a.lineHeight, b.lineHeight) &&\n Object.is(a.letterSpacing, b.letterSpacing) &&\n a.textAlign === b.textAlign &&\n Object.is(a.outlineWidth, b.outlineWidth) &&\n a.outlineColor === b.outlineColor &&\n Object.is(a.outlineOpacity, b.outlineOpacity) &&\n Object.is(a.outlineBlur, b.outlineBlur) &&\n Object.is(a.curveRadius, b.curveRadius) &&\n a.colorRanges.length === b.colorRanges.length &&\n a.colorRanges.every((range, i) => colorRangeEquals(range, b.colorRanges[i]));\n\nconst colorRangeEquals = (a: LabelColorRange, b: LabelColorRange | undefined): boolean =>\n b !== undefined && a.start === b.start && a.color === b.color;\n\n/** A label's material reference equality (`null` for troika's own). */\nexport const labelMaterialEquals = (a: MaterialRef | null, b: MaterialRef | null): boolean =>\n a === b || (a !== null && b !== null && materialRefEquals(a, b));\n\n/** Shader grid equality, apart from its position and rotation. */\nexport const shaderGridLookEquals = (a: ShaderGridNode, b: ShaderGridNode): boolean =>\n Object.is(a.size[0], b.size[0]) &&\n Object.is(a.size[1], b.size[1]) &&\n Object.is(a.cellSize, b.cellSize) &&\n Object.is(a.cellThickness, b.cellThickness) &&\n a.cellColor === b.cellColor &&\n Object.is(a.sectionSize, b.sectionSize) &&\n Object.is(a.sectionThickness, b.sectionThickness) &&\n a.sectionColor === b.sectionColor &&\n a.infinite === b.infinite &&\n a.followCamera === b.followCamera &&\n Object.is(a.fadeDistance, b.fadeDistance) &&\n Object.is(a.fadeStrength, b.fadeStrength) &&\n Object.is(a.fadeFrom, b.fadeFrom) &&\n a.side === b.side;\n\n/** Physics world equality. */\nexport const physicsEquals = (a: Physics | null, b: Physics | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n vec3Equals(a.gravity, b.gravity) &&\n a.paused === b.paused &&\n Object.is(a.timeStep, b.timeStep) &&\n a.interpolate === b.interpolate &&\n a.debug === b.debug &&\n jointsEqual(a.joints, b.joints));\n\n/** Anchor equality (`b` may be missing). */\nconst xrAnchorEquals = (a: XrAnchor, b: XrAnchor | undefined): boolean =>\n b !== undefined &&\n a.id === b.id &&\n vec3Equals(a.position, b.position) &&\n vec3Equals(a.rotation, b.rotation);\n\n/** Immersive presentation equality. */\nexport const xrEquals = (a: Xr | null, b: Xr | null): boolean =>\n a === b ||\n (a !== null &&\n b !== null &&\n vec3Equals(a.origin, b.origin) &&\n Object.is(a.heading, b.heading) &&\n a.referenceSpace === b.referenceSpace &&\n Object.is(a.framebufferScale, b.framebufferScale) &&\n a.hitTest === b.hitTest &&\n a.showInputs === b.showInputs &&\n (a.glide === b.glide ||\n (a.glide !== null &&\n b.glide !== null &&\n Object.is(a.glide.speed, b.glide.speed) &&\n a.glide.turn === b.glide.turn &&\n Object.is(a.glide.turnSpeed, b.glide.turnSpeed) &&\n Object.is(a.glide.snapDegrees, b.glide.snapDegrees))) &&\n a.planes === b.planes &&\n a.meshes === b.meshes &&\n a.domOverlay === b.domOverlay &&\n a.anchors.length === b.anchors.length &&\n a.anchors.every((anchor, i) => xrAnchorEquals(anchor, b.anchors[i])));\n\n/** Tracked space equality. */\nexport const xrSpaceEquals = (a: XrSpace | null, b: XrSpace | null): boolean => {\n if (a === b) return true;\n if (a === null || b === null) return false;\n switch (a._tag) {\n case 'Head':\n return b._tag === 'Head';\n case 'Joint':\n return b._tag === 'Joint' && a.hand === b.hand && a.joint === b.joint;\n case 'Controller':\n return b._tag === 'Controller' && a.hand === b.hand && a.space === b.space;\n case 'Anchor':\n case 'Plane':\n case 'Mesh':\n return b._tag === a._tag && a.id === b.id;\n }\n};\n",
|
|
12
|
+
"/**\n * Frame-rate monitoring with a performance factor, after Drei's `PerformanceMonitor`\n * (`drei-main/src/core/PerformanceMonitor.tsx` at `bf6f4ad`): frames are averaged over\n * windows of `ms`; once `iterations` averages are in, the factor steps down when more than\n * `threshold` of them fell below the lower bound, and up when more than `threshold` rose\n * above the upper bound. The application decides what the factor means, typically a\n * render resolution.\n *\n * Two differences from Drei: the factor starts at 1 (draw at full resolution until proven\n * slow), and a gap between frames longer than `idleMs` restarts the window, because an\n * on-demand scene that is asleep is idle, not slow.\n *\n * @module\n */\n\nexport type PerformanceOptions = {\n /** Milliseconds per fps average. Default 250. */\n readonly ms?: number;\n /** Averages per decision. Default 10. */\n readonly iterations?: number;\n /** Share of averages that must agree to move the factor. Default 0.75. */\n readonly threshold?: number;\n /** How far one decision moves the factor. Default 0.1. */\n readonly step?: number;\n /** Lower and upper fps bounds for a refresh rate. Default as Drei. */\n readonly bounds?: (refreshRate: number) => readonly [lower: number, upper: number];\n /** A pause between frames longer than this restarts measurement. Default 100. */\n readonly idleMs?: number;\n};\n\n/** A change of performance factor, with the fps average that caused it. */\nexport type PerformanceChange = { readonly fps: number; readonly factor: number };\n\nexport type PerformanceMonitor = {\n /** Records a frame at `nowMs`; returns a change when the factor moved. */\n readonly sample: (nowMs: number) => PerformanceChange | undefined;\n readonly factor: () => number;\n};\n\nconst defaultBounds = (refreshRate: number): readonly [number, number] =>\n refreshRate > 100 ? [60, 100] : [40, 60];\n\n/** Creates a frame-rate monitor. Allocation-free per frame except when a decision is made. */\nexport const createPerformanceMonitor = (options: PerformanceOptions = {}): PerformanceMonitor => {\n const ms = options.ms ?? 250;\n const iterations = options.iterations ?? 10;\n const threshold = options.threshold ?? 0.75;\n const step = options.step ?? 0.1;\n const bounds = options.bounds ?? defaultBounds;\n const idleMs = options.idleMs ?? 100;\n const averages = new Float64Array(iterations);\n let collected = 0;\n let windowStart: number | undefined;\n let lastFrame: number | undefined;\n let framesInWindow = 0;\n let refreshRate = 0;\n let factor = 1;\n\n const restart = (nowMs: number): void => {\n windowStart = nowMs;\n framesInWindow = 0;\n };\n\n const decide = (fps: number): PerformanceChange | undefined => {\n collected = 0;\n const [lower, upper] = bounds(refreshRate);\n let above = 0;\n let below = 0;\n for (const average of averages) {\n if (average >= upper) above++;\n if (average < lower) below++;\n }\n const before = factor;\n if (above > iterations * threshold) factor = Math.min(1, factor + step);\n if (below > iterations * threshold) factor = Math.max(0, factor - step);\n // Round away floating-point drift from repeated steps.\n factor = Math.round(factor * 1000) / 1000;\n return factor === before ? undefined : { fps, factor };\n };\n\n return {\n sample: (nowMs) => {\n const idle = lastFrame === undefined || nowMs - lastFrame > idleMs;\n lastFrame = nowMs;\n if (idle || windowStart === undefined) {\n restart(nowMs);\n return undefined;\n }\n framesInWindow++;\n const elapsed = nowMs - windowStart;\n if (elapsed < ms) return undefined;\n const fps = Math.round((framesInWindow / elapsed) * 1000);\n refreshRate = Math.max(refreshRate, fps);\n averages[collected] = fps;\n collected++;\n restart(nowMs);\n return collected === iterations ? decide(fps) : undefined;\n },\n factor: () => factor,\n };\n};\n",
|
|
13
|
+
"/**\n * Eased transitions of position and scale. A tween's pose is a pure function of scene\n * time: `from + (to - from) * easing(progress)`, so frames are deterministic.\n *\n * @module\n */\nimport type { Object3D, Vector3Tuple } from 'three';\n\nimport type { Easing, Vec3 } from './description.ts';\n\nconst backOvershoot = 1.70158;\n\n/** Maps linear progress in [0, 1] through an easing curve. */\nexport const easeProgress = (easing: Easing, progress: number): number => {\n switch (easing) {\n case 'linear':\n return progress;\n case 'easeInOutCubic':\n return progress < 0.5 ? 4 * progress ** 3 : 1 - (-2 * progress + 2) ** 3 / 2;\n case 'easeOutCubic':\n return 1 - (1 - progress) ** 3;\n case 'easeOutBack':\n return 1 + (backOvershoot + 1) * (progress - 1) ** 3 + backOvershoot * (progress - 1) ** 2;\n }\n};\n\n/** A position and scale transition in flight. */\nexport type Tween = {\n readonly fromPosition: Vector3Tuple;\n readonly fromScale: Vector3Tuple;\n readonly toPosition: Vec3;\n readonly toScale: Vec3;\n /** Scene time the tween started, in seconds. */\n readonly start: number;\n readonly seconds: number;\n readonly easing: Easing;\n};\n\n/** Starts a tween from the object's current pose towards the targets. */\nexport const startTween = (\n object: Object3D,\n target: { readonly position: Vec3; readonly scale: Vec3 },\n start: number,\n transition: { readonly seconds: number; readonly easing: Easing },\n): Tween => ({\n fromPosition: object.position.toArray(),\n fromScale: object.scale.toArray(),\n toPosition: target.position,\n toScale: target.scale,\n start,\n seconds: transition.seconds,\n easing: transition.easing,\n});\n\nconst lerp = (from: number, to: number, amount: number): number => from + (to - from) * amount;\n\n/**\n * Writes the tween's pose at `elapsedSeconds` into the object without allocating.\n * Returns true once the tween has finished, after writing the exact targets.\n */\nexport const applyTween = (object: Object3D, tween: Tween, elapsedSeconds: number): boolean => {\n const progress = Math.min(1, Math.max(0, (elapsedSeconds - tween.start) / tween.seconds));\n if (progress >= 1) {\n object.position.set(tween.toPosition[0], tween.toPosition[1], tween.toPosition[2]);\n object.scale.set(tween.toScale[0], tween.toScale[1], tween.toScale[2]);\n return true;\n }\n const amount = easeProgress(tween.easing, progress);\n object.position.set(\n lerp(tween.fromPosition[0], tween.toPosition[0], amount),\n lerp(tween.fromPosition[1], tween.toPosition[1], amount),\n lerp(tween.fromPosition[2], tween.toPosition[2], amount),\n );\n object.scale.set(\n lerp(tween.fromScale[0], tween.toScale[0], amount),\n lerp(tween.fromScale[1], tween.toScale[1], amount),\n lerp(tween.fromScale[2], tween.toScale[2], amount),\n );\n return false;\n};\n",
|
|
14
|
+
"/**\n * Constructors that fill in defaults and return fully specified descriptions.\n *\n * @module\n */\nimport type {\n AmbientLightNode,\n Animation,\n BasicMaterial,\n Body,\n Behave,\n BorrowedNode,\n Axis,\n BoxGeometry,\n Camera,\n ContactShadows,\n Environment,\n Gestures,\n GridNode,\n Sky,\n Xr,\n LabelAlign,\n LabelAnchorX,\n LabelAnchorY,\n LabelColorRange,\n LabelNode,\n MaterialSide,\n ShaderGridNode,\n TextAlign,\n TextBevel,\n TextGeometry,\n Overlay,\n Physics,\n BodyRef,\n Joint,\n JointKind,\n JointLimits,\n JointMotor,\n InteractionGroups,\n ColliderDescription,\n ColliderShapeDescription,\n CapsuleGeometry,\n CircleGeometry,\n ConeGeometry,\n CylinderGeometry,\n DirectionalLightNode,\n HemisphereLightNode,\n Instance,\n InstancesNode,\n LambertMaterial,\n Easing,\n GeometryRef,\n GroupNode,\n MaterialRef,\n MeshNode,\n NormalMaterial,\n ShadowMaterial,\n OrthographicCamera,\n PhongMaterial,\n PhysicalMaterial,\n PerspectiveCamera,\n PlaneGeometry,\n PointLightNode,\n PostEffect,\n RenderSettings,\n RenderTexture,\n RingGeometry,\n ResourceDefinitions,\n Rgb,\n Rotation,\n SceneDescription,\n SceneNode,\n SphereGeometry,\n SpotLightNode,\n TorusGeometry,\n StandardMaterial,\n Transition,\n Vec3,\n View,\n ViewRect,\n XrAnchor,\n XrGlide,\n XrSpace,\n Handedness,\n HandJoint,\n} from './description.ts';\n\nconst origin: Vec3 = [0, 0, 0];\nconst unitScale: Vec3 = [1, 1, 1];\nconst noRotation: Rotation = { _tag: 'Fixed', euler: origin };\nconst noResources: ResourceDefinitions = { geometries: [], materials: [] };\nconst instantTransition: Transition = { _tag: 'Instant' };\n\n/** Model-owned Euler angles in radians. */\nexport const fixed = (euler: Vec3): Rotation => ({ _tag: 'Fixed', euler });\n\n/** A spin behaviour: `phase + radiansPerSecond * elapsedSeconds` about `axis`. */\nexport const spin = (options: {\n readonly axis: Axis;\n readonly radiansPerSecond: number;\n readonly phase?: number;\n}): Rotation => ({\n _tag: 'Spin',\n axis: options.axis,\n radiansPerSecond: options.radiansPerSecond,\n phase: options.phase ?? 0,\n});\n\n/** Box geometry. Each dimension defaults to 1. */\nexport const box = (\n size: { readonly width?: number; readonly height?: number; readonly depth?: number } = {},\n): BoxGeometry => ({\n _tag: 'Box',\n width: size.width ?? 1,\n height: size.height ?? 1,\n depth: size.depth ?? 1,\n});\n\n/** Sphere geometry. Defaults (as three.js): radius 1, 32 × 16 segments. */\nexport const sphere = (\n options: {\n readonly radius?: number;\n readonly widthSegments?: number;\n readonly heightSegments?: number;\n } = {},\n): SphereGeometry => ({\n _tag: 'Sphere',\n radius: options.radius ?? 1,\n widthSegments: options.widthSegments ?? 32,\n heightSegments: options.heightSegments ?? 16,\n});\n\n/** Plane geometry in the XY plane, facing +Z. Each dimension defaults to 1. */\nexport const plane = (\n size: { readonly width?: number; readonly height?: number } = {},\n): PlaneGeometry => ({ _tag: 'Plane', width: size.width ?? 1, height: size.height ?? 1 });\n\n/** Cylinder geometry along Y. Defaults (as three.js): radius 1 top and bottom, height 1, 32 segments. */\nexport const cylinder = (\n options: {\n readonly radiusTop?: number;\n readonly radiusBottom?: number;\n readonly height?: number;\n readonly radialSegments?: number;\n } = {},\n): CylinderGeometry => ({\n _tag: 'Cylinder',\n radiusTop: options.radiusTop ?? 1,\n radiusBottom: options.radiusBottom ?? 1,\n height: options.height ?? 1,\n radialSegments: options.radialSegments ?? 32,\n});\n\n/** Torus geometry. Defaults (as three.js): radius 1, tube 0.4, 12 × 48 segments. */\nexport const torus = (\n options: {\n readonly radius?: number;\n readonly tube?: number;\n readonly radialSegments?: number;\n readonly tubularSegments?: number;\n } = {},\n): TorusGeometry => ({\n _tag: 'Torus',\n radius: options.radius ?? 1,\n tube: options.tube ?? 0.4,\n radialSegments: options.radialSegments ?? 12,\n tubularSegments: options.tubularSegments ?? 48,\n});\n\n/** Cone geometry along Y. Defaults (as three.js): radius 1, height 1, 32 segments. */\nexport const cone = (\n options: {\n readonly radius?: number;\n readonly height?: number;\n readonly radialSegments?: number;\n } = {},\n): ConeGeometry => ({\n _tag: 'Cone',\n radius: options.radius ?? 1,\n height: options.height ?? 1,\n radialSegments: options.radialSegments ?? 32,\n});\n\n/** Capsule geometry along Y. Defaults (as three.js): radius 1, height 1, 4 cap and 8 radial segments. */\nexport const capsule = (\n options: {\n readonly radius?: number;\n readonly height?: number;\n readonly capSegments?: number;\n readonly radialSegments?: number;\n } = {},\n): CapsuleGeometry => ({\n _tag: 'Capsule',\n radius: options.radius ?? 1,\n height: options.height ?? 1,\n capSegments: options.capSegments ?? 4,\n radialSegments: options.radialSegments ?? 8,\n});\n\n/** Ring geometry facing +Z. Defaults (as three.js): radii 0.5 and 1, 32 segments. */\nexport const ring = (\n options: {\n readonly innerRadius?: number;\n readonly outerRadius?: number;\n readonly thetaSegments?: number;\n } = {},\n): RingGeometry => ({\n _tag: 'Ring',\n innerRadius: options.innerRadius ?? 0.5,\n outerRadius: options.outerRadius ?? 1,\n thetaSegments: options.thetaSegments ?? 32,\n});\n\n/** Circle geometry facing +Z. Defaults (as three.js): radius 1, 32 segments. */\nexport const circle = (\n options: { readonly radius?: number; readonly segments?: number } = {},\n): CircleGeometry => ({\n _tag: 'Circle',\n radius: options.radius ?? 1,\n segments: options.segments ?? 32,\n});\n\n/**\n * Text from the typeface font lent under `font`. Defaults as Drei's `Text3D`: size 1,\n * depth 0.2, 8 curve segments, no bevel (a bevel given defaults to thickness 0.1, size\n * 0.01, offset 0, 4 segments), not centred. Depth 0 draws flat text. Letter spacing (in\n * ems), line height (a multiple of the font's) and alignment default to the font's own\n * layout, left aligned; unlike Drei, where three ignores them, they apply.\n */\nexport const text = (options: {\n readonly text: string;\n readonly font: string;\n readonly size?: number;\n readonly depth?: number;\n readonly curveSegments?: number;\n readonly bevel?: Partial<TextBevel>;\n readonly center?: boolean;\n readonly letterSpacing?: number;\n readonly lineHeight?: number;\n readonly align?: TextAlign;\n}): TextGeometry => ({\n _tag: 'Text',\n text: options.text,\n font: options.font,\n size: options.size ?? 1,\n depth: options.depth ?? 0.2,\n curveSegments: options.curveSegments ?? 8,\n bevel:\n options.bevel === undefined\n ? null\n : {\n thickness: options.bevel.thickness ?? 0.1,\n size: options.bevel.size ?? 0.01,\n offset: options.bevel.offset ?? 0,\n segments: options.bevel.segments ?? 4,\n },\n center: options.center ?? false,\n letterSpacing: options.letterSpacing ?? 0,\n lineHeight: options.lineHeight ?? 1,\n align: options.align ?? 'left',\n});\n\n/** Position and scale changes apply immediately. The default. */\nexport const instant = (): Transition => instantTransition;\n\n/** Position and scale changes ease to their new values over `seconds` of scene time. */\nexport const ease = (options: {\n readonly seconds: number;\n readonly easing?: Easing;\n}): Transition => ({\n _tag: 'Ease',\n seconds: options.seconds,\n easing: options.easing ?? 'easeInOutCubic',\n});\n\n/**\n * Unlit material. Defaults (as three.js): white, opaque, front faces.\n */\nexport const basic = (options: Partial<Omit<BasicMaterial, '_tag'>> = {}): BasicMaterial => ({\n _tag: 'Basic',\n color: options.color ?? 0xffffff,\n map: options.map ?? null,\n opacity: options.opacity ?? 1,\n transparent: options.transparent ?? false,\n side: options.side ?? 'front',\n wireframe: options.wireframe ?? false,\n});\n\n/**\n * Matte material. Defaults (as three.js): white, no emission, smooth shading.\n */\nexport const lambert = (options: Partial<Omit<LambertMaterial, '_tag'>> = {}): LambertMaterial => ({\n _tag: 'Lambert',\n color: options.color ?? 0xffffff,\n map: options.map ?? null,\n emissive: options.emissive ?? 0x000000,\n opacity: options.opacity ?? 1,\n transparent: options.transparent ?? false,\n side: options.side ?? 'front',\n wireframe: options.wireframe ?? false,\n flatShading: options.flatShading ?? false,\n});\n\n/**\n * Shiny material. Defaults (as three.js): white, specular `0x111111`, shininess 30.\n */\nexport const phong = (options: Partial<Omit<PhongMaterial, '_tag'>> = {}): PhongMaterial => ({\n _tag: 'Phong',\n color: options.color ?? 0xffffff,\n map: options.map ?? null,\n emissive: options.emissive ?? 0x000000,\n specular: options.specular ?? 0x111111,\n shininess: options.shininess ?? 30,\n opacity: options.opacity ?? 1,\n transparent: options.transparent ?? false,\n side: options.side ?? 'front',\n wireframe: options.wireframe ?? false,\n flatShading: options.flatShading ?? false,\n});\n\n/**\n * Physically based material. Defaults (as three.js): white, roughness 1, metalness 0.\n */\nexport const standard = (\n options: Partial<Omit<StandardMaterial, '_tag'>> = {},\n): StandardMaterial => ({\n _tag: 'Standard',\n color: options.color ?? 0xffffff,\n map: options.map ?? null,\n roughness: options.roughness ?? 1,\n metalness: options.metalness ?? 0,\n emissive: options.emissive ?? 0x000000,\n emissiveIntensity: options.emissiveIntensity ?? 1,\n opacity: options.opacity ?? 1,\n transparent: options.transparent ?? false,\n side: options.side ?? 'front',\n wireframe: options.wireframe ?? false,\n flatShading: options.flatShading ?? false,\n});\n\n/**\n * Physically based material with clearcoat and transmission. Defaults (as three.js):\n * the standard defaults, no clearcoat or transmission, index of refraction 1.5.\n */\nexport const physical = (\n options: Partial<Omit<PhysicalMaterial, '_tag'>> = {},\n): PhysicalMaterial => ({\n _tag: 'Physical',\n color: options.color ?? 0xffffff,\n map: options.map ?? null,\n roughness: options.roughness ?? 1,\n metalness: options.metalness ?? 0,\n emissive: options.emissive ?? 0x000000,\n emissiveIntensity: options.emissiveIntensity ?? 1,\n clearcoat: options.clearcoat ?? 0,\n clearcoatRoughness: options.clearcoatRoughness ?? 0,\n transmission: options.transmission ?? 0,\n ior: options.ior ?? 1.5,\n opacity: options.opacity ?? 1,\n transparent: options.transparent ?? false,\n side: options.side ?? 'front',\n wireframe: options.wireframe ?? false,\n flatShading: options.flatShading ?? false,\n});\n\n/**\n * Normal-coloured material, for debugging geometry. Defaults as three.js.\n */\nexport const normalMaterial = (\n options: Partial<Omit<NormalMaterial, '_tag'>> = {},\n): NormalMaterial => ({\n _tag: 'Normal',\n opacity: options.opacity ?? 1,\n transparent: options.transparent ?? false,\n side: options.side ?? 'front',\n wireframe: options.wireframe ?? false,\n flatShading: options.flatShading ?? false,\n});\n\n/**\n * A shadow catcher: shows only the shadows cast onto it (three.js's `ShadowMaterial`).\n * Defaults as three.js: black, opacity 1. Needs `render.shadows` and `receiveShadow`.\n */\nexport const shadowMaterial = (\n options: { readonly color?: Rgb; readonly opacity?: number } = {},\n): ShadowMaterial => ({\n _tag: 'Shadow',\n color: options.color ?? 0x000000,\n opacity: options.opacity ?? 1,\n});\n\n/**\n * A grid of lines on the XZ plane (three.js's `GridHelper`). Defaults as three.js: 10\n * across, 10 divisions, lines 0x888888 and centre lines 0x444444, at the origin.\n */\nexport const grid = (options: {\n readonly key: string;\n readonly position?: Vec3;\n readonly size?: number;\n readonly divisions?: number;\n readonly color?: Rgb;\n readonly centerColor?: Rgb;\n}): GridNode => ({\n _tag: 'Grid',\n key: options.key,\n position: options.position ?? origin,\n size: options.size ?? 10,\n divisions: options.divisions ?? 10,\n color: options.color ?? 0x888888,\n centerColor: options.centerColor ?? 0x444444,\n});\n\n/**\n * Drei's `Grid`, with its defaults: a 1 × 1 plane (pass `size`, or `infinite`), cells 0.5\n * apart in black at thickness 0.5, sections 1 apart in `#2080ff` at thickness 1, fading\n * over 100 units from the camera at strength 1, drawn on the back side.\n */\nexport const shaderGrid = (options: {\n readonly key: string;\n readonly position?: Vec3;\n readonly rotation?: Vec3;\n readonly size?: readonly [width: number, height: number];\n readonly cellSize?: number;\n readonly cellThickness?: number;\n readonly cellColor?: Rgb;\n readonly sectionSize?: number;\n readonly sectionThickness?: number;\n readonly sectionColor?: Rgb;\n readonly infinite?: boolean;\n readonly followCamera?: boolean;\n readonly fadeDistance?: number;\n readonly fadeStrength?: number;\n readonly fadeFrom?: number;\n readonly side?: MaterialSide;\n}): ShaderGridNode => ({\n _tag: 'ShaderGrid',\n key: options.key,\n position: options.position ?? origin,\n rotation: options.rotation ?? origin,\n size: options.size ?? [1, 1],\n cellSize: options.cellSize ?? 0.5,\n cellThickness: options.cellThickness ?? 0.5,\n cellColor: options.cellColor ?? 0x000000,\n sectionSize: options.sectionSize ?? 1,\n sectionThickness: options.sectionThickness ?? 1,\n sectionColor: options.sectionColor ?? 0x2080ff,\n infinite: options.infinite ?? false,\n followCamera: options.followCamera ?? false,\n fadeDistance: options.fadeDistance ?? 100,\n fadeStrength: options.fadeStrength ?? 1,\n fadeFrom: options.fadeFrom ?? 1,\n side: options.side ?? 'back',\n});\n\n/** A reference to a shared geometry defined in the scene's resources. */\nexport const sharedGeometry = (id: string): GeometryRef => ({ _tag: 'SharedGeometry', id });\n/** A geometry lent under `id` (`store.lendGeometry`): empty until it is lent. */\nexport const lentGeometry = (id: string): GeometryRef => ({ _tag: 'LentGeometry', id });\n\n/** A reference to a shared material defined in the scene's resources. */\nexport const sharedMaterial = (id: string): MaterialRef => ({ _tag: 'SharedMaterial', id });\n\n/** Key and optional transform shared by `group` and `mesh`. */\nexport type TransformOptions = {\n readonly key: string;\n readonly position?: Vec3;\n readonly rotation?: Rotation;\n readonly scale?: Vec3;\n /** How position and scale changes are shown. Defaults to `instant()`. */\n readonly transition?: Transition /** A registered behaviour to apply on top of the transform. */;\n readonly behaviour?: Behave | null;\n};\n\n/** A group of child nodes. */\nexport const group = (\n options: TransformOptions & {\n readonly interactive?: boolean;\n readonly children?: ReadonlyArray<SceneNode>;\n readonly body?: Body | null;\n readonly follow?: XrSpace | null;\n },\n): GroupNode => ({\n _tag: 'Group',\n key: options.key,\n position: options.position ?? origin,\n rotation: options.rotation ?? noRotation,\n scale: options.scale ?? unitScale,\n transition: options.transition ?? instantTransition,\n behaviour: options.behaviour ?? null,\n interactive: options.interactive ?? false,\n children: options.children ?? [],\n body: options.body ?? null,\n follow: options.follow ?? null,\n});\n\n/** The head (the viewer), for content that stays in view. */\nexport const headSpace = (): XrSpace => ({ _tag: 'Head' });\n\n/** A tracked hand's joint (`index-finger-tip`, say). */\nexport const jointSpace = (hand: Handedness, joint: HandJoint): XrSpace => ({\n _tag: 'Joint',\n hand,\n joint,\n});\n\n/** A controller's grip (where it is held) or its pointing ray. */\nexport const controllerSpace = (hand: Handedness, space: 'grip' | 'ray' = 'grip'): XrSpace => ({\n _tag: 'Controller',\n hand,\n space,\n});\n\n/** An anchor the scene placed with `xr({ anchors })`. */\nexport const anchorSpace = (id: string): XrSpace => ({ _tag: 'Anchor', id });\n\n/** A detected plane, by the id an `XrPlanes` event gave it. */\nexport const planeSpace = (id: string): XrSpace => ({ _tag: 'Plane', id });\n/** A mesh the session detected (`xr({ meshes: true })`), by its id from `XrMeshes`. */\nexport const meshSpace = (id: string): XrSpace => ({ _tag: 'Mesh', id });\n\n/** The id a detected mesh's geometry is lent under, for `xrMesh` and the adapter. */\nexport const xrMeshGeometryId = (id: string): string => `xr-mesh/${id}`;\n\n/**\n * A detected mesh's geometry (`xr({ meshes: true })`), in its own space: put it in a\n * group following `meshSpace(id)`. Empty until the session has detected it.\n */\nexport const xrMesh = (id: string): GeometryRef => lentGeometry(xrMeshGeometryId(id));\n\n/** An anchor at a place in the scene (Euler rotation, unturned by default). */\nexport const xrAnchor = (options: {\n readonly id: string;\n readonly position: Vec3;\n readonly rotation?: Vec3;\n}): XrAnchor => ({\n id: options.id,\n position: options.position,\n rotation: options.rotation ?? origin,\n});\n\n/** A mesh. Not interactive unless `interactive` is true. */\nexport const mesh = (\n options: TransformOptions & {\n readonly geometry: GeometryRef;\n readonly material: MaterialRef;\n readonly interactive?: boolean;\n readonly castShadow?: boolean;\n readonly receiveShadow?: boolean;\n readonly body?: Body | null;\n },\n): MeshNode => ({\n _tag: 'Mesh',\n key: options.key,\n position: options.position ?? origin,\n rotation: options.rotation ?? noRotation,\n scale: options.scale ?? unitScale,\n transition: options.transition ?? instantTransition,\n behaviour: options.behaviour ?? null,\n geometry: options.geometry,\n material: options.material,\n interactive: options.interactive ?? false,\n castShadow: options.castShadow ?? false,\n receiveShadow: options.receiveShadow ?? false,\n body: options.body ?? null,\n});\n\n/**\n * A rigid body for a mesh. Defaults as react-three-rapier's `RigidBody` and Rapier: dynamic,\n * a cuboid collider from the bounding box, density 1, friction 0.5, restitution 0, no\n * damping, gravity scale 1, no CCD, not a sensor, at rest, no impulse.\n */\nexport const body = (options: Partial<Body> = {}): Body => ({\n type: options.type ?? 'dynamic',\n collider: options.collider ?? 'cuboid',\n mass: options.mass ?? null,\n friction: options.friction ?? 0.5,\n restitution: options.restitution ?? 0,\n linearDamping: options.linearDamping ?? 0,\n angularDamping: options.angularDamping ?? 0,\n gravityScale: options.gravityScale ?? 1,\n ccd: options.ccd ?? false,\n sensor: options.sensor ?? false,\n linearVelocity: options.linearVelocity ?? origin,\n angularVelocity: options.angularVelocity ?? origin,\n impulse: options.impulse ?? null,\n colliders: options.colliders ?? null,\n contactForces: options.contactForces ?? null,\n collisionGroups: options.collisionGroups ?? null,\n solverGroups: options.solverGroups ?? null,\n});\n\n/**\n * Collision groups, as react-three-rapier's `interactionGroups(memberships, filters)`:\n * in `memberships` (0 to 15), interacting with `filters` (every group when omitted).\n */\nexport const interactionGroups = (\n memberships: number | ReadonlyArray<number>,\n filters?: number | ReadonlyArray<number>,\n): InteractionGroups => ({\n memberships: typeof memberships === 'number' ? [memberships] : memberships,\n filters: filters === undefined ? null : typeof filters === 'number' ? [filters] : filters,\n});\n\nconst placedCollider = (\n shape: ColliderShapeDescription,\n options: { readonly position?: Vec3; readonly rotation?: Vec3; readonly name?: string | null },\n): ColliderDescription => ({\n shape,\n position: options.position ?? origin,\n rotation: options.rotation ?? origin,\n name: options.name ?? null,\n});\n\n/** A box collider, `halfExtents` from its middle, as react-three-rapier's `CuboidCollider`. */\nexport const cuboidCollider = (options: {\n readonly halfExtents: Vec3;\n readonly position?: Vec3;\n readonly rotation?: Vec3;\n readonly name?: string | null;\n}): ColliderDescription =>\n placedCollider({ _tag: 'Cuboid', halfExtents: options.halfExtents }, options);\n\n/** A ball collider, as `BallCollider`. */\nexport const ballCollider = (options: {\n readonly radius: number;\n readonly position?: Vec3;\n readonly name?: string | null;\n}): ColliderDescription => placedCollider({ _tag: 'Ball', radius: options.radius }, options);\n\ntype Upright = {\n readonly halfHeight: number;\n readonly radius: number;\n readonly position?: Vec3;\n readonly rotation?: Vec3;\n /** The name collisions report this collider by. */\n readonly name?: string | null;\n};\n\n/** A capsule collider along y: `halfHeight` of cylinder, capped by `radius`. */\nexport const capsuleCollider = (options: Upright): ColliderDescription =>\n placedCollider(\n { _tag: 'Capsule', halfHeight: options.halfHeight, radius: options.radius },\n options,\n );\n\n/** A cylinder collider along y. */\nexport const cylinderCollider = (options: Upright): ColliderDescription =>\n placedCollider(\n { _tag: 'Cylinder', halfHeight: options.halfHeight, radius: options.radius },\n options,\n );\n\n/** A cone collider along y, its point up. */\nexport const coneCollider = (options: Upright): ColliderDescription =>\n placedCollider({ _tag: 'Cone', halfHeight: options.halfHeight, radius: options.radius }, options);\n\n/** A motor turning (or sliding) at `velocity`, with `factor` how hard it holds the speed. */\nexport const velocityMotor = (velocity: number, factor = 1): JointMotor => ({\n position: 0,\n velocity,\n stiffness: 0,\n damping: factor,\n});\n\n/** A motor holding `position`, as a spring of `stiffness` damped by `damping`. */\nexport const positionMotor = (\n position: number,\n stiffness: number,\n damping: number,\n): JointMotor => ({\n position,\n velocity: 0,\n stiffness,\n damping,\n});\n\nconst noJoints: ReadonlyArray<Joint> = [];\n\n/**\n * A physics world. Defaults as react-three-rapier's `Physics`: Earth gravity\n * `[0, -9.81, 0]`, running, fixed steps of 1/60 s, interpolated; no joints.\n */\nexport const physics = (options: Partial<Physics> = {}): Physics => ({\n gravity: options.gravity ?? [0, -9.81, 0],\n paused: options.paused ?? false,\n timeStep: options.timeStep ?? 1 / 60,\n interpolate: options.interpolate ?? true,\n debug: options.debug ?? false,\n joints: options.joints ?? noJoints,\n});\n\n/** A node's body (`instance` omitted), or one instance's of an instances node. */\nexport const bodyRef = (key: string, instance: string | null = null): BodyRef => ({\n key,\n instance,\n});\n\nconst refOf = (ref: string | BodyRef): BodyRef => (typeof ref === 'string' ? bodyRef(ref) : ref);\n\n/**\n * A joint between two bodies, named by node key or `bodyRef`. Anchors default to each\n * body's origin; the bodies still collide with each other unless `contacts` is false.\n */\nexport const joint = (options: {\n readonly key: string;\n readonly a: string | BodyRef;\n readonly b: string | BodyRef;\n readonly anchorA?: Vec3;\n readonly anchorB?: Vec3;\n readonly kind: JointKind;\n readonly contacts?: boolean;\n}): Joint => ({\n key: options.key,\n a: refOf(options.a),\n b: refOf(options.b),\n anchorA: options.anchorA ?? origin,\n anchorB: options.anchorB ?? origin,\n kind: options.kind,\n contacts: options.contacts ?? true,\n});\n\n/** Holds two bodies still relative to each other. Frames default to unturned. */\nexport const fixedJoint = (\n options: { readonly frameA?: Vec3; readonly frameB?: Vec3 } = {},\n): JointKind => ({\n _tag: 'Fixed',\n frameA: options.frameA ?? origin,\n frameB: options.frameB ?? origin,\n});\n\n/** A ball and socket at the anchors. */\nexport const sphericalJoint = (): JointKind => ({ _tag: 'Spherical' });\n\n/** A hinge about `axis` (each body's own), limited to `limits` radians and driven by `motor` if given. */\nexport const revoluteJoint = (options: {\n readonly axis: Vec3;\n readonly limits?: JointLimits | null;\n readonly motor?: JointMotor | null;\n}): JointKind => ({\n _tag: 'Revolute',\n axis: options.axis,\n limits: options.limits ?? null,\n motor: options.motor ?? null,\n});\n\n/** A slider along `axis`, limited to `limits` and driven by `motor` if given. */\nexport const prismaticJoint = (options: {\n readonly axis: Vec3;\n readonly limits?: JointLimits | null;\n readonly motor?: JointMotor | null;\n}): JointKind => ({\n _tag: 'Prismatic',\n axis: options.axis,\n limits: options.limits ?? null,\n motor: options.motor ?? null,\n});\n\n/** Keeps the anchors at most `length` apart. */\nexport const ropeJoint = (length: number): JointKind => ({ _tag: 'Rope', length });\n\n/** Pulls the anchors towards `restLength` apart. */\nexport const springJoint = (options: {\n readonly restLength: number;\n readonly stiffness: number;\n readonly damping: number;\n}): JointKind => ({ _tag: 'Spring', ...options });\n\nconst noAnchors: ReadonlyArray<XrAnchor> = [];\n\n/**\n * Gliding with the thumbsticks while presenting. Defaults as pmndrs/xr's\n * `useXRControllerLocomotion`: 2 m/s, a snap turn of 45° (smooth turns at 2 rad/s).\n */\nexport const glide = (options: Partial<XrGlide> = {}): XrGlide => ({\n speed: options.speed ?? 2,\n turn: options.turn ?? 'snap',\n turnSpeed: options.turnSpeed ?? 2,\n snapDegrees: options.snapDegrees ?? 45,\n});\n\n/**\n * Immersive presentation for a scene. Defaults: the player at the scene's origin facing\n * −z, `local-floor` (as pmndrs/xr), the device's framebuffer scale, inputs drawn (rays\n * and hand joints, where pmndrs/xr draws controller and hand models), no AR hit tests.\n */\nexport const xr = (options: Partial<Xr> = {}): Xr => ({\n origin: options.origin ?? origin,\n heading: options.heading ?? 0,\n referenceSpace: options.referenceSpace ?? 'local-floor',\n framebufferScale: options.framebufferScale ?? 1,\n hitTest: options.hitTest ?? false,\n showInputs: options.showInputs ?? true,\n glide: options.glide ?? null,\n anchors: options.anchors ?? noAnchors,\n planes: options.planes ?? false,\n meshes: options.meshes ?? false,\n domOverlay: options.domOverlay ?? false,\n});\n\n/** One instance. Defaults: at the origin, unrotated, unit scale, white. */\nexport const instance = (options: {\n readonly key: string;\n readonly position?: Vec3;\n readonly rotation?: Vec3;\n readonly scale?: Vec3;\n readonly color?: Rgb;\n}): Instance => ({\n key: options.key,\n position: options.position ?? origin,\n rotation: options.rotation ?? origin,\n scale: options.scale ?? unitScale,\n color: options.color ?? 0xffffff,\n});\n\n/** Many instances of one geometry and material, drawn together. Not interactive by default. */\nexport const instances = (\n options: TransformOptions & {\n readonly geometry: GeometryRef;\n readonly material: MaterialRef;\n readonly instances: ReadonlyArray<Instance>;\n readonly interactive?: boolean;\n readonly castShadow?: boolean;\n readonly receiveShadow?: boolean;\n readonly body?: Body | null;\n },\n): InstancesNode => ({\n _tag: 'Instances',\n key: options.key,\n position: options.position ?? origin,\n rotation: options.rotation ?? noRotation,\n scale: options.scale ?? unitScale,\n transition: options.transition ?? instantTransition,\n behaviour: options.behaviour ?? null,\n geometry: options.geometry,\n material: options.material,\n interactive: options.interactive ?? false,\n castShadow: options.castShadow ?? false,\n receiveShadow: options.receiveShadow ?? false,\n instances: options.instances,\n body: options.body ?? null,\n});\n\n/** Applies a registered behaviour by name. Parameters default to the behaviour's own. */\nexport const behave = (name: string, params: Readonly<Record<string, number>> = {}): Behave => ({\n name,\n params,\n});\n\n/** Plays an animation clip by name. Defaults: normal speed, looping. */\nexport const play = (\n clip: string,\n options: { readonly speed?: number; readonly loop?: boolean } = {},\n): Animation => ({ clip, speed: options.speed ?? 1, loop: options.loop ?? true });\n\n/** An object lent to the resource store under `id`. Not interactive by default. */\nexport const borrowed = (\n options: TransformOptions & {\n readonly id: string;\n readonly interactive?: boolean;\n readonly animation?: Animation | null;\n readonly body?: Body | null;\n },\n): BorrowedNode => ({\n _tag: 'Borrowed',\n key: options.key,\n id: options.id,\n animation: options.animation ?? null,\n position: options.position ?? origin,\n rotation: options.rotation ?? noRotation,\n scale: options.scale ?? unitScale,\n transition: options.transition ?? instantTransition,\n behaviour: options.behaviour ?? null,\n interactive: options.interactive ?? false,\n body: options.body ?? null,\n});\n\n/**\n * Text drawn from distance fields (Drei's `Text`). Defaults as Drei's: size 1, anchored at\n * its centre and middle, troika's default font; white, no outline, left-aligned lines,\n * never wrapped, the font's own line height. Not interactive by default.\n */\nconst noColorRanges: ReadonlyArray<LabelColorRange> = [];\n\nexport const label = (\n options: TransformOptions & {\n readonly text: string;\n readonly font?: string | null;\n readonly fontSize?: number;\n readonly color?: Rgb;\n readonly fillOpacity?: number;\n readonly anchorX?: LabelAnchorX;\n readonly anchorY?: LabelAnchorY;\n readonly maxWidth?: number | null;\n readonly lineHeight?: number | null;\n readonly letterSpacing?: number;\n readonly textAlign?: LabelAlign;\n readonly outlineWidth?: number;\n readonly outlineColor?: Rgb;\n readonly outlineOpacity?: number;\n readonly outlineBlur?: number;\n readonly colorRanges?: ReadonlyArray<LabelColorRange>;\n readonly curveRadius?: number;\n readonly material?: MaterialRef | null;\n readonly interactive?: boolean;\n },\n): LabelNode => ({\n _tag: 'Label',\n key: options.key,\n position: options.position ?? origin,\n rotation: options.rotation ?? noRotation,\n scale: options.scale ?? unitScale,\n transition: options.transition ?? instantTransition,\n behaviour: options.behaviour ?? null,\n interactive: options.interactive ?? false,\n text: options.text,\n font: options.font ?? null,\n fontSize: options.fontSize ?? 1,\n color: options.color ?? 0xffffff,\n fillOpacity: options.fillOpacity ?? 1,\n anchorX: options.anchorX ?? 'center',\n anchorY: options.anchorY ?? 'middle',\n maxWidth: options.maxWidth ?? null,\n lineHeight: options.lineHeight ?? null,\n letterSpacing: options.letterSpacing ?? 0,\n textAlign: options.textAlign ?? 'left',\n outlineWidth: options.outlineWidth ?? 0,\n outlineColor: options.outlineColor ?? 0x000000,\n outlineOpacity: options.outlineOpacity ?? 1,\n outlineBlur: options.outlineBlur ?? 0,\n colorRanges: options.colorRanges ?? noColorRanges,\n curveRadius: options.curveRadius ?? 0,\n material: options.material ?? null,\n});\n\n/** A run of a label's characters in `color`, from character index `start`. */\nexport const colorRange = (start: number, color: Rgb): LabelColorRange => ({ start, color });\n\n/** Ambient light. Defaults: white, intensity 1. */\nexport const ambientLight = (options: {\n readonly key: string;\n readonly color?: Rgb;\n readonly intensity?: number;\n}): AmbientLightNode => ({\n _tag: 'AmbientLight',\n key: options.key,\n color: options.color ?? 0xffffff,\n intensity: options.intensity ?? 1,\n});\n\n/**\n * Directional light. Defaults: white, intensity 1, shining from `[0, 1, 0]`; no shadow,\n * or a 512² shadow map covering ±5 world units (three.js's defaults) when casting.\n */\nexport const directionalLight = (options: {\n readonly key: string;\n readonly color?: Rgb;\n readonly intensity?: number;\n readonly position?: Vec3;\n readonly castShadow?: boolean;\n readonly shadowMapSize?: number;\n readonly shadowBias?: number;\n readonly shadowArea?: number;\n}): DirectionalLightNode => ({\n _tag: 'DirectionalLight',\n key: options.key,\n color: options.color ?? 0xffffff,\n intensity: options.intensity ?? 1,\n position: options.position ?? [0, 1, 0],\n castShadow: options.castShadow ?? false,\n shadowMapSize: options.shadowMapSize ?? 512,\n shadowBias: options.shadowBias ?? 0,\n shadowArea: options.shadowArea ?? 5,\n});\n\n/** Point light. Defaults (as three.js): white, intensity 1, at the origin, no cut-off, decay 2. */\nexport const pointLight = (options: {\n readonly key: string;\n readonly color?: Rgb;\n readonly intensity?: number;\n readonly position?: Vec3;\n readonly distance?: number;\n readonly decay?: number;\n readonly castShadow?: boolean;\n readonly shadowMapSize?: number;\n readonly shadowBias?: number;\n}): PointLightNode => ({\n _tag: 'PointLight',\n key: options.key,\n color: options.color ?? 0xffffff,\n intensity: options.intensity ?? 1,\n position: options.position ?? origin,\n distance: options.distance ?? 0,\n decay: options.decay ?? 2,\n castShadow: options.castShadow ?? false,\n shadowMapSize: options.shadowMapSize ?? 512,\n shadowBias: options.shadowBias ?? 0,\n});\n\n/**\n * Spot light. Defaults (as three.js): white, intensity 1, at `[0, 1, 0]` aimed at the\n * origin, no cut-off, a π/3 half-angle, a hard edge and decay 2.\n */\nexport const spotLight = (options: {\n readonly key: string;\n readonly color?: Rgb;\n readonly intensity?: number;\n readonly position?: Vec3;\n readonly target?: Vec3;\n readonly distance?: number;\n readonly angle?: number;\n readonly penumbra?: number;\n readonly decay?: number;\n readonly castShadow?: boolean;\n readonly shadowMapSize?: number;\n readonly shadowBias?: number;\n}): SpotLightNode => ({\n _tag: 'SpotLight',\n key: options.key,\n color: options.color ?? 0xffffff,\n intensity: options.intensity ?? 1,\n position: options.position ?? [0, 1, 0],\n target: options.target ?? origin,\n distance: options.distance ?? 0,\n angle: options.angle ?? Math.PI / 3,\n penumbra: options.penumbra ?? 0,\n decay: options.decay ?? 2,\n castShadow: options.castShadow ?? false,\n shadowMapSize: options.shadowMapSize ?? 512,\n shadowBias: options.shadowBias ?? 0,\n});\n\n/** Hemisphere light. Defaults (as three.js): white sky and ground, intensity 1, from `[0, 1, 0]`. */\nexport const hemisphereLight = (options: {\n readonly key: string;\n readonly color?: Rgb;\n readonly groundColor?: Rgb;\n readonly intensity?: number;\n readonly position?: Vec3;\n}): HemisphereLightNode => ({\n _tag: 'HemisphereLight',\n key: options.key,\n color: options.color ?? 0xffffff,\n groundColor: options.groundColor ?? 0xffffff,\n intensity: options.intensity ?? 1,\n position: options.position ?? [0, 1, 0],\n});\n\n/**\n * Perspective camera. Defaults: fov 50, near 0.1, far 100, at `[0, 0, 5]` looking at the\n * origin, no damping, not turning.\n */\nexport const perspectiveCamera = (\n options: Partial<Omit<PerspectiveCamera, '_tag'>> = {},\n): PerspectiveCamera => ({\n _tag: 'Perspective',\n fov: options.fov ?? 50,\n near: options.near ?? 0.1,\n far: options.far ?? 100,\n position: options.position ?? [0, 0, 5],\n lookAt: options.lookAt ?? origin,\n damping: options.damping ?? 0,\n autoRotate: options.autoRotate ?? 0,\n});\n\n/**\n * Orthographic camera. Defaults (as React Three Fiber): zoom 1 (one CSS pixel per world\n * unit, so set it), near 0.1, far 1000, at `[0, 0, 5]` looking at the origin.\n */\nexport const orthographicCamera = (\n options: Partial<Omit<OrthographicCamera, '_tag'>> = {},\n): OrthographicCamera => ({\n _tag: 'Orthographic',\n zoom: options.zoom ?? 1,\n near: options.near ?? 0.1,\n far: options.far ?? 1000,\n position: options.position ?? [0, 0, 5],\n lookAt: options.lookAt ?? origin,\n damping: options.damping ?? 0,\n autoRotate: options.autoRotate ?? 0,\n});\n\nconst noEffects: ReadonlyArray<PostEffect> = [];\n\n/**\n * Bloom: bright areas glow. Defaults: strength 1 (as three.js), radius 0.4 and threshold\n * 0.85, so only the brightest areas bloom (three.js leaves these two unset).\n */\nexport const bloom = (\n options: {\n readonly strength?: number;\n readonly radius?: number;\n readonly threshold?: number;\n } = {},\n): PostEffect => ({\n _tag: 'Bloom',\n strength: options.strength ?? 1,\n radius: options.radius ?? 0.4,\n threshold: options.threshold ?? 0.85,\n});\n\n/** Vignette: darker edges. Defaults (as three.js's `VignetteShader`): offset 1, darkness 1. */\nexport const vignette = (\n options: { readonly offset?: number; readonly darkness?: number } = {},\n): PostEffect => ({\n _tag: 'Vignette',\n offset: options.offset ?? 1,\n darkness: options.darkness ?? 1,\n});\n\n/** Film grain. Defaults (as three.js's `FilmPass`): intensity 0.5, in colour. */\nexport const film = (\n options: { readonly intensity?: number; readonly grayscale?: boolean } = {},\n): PostEffect => ({\n _tag: 'Film',\n intensity: options.intensity ?? 0.5,\n grayscale: options.grayscale ?? false,\n});\n\n/**\n * Render settings. Defaults: frames on demand, full resolution, shadows off, no tone\n * mapping, exposure 1, sRGB output. Two deliberate differences from React Three Fiber:\n *\n * - Frames default to `demand`, not `always`. Every visual change passes through the\n * kernel, which knows when a frame is needed, so nothing has to call `invalidate` and\n * idle scenes stop drawing.\n * - Tone mapping defaults to `none`, not ACES, so a validated palette renders as given.\n */\nexport const renderSettings = (options: Partial<RenderSettings> = {}): RenderSettings => ({\n frames: options.frames ?? 'demand',\n effects: options.effects ?? noEffects,\n resolution: options.resolution ?? 1,\n shadows: options.shadows ?? 'off',\n toneMapping: options.toneMapping ?? 'none',\n exposure: options.exposure ?? 1,\n colorSpace: options.colorSpace ?? 'srgb',\n});\n\nconst defaultRenderSettings = renderSettings();\n\nconst fullRect: ViewRect = { x: 0, y: 0, width: 1, height: 1 };\nconst noViews: ReadonlyArray<View> = [];\n\n/** A view of the scene through `camera` into `rect` of the canvas (default: all of it). */\nexport const view = (options: {\n readonly key: string;\n readonly camera: Camera;\n readonly rect?: Partial<ViewRect>;\n}): View => ({\n key: options.key,\n camera: options.camera,\n rect: {\n x: options.rect?.x ?? fullRect.x,\n y: options.rect?.y ?? fullRect.y,\n width: options.rect?.width ?? fullRect.width,\n height: options.rect?.height ?? fullRect.height,\n },\n});\n\nconst noRenderTextures: ReadonlyArray<RenderTexture> = [];\n\n/**\n * A scene rendered into a texture, lent under `id` for materials' `map`. Defaults:\n * 512 × 512, the default camera, transparent.\n */\nexport const renderTexture = (options: {\n readonly id: string;\n readonly width?: number;\n readonly height?: number;\n readonly camera?: Camera;\n readonly background?: Rgb | null;\n readonly children?: ReadonlyArray<SceneNode>;\n}): RenderTexture => ({\n id: options.id,\n width: options.width ?? 512,\n height: options.height ?? 512,\n camera: options.camera ?? perspectiveCamera(),\n background: options.background ?? null,\n children: options.children ?? [],\n});\n\n/** A scene description. */\n/**\n * Image-based lighting (Drei's `Environment`). Defaults as Drei: lighting only, no blur,\n * intensities 1. Without `map`, three.js's `RoomEnvironment`; with it, the equirectangular\n * texture lent under that id.\n */\nexport const environment = (\n options: {\n readonly map?: string;\n readonly background?: boolean | 'only';\n readonly backgroundBlurriness?: number;\n readonly backgroundIntensity?: number;\n readonly environmentIntensity?: number;\n } = {},\n): Environment => ({\n map: options.map ?? null,\n background: options.background ?? false,\n backgroundBlurriness: options.backgroundBlurriness ?? 0,\n backgroundIntensity: options.backgroundIntensity ?? 1,\n environmentIntensity: options.environmentIntensity ?? 1,\n});\n\n/**\n * Where Drei puts the sun from an inclination and azimuth, both 0 to 1\n * (`calcPosFromAngles` in `src/core/Sky.tsx`).\n */\nexport const sunPositionFromAngles = (inclination: number, azimuth: number): Vec3 => {\n const theta = Math.PI * (inclination - 0.5);\n const phi = 2 * Math.PI * (azimuth - 0.5);\n return [Math.cos(phi), Math.sin(theta), Math.sin(phi)];\n};\n\n/**\n * A daylight sky. Defaults as Drei's `Sky`: the sun from inclination 0.6 and azimuth 0.1,\n * turbidity 10, rayleigh 0.5, mie coefficient 0.005 and directional G 0.8, distance 1000,\n * and no clouds. The sky is high dynamic range: use tone mapping (`aces`, as three.js's\n * example and React Three Fiber's default), or it washes out to white.\n */\nexport const sky = (options: Partial<Sky> = {}): Sky => ({\n sunPosition: options.sunPosition ?? sunPositionFromAngles(0.6, 0.1),\n turbidity: options.turbidity ?? 10,\n rayleigh: options.rayleigh ?? 0.5,\n mieCoefficient: options.mieCoefficient ?? 0.005,\n mieDirectionalG: options.mieDirectionalG ?? 0.8,\n clouds: options.clouds ?? 0,\n distance: options.distance ?? 1000,\n});\n\n/**\n * Soft ground shadows (Drei's `ContactShadows`). Defaults as Drei: a 10 × 10 plane at the\n * origin (Drei's `scale` 10), shadows from 0 to 10 units above, blur 1 with the smooth\n * pass, opacity 1, black, 512 texels.\n */\nexport const contactShadows = (\n options: {\n readonly position?: Vec3;\n readonly size?: number | readonly [number, number];\n readonly near?: number;\n readonly far?: number;\n readonly blur?: number;\n readonly smooth?: boolean;\n readonly opacity?: number;\n readonly color?: Rgb;\n readonly resolution?: number;\n } = {},\n): ContactShadows => {\n const size = options.size ?? 10;\n return {\n position: options.position ?? origin,\n size: typeof size === 'number' ? [size, size] : size,\n near: options.near ?? 0,\n far: options.far ?? 10,\n blur: options.blur ?? 1,\n smooth: options.smooth ?? true,\n opacity: options.opacity ?? 1,\n color: options.color ?? 0x000000,\n resolution: options.resolution ?? 512,\n };\n};\n\nconst noOverlays: ReadonlyArray<Overlay> = [];\nconst noMeasures: ReadonlyArray<string> = [];\n\n/** Drei's `zIndexRange` default: near points on top, far ones at 0. */\nconst defaultZIndexRange: readonly [number, number] = [16777271, 0];\n\n/**\n * A point to show HTML at (Drei's `Html`). Defaults: world space at the origin, not\n * centred, constant size, never occluded, Drei's z-index range, the main camera.\n */\nexport const overlay = (options: {\n readonly key: string;\n readonly node?: string;\n readonly position?: Vec3;\n readonly center?: boolean;\n readonly distanceFactor?: number;\n readonly occlude?: boolean;\n readonly zIndexRange?: readonly [number, number];\n readonly view?: string;\n}): Overlay => ({\n key: options.key,\n node: options.node ?? null,\n position: options.position ?? origin,\n center: options.center ?? false,\n distanceFactor: options.distanceFactor ?? null,\n occlude: options.occlude ?? false,\n zIndexRange: options.zIndexRange ?? defaultZIndexRange,\n view: options.view ?? null,\n});\n\nexport const scene = (options: {\n readonly camera?: Camera;\n readonly gestures?: Gestures;\n readonly views?: ReadonlyArray<View>;\n readonly renderTextures?: ReadonlyArray<RenderTexture>;\n readonly overlays?: ReadonlyArray<Overlay>;\n /** Optional staging: leave out or pass `null` for none, so a Model can switch it off. */\n readonly environment?: Environment | null;\n readonly sky?: Sky | null;\n readonly contactShadows?: ContactShadows | null;\n readonly physics?: Physics | null;\n readonly xr?: Xr | null;\n readonly measure?: ReadonlyArray<string>;\n readonly render?: RenderSettings;\n readonly resources?: Partial<ResourceDefinitions>;\n readonly children?: ReadonlyArray<SceneNode>;\n}): SceneDescription => ({\n camera: options.camera ?? perspectiveCamera(),\n gestures: options.gestures ?? 'page',\n views: options.views ?? noViews,\n renderTextures: options.renderTextures ?? noRenderTextures,\n overlays: options.overlays ?? noOverlays,\n environment: options.environment ?? null,\n sky: options.sky ?? null,\n contactShadows: options.contactShadows ?? null,\n physics: options.physics ?? null,\n xr: options.xr ?? null,\n measure: options.measure ?? noMeasures,\n render: options.render ?? defaultRenderSettings,\n resources: {\n geometries: options.resources?.geometries ?? noResources.geometries,\n materials: options.resources?.materials ?? noResources.materials,\n },\n children: options.children ?? [],\n});\n",
|
|
15
|
+
"/**\n * Flattened, validated view of a scene description, used by the diff.\n *\n * @module\n */\nimport type { Joint, SceneDescription, SceneNode } from './description.ts';\n\n/** Parent of a node: another node's key, or `null` for the scene root. */\nexport type ParentKey = string | null;\n\n/** A node with its position in the tree. */\nexport type IndexedNode = {\n readonly node: SceneNode;\n readonly parent: ParentKey;\n};\n\n/** A description is rejected as a whole; nothing is applied (no partial updates). */\nexport type DescriptionError =\n | { readonly _tag: 'DuplicateKey'; readonly key: string }\n | {\n readonly _tag: 'DuplicateResourceId';\n readonly resource: 'geometry' | 'material';\n readonly id: string;\n }\n | { readonly _tag: 'UnknownSharedGeometry'; readonly nodeKey: string; readonly id: string }\n | { readonly _tag: 'UnknownSharedMaterial'; readonly nodeKey: string; readonly id: string }\n | { readonly _tag: 'DuplicateInstanceKey'; readonly nodeKey: string; readonly key: string }\n | { readonly _tag: 'UnknownBehaviour'; readonly nodeKey: string; readonly name: string }\n | { readonly _tag: 'DuplicateViewKey'; readonly key: string }\n | { readonly _tag: 'DuplicateRenderTextureId'; readonly id: string }\n | { readonly _tag: 'DuplicateOverlayKey'; readonly key: string }\n | { readonly _tag: 'UnknownOverlayNode'; readonly key: string; readonly node: string }\n | { readonly _tag: 'UnknownOverlayView'; readonly key: string; readonly view: string }\n | { readonly _tag: 'UnknownMeasuredNode'; readonly key: string }\n /** Two joints share a key. */\n | { readonly _tag: 'DuplicateJointKey'; readonly key: string }\n /** A joint names a node that is not in the scene. */\n | { readonly _tag: 'UnknownJointBody'; readonly joint: string; readonly body: string };\n\n/** A validated scene. Keys are unique across the whole scene. */\nexport type SceneIndex = {\n readonly description: SceneDescription | null;\n readonly nodes: ReadonlyMap<string, IndexedNode>;\n /** Child keys per parent, in description order. Includes the root (`null`). */\n readonly children: ReadonlyMap<ParentKey, ReadonlyArray<string>>;\n /** Keys in depth-first pre-order: parents always precede their children. */\n readonly preOrder: ReadonlyArray<string>;\n};\n\n/** The index of the empty scene that every graph starts from. */\nexport const emptyIndex: SceneIndex = {\n description: null,\n nodes: new Map(),\n children: new Map([[null, []]]),\n preOrder: [],\n};\n\nexport type IndexResult =\n | { readonly _tag: 'Indexed'; readonly index: SceneIndex }\n | { readonly _tag: 'Invalid'; readonly error: DescriptionError };\n\n/** A node waiting to be indexed: its index entry, and the list its key joins. */\ntype Stacked = IndexedNode & { readonly siblings: Array<string> };\n\n/** The first instance key used twice, if any. */\nconst firstDuplicateInstance = (\n instances: ReadonlyArray<{ readonly key: string }>,\n): string | undefined => {\n const seen = new Set<string>();\n for (const { key } of instances) {\n if (seen.has(key)) return key;\n seen.add(key);\n }\n return undefined;\n};\n\n/** The first joint error: a key used twice, or a body naming no node. */\nconst jointsError = (\n joints: ReadonlyArray<Joint>,\n nodes: ReadonlyMap<string, IndexedNode>,\n): DescriptionError | undefined => {\n const duplicate = firstDuplicateInstance(joints);\n if (duplicate !== undefined) return { _tag: 'DuplicateJointKey', key: duplicate };\n for (const joint of joints) {\n for (const { key } of [joint.a, joint.b]) {\n if (!nodes.has(key)) return { _tag: 'UnknownJointBody', joint: joint.key, body: key };\n }\n }\n return undefined;\n};\n\n/** Validates and flattens a description. */\nexport const indexScene = (\n description: SceneDescription,\n behaviours: ReadonlySet<string> = new Set(),\n): IndexResult => {\n const duplicateTexture = firstDuplicateInstance(\n description.renderTextures.map((texture) => ({ key: texture.id })),\n );\n if (duplicateTexture !== undefined) {\n return { _tag: 'Invalid', error: { _tag: 'DuplicateRenderTextureId', id: duplicateTexture } };\n }\n const duplicateView = firstDuplicateInstance(description.views);\n if (duplicateView !== undefined) {\n return { _tag: 'Invalid', error: { _tag: 'DuplicateViewKey', key: duplicateView } };\n }\n const duplicateOverlay = firstDuplicateInstance(description.overlays);\n if (duplicateOverlay !== undefined) {\n return { _tag: 'Invalid', error: { _tag: 'DuplicateOverlayKey', key: duplicateOverlay } };\n }\n const viewKeys = new Set(description.views.map((view) => view.key));\n const strayView = description.overlays.find(\n (overlay) => overlay.view !== null && !viewKeys.has(overlay.view),\n );\n if (strayView?.view != null) {\n return {\n _tag: 'Invalid',\n error: { _tag: 'UnknownOverlayView', key: strayView.key, view: strayView.view },\n };\n }\n const geometryIds = new Set<string>();\n for (const { id } of description.resources.geometries) {\n if (geometryIds.has(id)) {\n return { _tag: 'Invalid', error: { _tag: 'DuplicateResourceId', resource: 'geometry', id } };\n }\n geometryIds.add(id);\n }\n const materialIds = new Set<string>();\n for (const { id } of description.resources.materials) {\n if (materialIds.has(id)) {\n return { _tag: 'Invalid', error: { _tag: 'DuplicateResourceId', resource: 'material', id } };\n }\n materialIds.add(id);\n }\n\n const nodes = new Map<string, IndexedNode>();\n const rootChildren: Array<string> = [];\n const children = new Map<ParentKey, Array<string>>([[null, rootChildren]]);\n const preOrder: Array<string> = [];\n // Explicit stack instead of recursion: deep scenes cannot overflow the call stack. Each\n // item becomes the node's index entry, and carries its parent's child list, so indexing\n // a node allocates nothing else.\n const stack: Array<Stacked> = [];\n for (let i = description.children.length - 1; i >= 0; i--) {\n const node = description.children[i];\n if (node !== undefined) stack.push({ node, parent: null, siblings: rootChildren });\n }\n for (let item = stack.pop(); item !== undefined; item = stack.pop()) {\n const { node } = item;\n if (nodes.has(node.key))\n return { _tag: 'Invalid', error: { _tag: 'DuplicateKey', key: node.key } };\n if (\n node._tag === 'Label' &&\n node.material?._tag === 'SharedMaterial' &&\n !materialIds.has(node.material.id)\n ) {\n return {\n _tag: 'Invalid',\n error: { _tag: 'UnknownSharedMaterial', nodeKey: node.key, id: node.material.id },\n };\n }\n if (node._tag === 'Mesh' || node._tag === 'Instances') {\n if (node.geometry._tag === 'SharedGeometry' && !geometryIds.has(node.geometry.id)) {\n return {\n _tag: 'Invalid',\n error: { _tag: 'UnknownSharedGeometry', nodeKey: node.key, id: node.geometry.id },\n };\n }\n if (node.material._tag === 'SharedMaterial' && !materialIds.has(node.material.id)) {\n return {\n _tag: 'Invalid',\n error: { _tag: 'UnknownSharedMaterial', nodeKey: node.key, id: node.material.id },\n };\n }\n }\n if ('behaviour' in node && node.behaviour !== null && !behaviours.has(node.behaviour.name)) {\n return {\n _tag: 'Invalid',\n error: { _tag: 'UnknownBehaviour', nodeKey: node.key, name: node.behaviour.name },\n };\n }\n if (node._tag === 'Instances') {\n const duplicate = firstDuplicateInstance(node.instances);\n if (duplicate !== undefined) {\n return {\n _tag: 'Invalid',\n error: { _tag: 'DuplicateInstanceKey', nodeKey: node.key, key: duplicate },\n };\n }\n }\n nodes.set(node.key, item);\n preOrder.push(node.key);\n item.siblings.push(node.key);\n if (node._tag === 'Group') {\n const siblings: Array<string> = [];\n children.set(node.key, siblings);\n for (let i = node.children.length - 1; i >= 0; i--) {\n const child = node.children[i];\n if (child !== undefined) stack.push({ node: child, parent: node.key, siblings });\n }\n }\n }\n const strayNode = description.overlays.find(\n (overlay) => overlay.node !== null && !nodes.has(overlay.node),\n );\n if (strayNode?.node != null) {\n return {\n _tag: 'Invalid',\n error: { _tag: 'UnknownOverlayNode', key: strayNode.key, node: strayNode.node },\n };\n }\n const unmeasurable = description.measure.find((key) => !nodes.has(key));\n if (unmeasurable !== undefined) {\n return { _tag: 'Invalid', error: { _tag: 'UnknownMeasuredNode', key: unmeasurable } };\n }\n const jointError = jointsError(description.physics?.joints ?? [], nodes);\n if (jointError !== undefined) return { _tag: 'Invalid', error: jointError };\n return { _tag: 'Indexed', index: { description, nodes, children, preOrder } };\n};\n",
|
|
16
|
+
"/**\n * Keyed diff: `(previous index, next description) => operations`.\n *\n * Pure. Operations are emitted in the order the applier must run them:\n *\n * 1. `SetCamera`, `DefineResources`\n * 2. `Create`, `Replace`, `Move`, `Update` in depth-first pre-order (parents first)\n * 3. `Remove`\n * 4. `Order`, only where child order would otherwise be wrong\n *\n * Keys are unique across the scene, so a node keeps its identity when it moves between\n * parents. A node whose kind changes under the same key is replaced.\n *\n * @module\n */\nimport type {\n Camera,\n RenderSettings,\n ResourceDefinitions,\n SceneDescription,\n SceneNode,\n View,\n} from './description.ts';\nimport {\n cameraEquals,\n renderSettingsEquals,\n animationEquals,\n behaviourEquals,\n bodyEquals,\n geometryRefEquals,\n labelMaterialEquals,\n labelTypeEquals,\n xrSpaceEquals,\n shaderGridLookEquals,\n instancesEqual,\n materialRefEquals,\n resourcesEqual,\n rotationEquals,\n transitionEquals,\n viewsEqual,\n vec3Equals,\n} from './equality.ts';\nimport {\n type DescriptionError,\n indexScene,\n type ParentKey,\n type SceneIndex,\n} from './sceneIndex.ts';\n\n/** A node property that an `Update` changes. */\nexport type Field =\n | 'position'\n | 'rotation'\n | 'scale'\n | 'transition'\n | 'geometry'\n | 'material'\n | 'interactive'\n | 'color'\n | 'intensity'\n | 'groundColor'\n | 'target'\n | 'distance'\n | 'angle'\n | 'penumbra'\n | 'decay'\n | 'castShadow'\n | 'receiveShadow'\n | 'shadowMapSize'\n | 'shadowBias'\n | 'shadowArea'\n | 'instances'\n | 'id'\n | 'animation'\n | 'behaviour'\n | 'size'\n | 'divisions'\n | 'centerColor'\n | 'body'\n /** A label's text or any of its type settings. */\n | 'text'\n /** A shader grid's look: anything but where it is. */\n | 'grid'\n /** The tracked space a group follows. */\n | 'follow';\n\n/** A single change to apply to the hosted scene graph. */\nexport type Op =\n | { readonly _tag: 'SetCamera'; readonly camera: Camera }\n | { readonly _tag: 'SetViews'; readonly views: ReadonlyArray<View> }\n /** A render texture was created, resized or its scene changed (its own operations). */\n | { readonly _tag: 'UpdateRenderTexture'; readonly id: string; readonly ops: ReadonlyArray<Op> }\n | { readonly _tag: 'RemoveRenderTexture'; readonly id: string }\n | { readonly _tag: 'SetRenderSettings'; readonly settings: RenderSettings }\n | { readonly _tag: 'DefineResources'; readonly resources: ResourceDefinitions }\n | { readonly _tag: 'Create'; readonly node: SceneNode; readonly parent: ParentKey }\n | { readonly _tag: 'Replace'; readonly node: SceneNode; readonly parent: ParentKey }\n | { readonly _tag: 'Move'; readonly key: string; readonly parent: ParentKey }\n | {\n readonly _tag: 'Update';\n readonly node: SceneNode;\n readonly fields: ReadonlyArray<Field>;\n }\n | { readonly _tag: 'Remove'; readonly key: string }\n | { readonly _tag: 'Order'; readonly parent: ParentKey; readonly keys: ReadonlyArray<string> };\n\nexport type DiffResult =\n | { readonly _tag: 'Diffed'; readonly ops: ReadonlyArray<Op>; readonly index: SceneIndex }\n | { readonly _tag: 'Invalid'; readonly error: DescriptionError };\n\nconst noFields: ReadonlyArray<Field> = [];\n\n/**\n * Fields that differ between two nodes, or `undefined` when the kind changed and the\n * node must be replaced.\n */\nexport const changedFields = (\n prev: SceneNode,\n next: SceneNode,\n): ReadonlyArray<Field> | undefined => {\n if (prev === next) return noFields;\n const fields: Array<Field> = [];\n switch (next._tag) {\n case 'Group': {\n if (prev._tag !== 'Group') return undefined;\n if (!behaviourEquals(prev.behaviour, next.behaviour)) fields.push('behaviour');\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (!rotationEquals(prev.rotation, next.rotation)) fields.push('rotation');\n if (!vec3Equals(prev.scale, next.scale)) fields.push('scale');\n if (!transitionEquals(prev.transition, next.transition)) fields.push('transition');\n if (prev.interactive !== next.interactive) fields.push('interactive');\n if (!bodyEquals(prev.body, next.body)) fields.push('body');\n if (!xrSpaceEquals(prev.follow, next.follow)) fields.push('follow');\n return fields;\n }\n case 'Mesh': {\n if (prev._tag !== 'Mesh') return undefined;\n if (!behaviourEquals(prev.behaviour, next.behaviour)) fields.push('behaviour');\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (!rotationEquals(prev.rotation, next.rotation)) fields.push('rotation');\n if (!vec3Equals(prev.scale, next.scale)) fields.push('scale');\n if (!transitionEquals(prev.transition, next.transition)) fields.push('transition');\n if (!geometryRefEquals(prev.geometry, next.geometry)) fields.push('geometry');\n if (!materialRefEquals(prev.material, next.material)) fields.push('material');\n if (prev.interactive !== next.interactive) fields.push('interactive');\n if (prev.castShadow !== next.castShadow) fields.push('castShadow');\n if (prev.receiveShadow !== next.receiveShadow) fields.push('receiveShadow');\n if (!bodyEquals(prev.body, next.body)) fields.push('body');\n return fields;\n }\n case 'Instances': {\n if (prev._tag !== 'Instances') return undefined;\n if (!behaviourEquals(prev.behaviour, next.behaviour)) fields.push('behaviour');\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (!rotationEquals(prev.rotation, next.rotation)) fields.push('rotation');\n if (!vec3Equals(prev.scale, next.scale)) fields.push('scale');\n if (!transitionEquals(prev.transition, next.transition)) fields.push('transition');\n if (!geometryRefEquals(prev.geometry, next.geometry)) fields.push('geometry');\n if (!materialRefEquals(prev.material, next.material)) fields.push('material');\n if (prev.interactive !== next.interactive) fields.push('interactive');\n if (prev.castShadow !== next.castShadow) fields.push('castShadow');\n if (prev.receiveShadow !== next.receiveShadow) fields.push('receiveShadow');\n if (!instancesEqual(prev.instances, next.instances)) fields.push('instances');\n if (!bodyEquals(prev.body, next.body)) fields.push('body');\n return fields;\n }\n case 'Borrowed': {\n if (prev._tag !== 'Borrowed') return undefined;\n if (!behaviourEquals(prev.behaviour, next.behaviour)) fields.push('behaviour');\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (!rotationEquals(prev.rotation, next.rotation)) fields.push('rotation');\n if (!vec3Equals(prev.scale, next.scale)) fields.push('scale');\n if (!transitionEquals(prev.transition, next.transition)) fields.push('transition');\n if (prev.id !== next.id) fields.push('id');\n if (!animationEquals(prev.animation, next.animation)) fields.push('animation');\n if (prev.interactive !== next.interactive) fields.push('interactive');\n if (!bodyEquals(prev.body, next.body)) fields.push('body');\n return fields;\n }\n case 'Label': {\n if (prev._tag !== 'Label') return undefined;\n if (!behaviourEquals(prev.behaviour, next.behaviour)) fields.push('behaviour');\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (!rotationEquals(prev.rotation, next.rotation)) fields.push('rotation');\n if (!vec3Equals(prev.scale, next.scale)) fields.push('scale');\n if (!transitionEquals(prev.transition, next.transition)) fields.push('transition');\n if (prev.interactive !== next.interactive) fields.push('interactive');\n if (!labelTypeEquals(prev, next)) fields.push('text');\n if (!labelMaterialEquals(prev.material, next.material)) fields.push('material');\n return fields;\n }\n case 'AmbientLight': {\n if (prev._tag !== 'AmbientLight') return undefined;\n if (!Object.is(prev.color, next.color)) fields.push('color');\n if (!Object.is(prev.intensity, next.intensity)) fields.push('intensity');\n return fields;\n }\n case 'DirectionalLight': {\n if (prev._tag !== 'DirectionalLight') return undefined;\n if (!Object.is(prev.color, next.color)) fields.push('color');\n if (!Object.is(prev.intensity, next.intensity)) fields.push('intensity');\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (prev.castShadow !== next.castShadow) fields.push('castShadow');\n if (!Object.is(prev.shadowMapSize, next.shadowMapSize)) fields.push('shadowMapSize');\n if (!Object.is(prev.shadowBias, next.shadowBias)) fields.push('shadowBias');\n if (!Object.is(prev.shadowArea, next.shadowArea)) fields.push('shadowArea');\n return fields;\n }\n case 'PointLight': {\n if (prev._tag !== 'PointLight') return undefined;\n if (!Object.is(prev.color, next.color)) fields.push('color');\n if (!Object.is(prev.intensity, next.intensity)) fields.push('intensity');\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (!Object.is(prev.distance, next.distance)) fields.push('distance');\n if (!Object.is(prev.decay, next.decay)) fields.push('decay');\n if (prev.castShadow !== next.castShadow) fields.push('castShadow');\n if (!Object.is(prev.shadowMapSize, next.shadowMapSize)) fields.push('shadowMapSize');\n if (!Object.is(prev.shadowBias, next.shadowBias)) fields.push('shadowBias');\n return fields;\n }\n case 'SpotLight': {\n if (prev._tag !== 'SpotLight') return undefined;\n if (!Object.is(prev.color, next.color)) fields.push('color');\n if (!Object.is(prev.intensity, next.intensity)) fields.push('intensity');\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (!vec3Equals(prev.target, next.target)) fields.push('target');\n if (!Object.is(prev.distance, next.distance)) fields.push('distance');\n if (!Object.is(prev.angle, next.angle)) fields.push('angle');\n if (!Object.is(prev.penumbra, next.penumbra)) fields.push('penumbra');\n if (!Object.is(prev.decay, next.decay)) fields.push('decay');\n if (prev.castShadow !== next.castShadow) fields.push('castShadow');\n if (!Object.is(prev.shadowMapSize, next.shadowMapSize)) fields.push('shadowMapSize');\n if (!Object.is(prev.shadowBias, next.shadowBias)) fields.push('shadowBias');\n return fields;\n }\n case 'ShaderGrid': {\n if (prev._tag !== 'ShaderGrid') return undefined;\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (!vec3Equals(prev.rotation, next.rotation)) fields.push('rotation');\n if (!shaderGridLookEquals(prev, next)) fields.push('grid');\n return fields;\n }\n case 'Grid': {\n if (prev._tag !== 'Grid') return undefined;\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n if (!Object.is(prev.size, next.size)) fields.push('size');\n if (prev.divisions !== next.divisions) fields.push('divisions');\n if (prev.color !== next.color) fields.push('color');\n if (prev.centerColor !== next.centerColor) fields.push('centerColor');\n return fields;\n }\n case 'HemisphereLight': {\n if (prev._tag !== 'HemisphereLight') return undefined;\n if (!Object.is(prev.color, next.color)) fields.push('color');\n if (!Object.is(prev.groundColor, next.groundColor)) fields.push('groundColor');\n if (!Object.is(prev.intensity, next.intensity)) fields.push('intensity');\n if (!vec3Equals(prev.position, next.position)) fields.push('position');\n return fields;\n }\n }\n};\n\n/**\n * Whether a parent's children end up in `keys` order without an `Order`: its previous\n * children still under it, in previous order, then those appended by this diff. Compared\n * in place, as it runs for every parent on every reconcile.\n */\nconst inOrder = (\n previous: ReadonlyArray<string>,\n appended: ReadonlyArray<string>,\n keys: ReadonlyArray<string>,\n stays: (key: string) => boolean,\n): boolean => {\n let at = 0;\n for (const key of previous) {\n if (!stays(key)) continue;\n if (keys[at] !== key) return false;\n at++;\n }\n for (const key of appended) {\n if (keys[at] !== key) return false;\n at++;\n }\n return at === keys.length;\n};\n\nconst noKeys: ReadonlyArray<string> = [];\n\nconst noBehaviours: ReadonlySet<string> = new Set();\n\n/**\n * Diffs a validated previous scene against the next description. `behaviours` are the\n * names registered with the scene; naming any other is invalid.\n */\nexport const diff = (\n prev: SceneIndex,\n next: SceneDescription,\n behaviours: ReadonlySet<string> = noBehaviours,\n): DiffResult => {\n if (prev.description === next) return { _tag: 'Diffed', ops: [], index: prev };\n const indexed = indexScene(next, behaviours);\n if (indexed._tag === 'Invalid') return indexed;\n const index = indexed.index;\n const ops: Array<Op> = [];\n\n const prevDescription = prev.description;\n if (prevDescription === null || !cameraEquals(prevDescription.camera, next.camera)) {\n ops.push({ _tag: 'SetCamera', camera: next.camera });\n }\n if (prevDescription === null || !viewsEqual(prevDescription.views, next.views)) {\n ops.push({ _tag: 'SetViews', views: next.views });\n }\n if (prevDescription === null || !renderSettingsEquals(prevDescription.render, next.render)) {\n ops.push({ _tag: 'SetRenderSettings', settings: next.render });\n }\n if (prevDescription === null || !resourcesEqual(prevDescription.resources, next.resources)) {\n ops.push({ _tag: 'DefineResources', resources: next.resources });\n }\n\n // Keys appended to each parent by this diff (created, or moved in from elsewhere).\n const appended = new Map<ParentKey, Array<string>>();\n const append = (parent: ParentKey, key: string): void => {\n const list = appended.get(parent);\n if (list === undefined) appended.set(parent, [key]);\n else list.push(key);\n };\n // Parents whose hosted object was created by this diff: their children arrive in order.\n const freshParents = new Set<string>();\n // Whether any node changed parent (moved, or replaced under another).\n let reparented = false;\n\n for (const key of index.preOrder) {\n const current = index.nodes.get(key);\n if (current === undefined) continue;\n const before = prev.nodes.get(key);\n if (before === undefined) {\n ops.push({ _tag: 'Create', node: current.node, parent: current.parent });\n append(current.parent, key);\n freshParents.add(key);\n continue;\n }\n const fields = changedFields(before.node, current.node);\n if (fields === undefined) {\n ops.push({ _tag: 'Replace', node: current.node, parent: current.parent });\n if (before.parent !== current.parent) {\n reparented = true;\n append(current.parent, key);\n }\n continue;\n }\n if (before.parent !== current.parent) {\n reparented = true;\n ops.push({ _tag: 'Move', key, parent: current.parent });\n append(current.parent, key);\n }\n if (fields.length > 0) ops.push({ _tag: 'Update', node: current.node, fields });\n }\n\n // With nothing created and as many nodes as before, every previous key is still here.\n let removed = false;\n if (freshParents.size > 0 || index.nodes.size !== prev.nodes.size) {\n for (const key of prev.preOrder) {\n if (index.nodes.has(key)) continue;\n removed = true;\n ops.push({ _tag: 'Remove', key });\n }\n }\n // Nothing moved or removed: every previous child is still under its parent.\n const settled = !reparented && !removed;\n\n // After the steps above each parent holds its surviving children in previous order,\n // followed by appended children in next order. Reorder only where that is wrong.\n for (const [parent, keys] of index.children) {\n if (parent !== null && freshParents.has(parent)) continue;\n const stays = (key: string): boolean => settled || index.nodes.get(key)?.parent === parent;\n const previous = prev.children.get(parent) ?? noKeys;\n if (!inOrder(previous, appended.get(parent) ?? noKeys, keys, stays)) {\n ops.push({ _tag: 'Order', parent, keys });\n }\n }\n\n return { _tag: 'Diffed', ops, index };\n};\n",
|
|
17
|
+
"/**\n * GPU resource ownership (PLAN D5).\n *\n * - Owned: created for one mesh, disposed when that mesh releases it.\n * - Shared: defined by id, created on first use, reference-counted by the meshes using\n * it, disposed when the last user releases it. Several scene graphs may share one store.\n *\n * Definitions are upserts. Changing a live shared material within its kind updates it in\n * place. Changing a live shared geometry, or a shared material's kind, creates a\n * replacement, notifies subscribers (each scene graph swaps it onto its meshes) and\n * disposes the old one.\n *\n * The store is synchronous so the applier stays synchronous. The Effect runtime owns the\n * store's lifetime and calls `dispose` from a scope finalizer.\n *\n * @module\n */\nimport {\n BoxGeometry,\n BufferGeometry,\n CapsuleGeometry,\n CircleGeometry,\n ConeGeometry,\n CylinderGeometry,\n ExtrudeGeometry,\n Material,\n type Object3D,\n type Texture,\n PlaneGeometry,\n RingGeometry,\n ShapeGeometry as ShapeGeometry3,\n SphereGeometry,\n TorusGeometry,\n} from 'three';\nimport type { Font } from 'three/addons/loaders/FontLoader.js';\n\nimport type {\n GeometryRef,\n MaterialRef,\n ResourceDefinitions,\n ShapeGeometry,\n SurfaceMaterial,\n TextGeometry,\n} from './description.ts';\nimport { geometryRefEquals, materialRefEquals } from './equality.ts';\nimport { buildMaterial, type HostMaterial, updateMaterial } from './materials.ts';\nimport { layoutText } from './textLayout.ts';\n\n/** Lifetime counters for one resource type. `live` is `created - disposed`. */\nexport type ResourceCounts = {\n readonly created: number;\n readonly disposed: number;\n readonly live: number;\n};\n\nexport type ResourceStats = {\n readonly geometries: ResourceCounts;\n readonly materials: ResourceCounts;\n /** Acquisitions per live shared resource id. */\n readonly sharedGeometryUsers: ReadonlyMap<string, number>;\n readonly sharedMaterialUsers: ReadonlyMap<string, number>;\n};\n\n/** A loan that changed: an object for `borrowed` nodes, or a texture for materials. */\nexport type Loan = {\n readonly kind: 'object' | 'texture' | 'font' | 'geometry';\n readonly id: string;\n};\n\n/** Raised when a live shared geometry is replaced because its definition changed. */\nexport type GeometryReplaced = {\n readonly previous: BufferGeometry;\n readonly next: BufferGeometry;\n};\n\n/** Raised when a live shared material is replaced because its kind changed. */\nexport type MaterialReplaced = {\n readonly previous: HostMaterial;\n readonly next: HostMaterial;\n};\n\nexport type ResourceStore = {\n readonly define: (definitions: ResourceDefinitions) => void;\n readonly acquireGeometry: (ref: GeometryRef) => BufferGeometry;\n /** Releases one acquisition. `geometry` is the value currently held for `ref`. */\n readonly releaseGeometry: (ref: GeometryRef, geometry: BufferGeometry) => void;\n readonly acquireMaterial: (ref: MaterialRef) => HostMaterial;\n /** Releases one acquisition. `material` is the value currently held for `ref`. */\n readonly releaseMaterial: (ref: MaterialRef, material: HostMaterial) => void;\n /** Subscribes to shared geometry replacement. Returns an unsubscribe function. */\n readonly onGeometryReplaced: (listener: (event: GeometryReplaced) => void) => () => void;\n /**\n * Subscribes to any change to a live shared resource (updated in place or replaced),\n * so scenes using it know to draw again. Returns an unsubscribe function.\n */\n readonly onSharedChanged: (listener: () => void) => () => void;\n /**\n * Lends an application-owned three.js object under `id`, replacing any earlier loan.\n * Scenes show it wherever a `borrowed` node names `id`. The store never disposes it.\n * Returns a function that withdraws this loan (and nothing lent since).\n */\n readonly lend: (id: string, object: Object3D) => () => void;\n /** The object lent under `id`, if any. */\n readonly lent: (id: string) => Object3D | undefined;\n /**\n * Lends an application-owned texture under `id`, for materials' `map`. Materials using\n * it update at once, owned and shared alike. The store never disposes it. Returns a\n * function that withdraws this loan.\n */\n readonly lendTexture: (id: string, texture: Texture) => () => void;\n /** The texture lent under `id`, if any. */\n readonly texture: (id: string) => Texture | undefined;\n /**\n * Lends a typeface font under `id` for text geometries naming it. Text already shown\n * is rebuilt. Returns a function that withdraws the loan.\n */\n readonly lendFont: (id: string, font: Font) => () => void;\n /** The font lent under `id`, if any. */\n readonly font: (id: string) => Font | undefined;\n /**\n * Lends an application-owned geometry under `id`, for meshes whose geometry is\n * `lentGeometry(id)`; they show it at once, and nothing once it is withdrawn. The store\n * never disposes it. Returns a function that withdraws this loan.\n */\n readonly lendGeometry: (id: string, geometry: BufferGeometry) => () => void;\n /** Subscribes to loans and withdrawals of objects and textures. Returns an unsubscribe. */\n readonly onLoanChanged: (listener: (loan: Loan) => void) => () => void;\n /** Subscribes to shared material replacement. Returns an unsubscribe function. */\n readonly onMaterialReplaced: (listener: (event: MaterialReplaced) => void) => () => void;\n /**\n * Applies new parameters to an owned material in place. Returns `false`, changing\n * nothing, when `next` is a different kind: release it and acquire a new one instead.\n */\n readonly updateOwnedMaterial: (material: HostMaterial, next: SurfaceMaterial) => boolean;\n /** The shared id of a live geometry, or `undefined` if it is owned or unknown. */\n readonly sharedGeometryId: (geometry: BufferGeometry) => string | undefined;\n /** The shared id of a live material, or `undefined` if it is owned or unknown. */\n readonly sharedMaterialId: (material: HostMaterial) => string | undefined;\n readonly stats: () => ResourceStats;\n /** Disposes every live resource. Idempotent. */\n readonly dispose: () => void;\n};\n\ntype Shared<A> = { value: A; users: number };\n\ntype Counter = { created: number; disposed: number };\n\nconst counts = (counter: Counter): ResourceCounts => ({\n created: counter.created,\n disposed: counter.disposed,\n live: counter.created - counter.disposed,\n});\n\nconst userCounts = <A>(entries: ReadonlyMap<string, Shared<A>>): ReadonlyMap<string, number> => {\n const result = new Map<string, number>();\n for (const [id, entry] of entries) result.set(id, entry.users);\n return result;\n};\n\n// A swapped-out shared geometry keeps its id in the WeakMap, so check it is still current.\nconst liveId = <A extends object>(\n entries: ReadonlyMap<string, Shared<A>>,\n ids: WeakMap<A, string>,\n value: A,\n): string | undefined => {\n const id = ids.get(value);\n if (id === undefined || entries.get(id)?.value !== value) return undefined;\n return id;\n};\n\n/**\n * Text from its font: flat shapes, or extruded as three's `TextGeometry` extrudes them\n * (its options, from shapes laid out with spacing and alignment).\n */\nconst buildText = (shape: TextGeometry, font: Font | undefined): BufferGeometry => {\n if (font === undefined) return new BufferGeometry();\n const shapes = [...layoutText(font, shape.text, shape)];\n const geometry =\n shape.depth === 0 && shape.bevel === null\n ? new ShapeGeometry3(shapes, shape.curveSegments)\n : new ExtrudeGeometry(shapes, {\n depth: shape.depth,\n curveSegments: shape.curveSegments,\n bevelEnabled: shape.bevel !== null,\n bevelThickness: shape.bevel?.thickness ?? 0,\n bevelSize: shape.bevel?.size ?? 0,\n bevelOffset: shape.bevel?.offset ?? 0,\n bevelSegments: shape.bevel?.segments ?? 1,\n });\n if (shape.center) geometry.center();\n return geometry;\n};\n\n/** Builds the three.js geometry for a shape description. */\nconst buildShape = (\n shape: ShapeGeometry,\n fontOf: (id: string) => Font | undefined,\n): BufferGeometry => {\n switch (shape._tag) {\n case 'Text':\n return buildText(shape, fontOf(shape.font));\n case 'Box':\n return new BoxGeometry(shape.width, shape.height, shape.depth);\n case 'Sphere':\n return new SphereGeometry(shape.radius, shape.widthSegments, shape.heightSegments);\n case 'Plane':\n return new PlaneGeometry(shape.width, shape.height);\n case 'Cylinder':\n return new CylinderGeometry(\n shape.radiusTop,\n shape.radiusBottom,\n shape.height,\n shape.radialSegments,\n );\n case 'Torus':\n return new TorusGeometry(\n shape.radius,\n shape.tube,\n shape.radialSegments,\n shape.tubularSegments,\n );\n case 'Cone':\n return new ConeGeometry(shape.radius, shape.height, shape.radialSegments);\n case 'Capsule':\n return new CapsuleGeometry(\n shape.radius,\n shape.height,\n shape.capSegments,\n shape.radialSegments,\n );\n case 'Ring':\n return new RingGeometry(shape.innerRadius, shape.outerRadius, shape.thetaSegments);\n case 'Circle':\n return new CircleGeometry(shape.radius, shape.segments);\n }\n};\n\n/** Creates an empty resource store. */\n/** What a mesh shows while its lent geometry is not lent: nothing. Shared, never disposed. */\nconst notLent = new BufferGeometry();\n\nexport const createResourceStore = (): ResourceStore => {\n const geometryDefinitions = new Map<string, ShapeGeometry>();\n const materialDefinitions = new Map<string, SurfaceMaterial>();\n const sharedGeometries = new Map<string, Shared<BufferGeometry>>();\n const sharedMaterials = new Map<string, Shared<HostMaterial>>();\n const sharedGeometryIds = new WeakMap<BufferGeometry, string>();\n const sharedMaterialIds = new WeakMap<HostMaterial, string>();\n const owned = new Set<BufferGeometry | HostMaterial>();\n const replacedListeners = new Set<(event: GeometryReplaced) => void>();\n const materialListeners = new Set<(event: MaterialReplaced) => void>();\n const changeListeners = new Set<() => void>();\n const loans = new Map<string, Object3D>();\n const textures = new Map<string, Texture>();\n const textureOf = (id: string): Texture | undefined => textures.get(id);\n const fonts = new Map<string, Font>();\n const fontOf = (id: string): Font | undefined => fonts.get(id);\n const lentGeometries = new Map<string, BufferGeometry>();\n const loanListeners = new Set<(loan: Loan) => void>();\n const loanChanged = (loan: Loan): void => {\n // Shared materials belong to the store: re-apply those that use a changed texture.\n if (loan.kind === 'texture') {\n for (const [id, definition] of materialDefinitions) {\n const live = sharedMaterials.get(id);\n if (live !== undefined && 'map' in definition && definition.map === loan.id) {\n updateMaterial(live.value, definition, textureOf);\n }\n }\n }\n // Shared text is the store's too: rebuild what uses a changed font.\n if (loan.kind === 'font') {\n for (const [id, definition] of geometryDefinitions) {\n if (definition._tag === 'Text' && definition.font === loan.id)\n replaceShared(id, definition);\n }\n }\n for (const listener of loanListeners) listener(loan);\n };\n const notifyChanged = (): void => {\n for (const listener of changeListeners) listener();\n };\n const geometryCounter: Counter = { created: 0, disposed: 0 };\n const materialCounter: Counter = { created: 0, disposed: 0 };\n\n const makeGeometry = (description: ShapeGeometry): BufferGeometry => {\n geometryCounter.created++;\n return buildShape(description, fontOf);\n };\n const disposeGeometry = (geometry: BufferGeometry): void => {\n geometryCounter.disposed++;\n geometry.dispose();\n };\n const makeMaterial = (description: SurfaceMaterial): HostMaterial => {\n materialCounter.created++;\n return buildMaterial(description, textureOf);\n };\n const disposeMaterial = (material: HostMaterial): void => {\n materialCounter.disposed++;\n material.dispose();\n };\n\n /** Rebuilds a live shared geometry and swaps it onto every user. */\n function replaceShared(id: string, definition: ShapeGeometry): void {\n const live = sharedGeometries.get(id);\n if (live === undefined) return;\n const previous = live.value;\n const replacement = makeGeometry(definition);\n sharedGeometryIds.set(replacement, id);\n live.value = replacement;\n for (const listener of replacedListeners) listener({ previous, next: replacement });\n disposeGeometry(previous);\n notifyChanged();\n }\n\n const define = (definitions: ResourceDefinitions): void => {\n for (const { id, geometry } of definitions.geometries) {\n const before = geometryDefinitions.get(id);\n geometryDefinitions.set(id, geometry);\n if (before === undefined || geometryRefEquals(before, geometry)) continue;\n replaceShared(id, geometry);\n }\n for (const { id, material } of definitions.materials) {\n const before = materialDefinitions.get(id);\n materialDefinitions.set(id, material);\n const live = sharedMaterials.get(id);\n if (live === undefined || before === undefined || materialRefEquals(before, material)) {\n continue;\n }\n if (updateMaterial(live.value, material, textureOf)) {\n notifyChanged();\n continue;\n }\n const previous = live.value;\n const replacement = makeMaterial(material);\n sharedMaterialIds.set(replacement, id);\n live.value = replacement;\n for (const listener of materialListeners) listener({ previous, next: replacement });\n disposeMaterial(previous);\n notifyChanged();\n }\n };\n\n const acquireGeometry = (ref: GeometryRef): BufferGeometry => {\n // A lent geometry is the lender's: shown as it is, never counted or disposed.\n if (ref._tag === 'LentGeometry') return lentGeometries.get(ref.id) ?? notLent;\n if (ref._tag !== 'SharedGeometry') {\n const geometry = makeGeometry(ref);\n owned.add(geometry);\n return geometry;\n }\n const live = sharedGeometries.get(ref.id);\n if (live !== undefined) {\n live.users++;\n return live.value;\n }\n const definition = geometryDefinitions.get(ref.id);\n if (definition === undefined)\n throw new Error(`effect-three: undefined shared geometry \"${ref.id}\"`);\n const geometry = makeGeometry(definition);\n sharedGeometries.set(ref.id, { value: geometry, users: 1 });\n sharedGeometryIds.set(geometry, ref.id);\n return geometry;\n };\n\n const releaseGeometry = (ref: GeometryRef, geometry: BufferGeometry): void => {\n if (ref._tag === 'LentGeometry') return;\n if (ref._tag !== 'SharedGeometry') {\n if (owned.delete(geometry)) disposeGeometry(geometry);\n return;\n }\n const live = sharedGeometries.get(ref.id);\n if (live === undefined || live.value !== geometry) return;\n live.users--;\n if (live.users > 0) return;\n sharedGeometries.delete(ref.id);\n disposeGeometry(live.value);\n };\n\n const acquireMaterial = (ref: MaterialRef): HostMaterial => {\n if (ref._tag !== 'SharedMaterial') {\n const material = makeMaterial(ref);\n owned.add(material);\n return material;\n }\n const live = sharedMaterials.get(ref.id);\n if (live !== undefined) {\n live.users++;\n return live.value;\n }\n const definition = materialDefinitions.get(ref.id);\n if (definition === undefined)\n throw new Error(`effect-three: undefined shared material \"${ref.id}\"`);\n const material = makeMaterial(definition);\n sharedMaterials.set(ref.id, { value: material, users: 1 });\n sharedMaterialIds.set(material, ref.id);\n return material;\n };\n\n const releaseMaterial = (ref: MaterialRef, material: HostMaterial): void => {\n if (ref._tag !== 'SharedMaterial') {\n if (owned.delete(material)) disposeMaterial(material);\n return;\n }\n const live = sharedMaterials.get(ref.id);\n if (live === undefined || live.value !== material) return;\n live.users--;\n if (live.users > 0) return;\n sharedMaterials.delete(ref.id);\n disposeMaterial(live.value);\n };\n\n const dispose = (): void => {\n for (const resource of owned) {\n if (resource instanceof Material) disposeMaterial(resource);\n else disposeGeometry(resource);\n }\n owned.clear();\n for (const entry of sharedGeometries.values()) disposeGeometry(entry.value);\n sharedGeometries.clear();\n for (const entry of sharedMaterials.values()) disposeMaterial(entry.value);\n sharedMaterials.clear();\n };\n\n return {\n define,\n acquireGeometry,\n releaseGeometry,\n acquireMaterial,\n releaseMaterial,\n updateOwnedMaterial: (material, next) => updateMaterial(material, next, textureOf),\n onGeometryReplaced: (listener) => {\n replacedListeners.add(listener);\n return () => {\n replacedListeners.delete(listener);\n };\n },\n lend: (id, object) => {\n loans.set(id, object);\n loanChanged({ kind: 'object', id });\n return () => {\n if (loans.get(id) !== object) return;\n loans.delete(id);\n loanChanged({ kind: 'object', id });\n };\n },\n lent: (id) => loans.get(id),\n lendTexture: (id, texture) => {\n textures.set(id, texture);\n loanChanged({ kind: 'texture', id });\n return () => {\n if (textures.get(id) !== texture) return;\n textures.delete(id);\n loanChanged({ kind: 'texture', id });\n };\n },\n texture: textureOf,\n lendFont: (id, font) => {\n fonts.set(id, font);\n loanChanged({ kind: 'font', id });\n return () => {\n if (fonts.get(id) !== font) return;\n fonts.delete(id);\n loanChanged({ kind: 'font', id });\n };\n },\n font: fontOf,\n lendGeometry: (id, geometry) => {\n lentGeometries.set(id, geometry);\n loanChanged({ kind: 'geometry', id });\n return () => {\n if (lentGeometries.get(id) !== geometry) return;\n lentGeometries.delete(id);\n loanChanged({ kind: 'geometry', id });\n };\n },\n onLoanChanged: (listener) => {\n loanListeners.add(listener);\n return () => {\n loanListeners.delete(listener);\n };\n },\n onSharedChanged: (listener) => {\n changeListeners.add(listener);\n return () => {\n changeListeners.delete(listener);\n };\n },\n onMaterialReplaced: (listener) => {\n materialListeners.add(listener);\n return () => {\n materialListeners.delete(listener);\n };\n },\n sharedGeometryId: (geometry) => liveId(sharedGeometries, sharedGeometryIds, geometry),\n sharedMaterialId: (material) => liveId(sharedMaterials, sharedMaterialIds, material),\n stats: () => ({\n geometries: counts(geometryCounter),\n materials: counts(materialCounter),\n sharedGeometryUsers: userCounts(sharedGeometries),\n sharedMaterialUsers: userCounts(sharedMaterials),\n }),\n dispose,\n };\n};\n",
|
|
18
|
+
"/**\n * Lays out text from a typeface font as shapes, with letter spacing, line height and\n * alignment.\n *\n * Behavioural reference: three.js `FontLoader.js` `createPaths` at 0.186.1 (each glyph\n * advanced by its `ha`, a new line down by the font's bounding box height plus its\n * underline thickness, a missing glyph drawn as `?`). Drei's `Text3D` (`bf6f4ad`) takes\n * `letterSpacing` and `lineHeight` and hands them to `TextGeometry`, which ignores them;\n * here they are applied, in the units troika's `Text` uses: letter spacing in ems, line\n * height as a multiple of the font's own. At the defaults the shapes are three's.\n *\n * @module\n */\nimport { Vector2, type Path, type Shape } from 'three';\nimport type { Font } from 'three/addons/loaders/FontLoader.js';\n\nimport type { TextAlign } from './description.ts';\n\n/** How to lay the text out. */\nexport type TextLayout = {\n readonly size: number;\n /** Extra space after each glyph, in ems (multiples of `size`). */\n readonly letterSpacing: number;\n /** Line spacing as a multiple of the font's. */\n readonly lineHeight: number;\n /** Where each line sits within the widest. */\n readonly align: TextAlign;\n};\n\ntype Glyph = { readonly ha: number };\n\nconst corners = ['v0', 'v1', 'v2', 'v3'] as const;\n\n/** Moves every point of a path's curves by `(dx, dy)`. */\nconst shiftPath = (path: Path, dx: number, dy: number): void => {\n for (const curve of path.curves) {\n for (const corner of corners) {\n const point: unknown = Reflect.get(curve, corner);\n if (point instanceof Vector2) point.set(point.x + dx, point.y + dy);\n }\n }\n};\n\n/** Moves a shape and its holes. */\nconst shiftShape = (shape: Shape, dx: number, dy: number): Shape => {\n shiftPath(shape, dx, dy);\n for (const hole of shape.holes) shiftPath(hole, dx, dy);\n return shape;\n};\n\n/** A glyph, or `?` for one the font lacks; neither, and the character is skipped. */\nconst glyphOf = (font: Font, char: string): Glyph | undefined => {\n const glyphs: Readonly<Record<string, Glyph | undefined>> = font.data.glyphs;\n return glyphs[char] ?? glyphs['?'];\n};\n\ntype Line = {\n readonly chars: ReadonlyArray<string>;\n readonly starts: ReadonlyArray<number>;\n readonly width: number;\n};\n\n/** A line's drawable glyphs, where each starts, and its width (without trailing spacing). */\nconst lineOf = (font: Font, line: string, scale: number, spacing: number): Line => {\n const chars: Array<string> = [];\n const starts: Array<number> = [];\n let x = 0;\n for (const char of Array.from(line)) {\n const glyph = glyphOf(font, char);\n if (glyph === undefined) continue;\n chars.push(char);\n starts.push(x);\n x += glyph.ha * scale + spacing;\n }\n return { chars, starts, width: chars.length === 0 ? 0 : x - spacing };\n};\n\nconst alignShift = { left: () => 0, center: (gap: number) => gap / 2, right: (gap: number) => gap };\n\n/** The shapes of `text` laid out by `layout`, the first line's baseline at y = 0. */\nexport const layoutText = (font: Font, text: string, layout: TextLayout): ReadonlyArray<Shape> => {\n const { data } = font;\n const scale = layout.size / data.resolution;\n const lineStep =\n (data.boundingBox.yMax - data.boundingBox.yMin + data.underlineThickness) *\n scale *\n layout.lineHeight;\n const spacing = layout.letterSpacing * layout.size;\n const lines = text.split('\\n').map((line) => lineOf(font, line, scale, spacing));\n const widest = Math.max(0, ...lines.map((line) => line.width));\n const shapes: Array<Shape> = [];\n lines.forEach((line, row) => {\n const indent = alignShift[layout.align](widest - line.width);\n line.chars.forEach((char, i) => {\n const x = indent + (line.starts[i] ?? 0);\n for (const shape of font.generateShapes(char, layout.size)) {\n shapes.push(shiftShape(shape, x, -row * lineStep));\n }\n });\n });\n return shapes;\n};\n",
|
|
19
|
+
"/**\n * Scene time. Behaviours read elapsed seconds from here; pausing animation (for example\n * under `prefers-reduced-motion`) freezes scene time while frames keep rendering, and\n * resuming continues from the frozen value rather than jumping ahead.\n *\n * @module\n */\n\nexport type SceneClock = {\n /** Scene seconds elapsed while animating. */\n readonly elapsedSeconds: () => number;\n /** Freezes (`false`) or resumes (`true`) scene time. Idempotent. */\n readonly setAnimating: (animating: boolean) => void;\n readonly animating: () => boolean;\n};\n\n/** Creates a scene clock over a monotonic source of seconds. */\nexport const createSceneClock = (nowSeconds: () => number): SceneClock => {\n const start = nowSeconds();\n let frozenAt: number | undefined;\n let paused = 0;\n const elapsedSeconds = (): number => (frozenAt ?? nowSeconds()) - start - paused;\n return {\n elapsedSeconds,\n setAnimating: (animating) => {\n if (animating && frozenAt !== undefined) {\n paused += nowSeconds() - frozenAt;\n frozenAt = undefined;\n } else if (!animating && frozenAt === undefined) {\n frozenAt = nowSeconds();\n }\n },\n animating: () => frozenAt === undefined,\n };\n};\n",
|
|
20
|
+
"/**\n * Frame scheduling contracts. A scheduler calls registered callbacks once per frame:\n * `requestAnimationFrame` in a browser, three's `setAnimationLoop` for WebGPU and XR, or\n * a manual scheduler in tests.\n *\n * @module\n */\n\n/** Registers a per-frame callback and returns a function that unregisters it. */\nexport type FrameScheduler = {\n readonly subscribe: (onFrame: () => void) => () => void;\n};\n\n/** A scheduler driven by hand. `step` runs one frame for every subscriber. */\nexport type ManualFrames = FrameScheduler & {\n readonly step: () => void;\n readonly subscribers: () => number;\n};\n\n/** Creates a manual frame scheduler for deterministic tests. */\nexport const createManualFrames = (): ManualFrames => {\n const callbacks = new Set<() => void>();\n return {\n subscribe: (onFrame) => {\n callbacks.add(onFrame);\n return () => {\n callbacks.delete(onFrame);\n };\n },\n step: () => {\n // Snapshot: callbacks subscribed during this frame first run on the next one.\n for (const onFrame of Array.from(callbacks)) onFrame();\n },\n subscribers: () => callbacks.size,\n };\n};\n\n/** A scheduler that forwards frames only while open. */\nexport type GatedFrames = FrameScheduler & {\n readonly setOpen: (open: boolean) => void;\n};\n\n/**\n * Wraps `base` so frames pass only while open: for example, only while the canvas is on\n * screen, or only while a scene has something to draw. A closed gate unsubscribes from\n * `base`, so a scheduler that stops when nobody listens (such as the browser's animation\n * frames) really stops.\n */\nexport const createGatedFrames = (base: FrameScheduler): GatedFrames => {\n let open = true;\n const callbacks = new Set<() => void>();\n let unsubscribe: (() => void) | undefined;\n const forward = (): void => {\n // Snapshot: a callback may close the gate or unsubscribe while running.\n for (const onFrame of Array.from(callbacks)) onFrame();\n };\n const sync = (): void => {\n const wanted = open && callbacks.size > 0;\n if (wanted && unsubscribe === undefined) unsubscribe = base.subscribe(forward);\n else if (!wanted && unsubscribe !== undefined) {\n unsubscribe();\n unsubscribe = undefined;\n }\n };\n return {\n subscribe: (onFrame) => {\n callbacks.add(onFrame);\n sync();\n return () => {\n callbacks.delete(onFrame);\n sync();\n };\n },\n setOpen: (next) => {\n open = next;\n sync();\n },\n };\n};\n\n/** Turns a scene's frames on and off. Off unsubscribes, so an idle scheduler can stop. */\nexport type FrameControl = {\n readonly wake: () => void;\n readonly sleep: () => void;\n};\n\n/** The part of a scene loop that pacing needs. */\nexport type Paced = {\n readonly frame: () => void;\n readonly wantsFrames: () => boolean;\n};\n\nexport type FramePacer = {\n /** The per-frame callback: draws, then sleeps when no further frame is wanted. */\n readonly frame: () => void;\n /** Connects the subscription's control, putting it to sleep if nothing is wanted yet. */\n readonly attach: (control: FrameControl) => void;\n /** Wakes the subscription if a frame is now wanted. Call on every invalidation. */\n readonly wake: () => void;\n /** Draws one frame now, whatever the mode: React Three Fiber's `advance`. */\n readonly advance: () => void;\n};\n\n/**\n * Paces a scene's frames: subscribed while frames are wanted, asleep otherwise, so an\n * idle scene costs no frames at all.\n */\nexport const createFramePacer = (loop: Paced): FramePacer => {\n let control: FrameControl | undefined;\n return {\n frame: () => {\n loop.frame();\n if (!loop.wantsFrames()) control?.sleep();\n },\n attach: (next) => {\n control = next;\n if (!loop.wantsFrames()) next.sleep();\n },\n wake: () => {\n if (loop.wantsFrames()) control?.wake();\n },\n advance: loop.frame,\n };\n};\n",
|
|
21
|
+
"/**\n * Orbit controls as data: pure functions from a camera and a gesture to the next camera.\n * The camera stays in the application's Model; a `Gesture` Message carries the input and\n * `orbit` applies it, so time travel, undo and persistence see every camera move.\n *\n * Behavioural reference: three.js `examples/jsm/controls/OrbitControls.js` at 0.186.1,\n * the class Drei's `OrbitControls` wraps (`drei-main/src/core/OrbitControls.tsx` at\n * `bf6f4ad`). As there:\n *\n * - The camera circles its `lookAt` point (the target) with world up `+y`.\n * - Left drag rotates (with shift, control or meta: pans), middle drag dollies, right\n * drag pans (with a modifier: rotates). One finger rotates; two pinch and pan.\n * - A full drag across the height of the area turns the camera once round (`rotateSpeed`\n * 1). Wheel and dolly steps scale the distance by `0.95 ^ (zoomSpeed * |delta| / 100)`;\n * orthographic cameras change `zoom` instead.\n * - Panning moves target and camera together, by the distance under the pointer.\n * - Polar and azimuth limits, distance and zoom limits are applied after every step.\n *\n * Unlike three's controls these hold no state between calls; smoothing is the camera's\n * own `damping`, which the scene applies to the rendered camera.\n *\n * @module\n */\nimport {\n MathUtils,\n Matrix4,\n OrthographicCamera,\n PerspectiveCamera,\n Plane,\n Ray,\n Spherical,\n Vector3,\n} from 'three';\n\nimport type { Camera, Vec3 } from './description.ts';\nimport type { Gesture, Modifiers } from './pointer.ts';\n\n/** How `orbit` reads gestures: speeds and limits, as three.js's `OrbitControls`. */\nexport type OrbitOptions = {\n readonly enableRotate: boolean;\n readonly enableZoom: boolean;\n readonly enablePan: boolean;\n readonly rotateSpeed: number;\n readonly zoomSpeed: number;\n readonly panSpeed: number;\n /** Pan in the screen's plane (`true`, the default) or along the ground (`false`). */\n readonly screenSpacePanning: boolean;\n /** Perspective cameras: the closest and furthest distance from the target. */\n readonly minDistance: number;\n readonly maxDistance: number;\n /** Orthographic cameras: the smallest and largest `zoom`. */\n readonly minZoom: number;\n readonly maxZoom: number;\n /** Radians from straight above (0) to straight below (π). */\n readonly minPolarAngle: number;\n readonly maxPolarAngle: number;\n /** Radians around the vertical axis; infinite (the default) for no limit. */\n readonly minAzimuthAngle: number;\n readonly maxAzimuthAngle: number;\n /** Dolly toward the point under the pointer rather than the target (`zoomToCursor`). */\n readonly zoomToCursor: boolean;\n /** Pixels an arrow key pans by, and turns an arrow key with a modifier makes. */\n readonly keyPanSpeed: number;\n readonly keyRotateSpeed: number;\n};\n\n/** three.js's `OrbitControls` defaults. */\nexport const defaultOrbit: OrbitOptions = {\n enableRotate: true,\n enableZoom: true,\n enablePan: true,\n rotateSpeed: 1,\n zoomSpeed: 1,\n panSpeed: 1,\n screenSpacePanning: true,\n minDistance: 0,\n maxDistance: Infinity,\n minZoom: 0,\n maxZoom: Infinity,\n minPolarAngle: 0,\n maxPolarAngle: Math.PI,\n minAzimuthAngle: -Infinity,\n maxAzimuthAngle: Infinity,\n zoomToCursor: false,\n keyPanSpeed: 7,\n keyRotateSpeed: 1,\n};\n\n/** Orbit options: three.js's defaults with yours on top. */\nexport const orbitOptions = (options: Partial<OrbitOptions> = {}): OrbitOptions => ({\n ...defaultOrbit,\n ...options,\n});\n\nconst twoPi = 2 * Math.PI;\n\n// Scratch values, so a step allocates only the camera it returns.\nconst offset = new Vector3();\nconst spherical = new Spherical();\nconst target = new Vector3();\nconst position = new Vector3();\nconst axis = new Vector3();\nconst panOffset = new Vector3();\nconst basis = new Matrix4();\nconst worldUp = new Vector3(0, 1, 0);\n\nconst toVec3 = (vector: Vector3): Vec3 => [vector.x, vector.y, vector.z];\n\n/** Clamps an azimuth to limits that may wrap past ±π (OrbitControls' `update`). */\nconst clampAzimuth = (theta: number, options: OrbitOptions): number => {\n let min = options.minAzimuthAngle;\n let max = options.maxAzimuthAngle;\n if (!Number.isFinite(min) || !Number.isFinite(max)) return theta;\n if (min < -Math.PI) min += twoPi;\n else if (min > Math.PI) min -= twoPi;\n if (max < -Math.PI) max += twoPi;\n else if (max > Math.PI) max -= twoPi;\n if (min <= max) return Math.max(min, Math.min(max, theta));\n return theta > (min + max) / 2 ? Math.max(min, theta) : Math.min(max, theta);\n};\n\nconst clampDistance = (distance: number, options: OrbitOptions): number =>\n Math.max(options.minDistance, Math.min(options.maxDistance, distance));\n\n/** Brings `spherical` within the limits, as every OrbitControls `update` does. */\nconst limit = (options: OrbitOptions): void => {\n spherical.theta = clampAzimuth(spherical.theta, options);\n spherical.phi = Math.max(options.minPolarAngle, Math.min(options.maxPolarAngle, spherical.phi));\n spherical.makeSafe();\n spherical.radius = clampDistance(spherical.radius, options);\n};\n\n/**\n * Reads the camera's offset from its target into `spherical`, within the limits: a\n * camera outside them starts from where the controls would first put it.\n */\nconst readSpherical = (camera: Camera, options: OrbitOptions): void => {\n target.fromArray(camera.lookAt);\n offset.fromArray(camera.position).sub(target);\n spherical.setFromVector3(offset);\n limit(options);\n};\n\n/** The camera placed at `spherical` around `target`, within the limits, with `zoom`. */\nconst place = (camera: Camera, options: OrbitOptions, zoom: number): Camera => {\n limit(options);\n position.setFromSpherical(spherical).add(target);\n const lookAt = toVec3(target);\n return camera._tag === 'Perspective'\n ? { ...camera, position: toVec3(position), lookAt }\n : {\n ...camera,\n position: toVec3(position),\n lookAt,\n zoom: clampZoom(zoom, options),\n };\n};\n\nconst clampZoom = (zoom: number, options: OrbitOptions): number =>\n Math.max(options.minZoom, Math.min(options.maxZoom, zoom));\n\n/** An orthographic camera's zoom within the limits; 1 for a perspective camera. */\nconst zoomOf = (camera: Camera, options: OrbitOptions): number =>\n camera._tag === 'Orthographic' ? clampZoom(camera.zoom, options) : 1;\n\n/**\n * Turns the camera round its target by a drag of `deltaX`, `deltaY` CSS pixels over an\n * area `height` pixels tall: a drag the full height turns it once round.\n */\nexport const rotateCamera = (\n camera: Camera,\n deltaX: number,\n deltaY: number,\n height: number,\n options: OrbitOptions = defaultOrbit,\n): Camera => {\n readSpherical(camera, options);\n const scale = (twoPi * options.rotateSpeed) / Math.max(1, height);\n spherical.theta -= deltaX * scale;\n spherical.phi -= deltaY * scale;\n return place(camera, options, zoomOf(camera, options));\n};\n\n/**\n * Scales the camera's distance from its target by `scale` (below 1 moves closer). An\n * orthographic camera keeps its distance and divides its `zoom` by `scale` instead.\n */\nexport const dollyCamera = (\n camera: Camera,\n scale: number,\n options: OrbitOptions = defaultOrbit,\n): Camera => {\n readSpherical(camera, options);\n if (camera._tag === 'Perspective') spherical.radius *= scale;\n return place(camera, options, zoomOf(camera, options) / scale);\n};\n\n/**\n * Moves the camera and its target together by a drag of `deltaX`, `deltaY` CSS pixels\n * over an area `width` by `height`: the scene follows the pointer at the target's depth.\n */\nexport const panCamera = (\n camera: Camera,\n deltaX: number,\n deltaY: number,\n area: { readonly width: number; readonly height: number },\n options: OrbitOptions = defaultOrbit,\n): Camera => {\n readSpherical(camera, options);\n position.setFromSpherical(spherical).add(target);\n basis.lookAt(position, target, worldUp);\n const dx = deltaX * options.panSpeed;\n const dy = deltaY * options.panSpeed;\n // World units per CSS pixel at the target's depth.\n const left =\n camera._tag === 'Perspective'\n ? (2 * dx * spherical.radius * Math.tan((camera.fov / 2) * (Math.PI / 180))) /\n Math.max(1, area.height)\n : dx / zoomOf(camera, options);\n const up =\n camera._tag === 'Perspective'\n ? (2 * dy * spherical.radius * Math.tan((camera.fov / 2) * (Math.PI / 180))) /\n Math.max(1, area.height)\n : dy / zoomOf(camera, options);\n panOffset.setFromMatrixColumn(basis, 0).multiplyScalar(-left);\n if (options.screenSpacePanning) {\n axis.setFromMatrixColumn(basis, 1);\n } else {\n axis.setFromMatrixColumn(basis, 0);\n axis.crossVectors(worldUp, axis);\n }\n panOffset.addScaledVector(axis, up);\n target.add(panOffset);\n return place(camera, options, zoomOf(camera, options));\n};\n\n/** Where on a gesture's area the pointer is: its size, and `x`, `y` from −1 to 1, y up. */\nexport type Cursor = {\n readonly width: number;\n readonly height: number;\n readonly x: number;\n readonly y: number;\n};\n\n/** OrbitControls' `_TILT_LIMIT`: steeper than 70° from up, a ground target is not moved. */\nconst tiltLimit = Math.cos(70 * MathUtils.DEG2RAD);\n\nconst pointer = new Vector3();\nconst before = new Vector3();\nconst forward = new Vector3();\nconst groundRay = new Ray();\nconst ground = new Plane();\n\n/** A three.js camera placed as `spherical` around `target` puts it, fitted to `cursor`'s area. */\nconst hostCamera = (camera: Camera, cursor: Cursor, zoom: number) => {\n const host =\n camera._tag === 'Perspective'\n ? new PerspectiveCamera(\n camera.fov,\n cursor.width / Math.max(1, cursor.height),\n camera.near,\n camera.far,\n )\n : new OrthographicCamera(\n cursor.width / -2,\n cursor.width / 2,\n cursor.height / 2,\n cursor.height / -2,\n camera.near,\n camera.far,\n );\n if (host instanceof OrthographicCamera) host.zoom = zoom;\n host.updateProjectionMatrix();\n host.position.setFromSpherical(spherical).add(target);\n host.lookAt(target);\n host.updateMatrixWorld();\n return host;\n};\n\n/**\n * Dollies toward the point under the cursor by `scale` (below 1 moves closer), as\n * OrbitControls does with `zoomToCursor`: a perspective camera moves along the pointer's\n * ray; an orthographic one zooms and shifts so the point under the cursor stays there.\n * The target then follows, `radius` ahead along the view (or on the ground, when panning\n * along it and the view is not too steep). A middle-button drag aims where it was\n * pressed: three 0.186's `_handleMouseDownDolly` passes `clientX` for both coordinates, a\n * typo this does not copy.\n */\nexport const dollyCameraToward = (\n camera: Camera,\n scale: number,\n cursor: Cursor,\n options: OrbitOptions = defaultOrbit,\n): Camera => {\n readSpherical(camera, options);\n const host = hostCamera(camera, cursor, zoomOf(camera, options));\n let radius = spherical.radius;\n if (host instanceof PerspectiveCamera) {\n pointer.set(cursor.x, cursor.y, 1).unproject(host).sub(host.position).normalize();\n const next = clampDistance(radius * scale, options);\n host.position.addScaledVector(pointer, radius - next);\n radius = next;\n } else {\n before.set(cursor.x, cursor.y, 0).unproject(host);\n host.zoom = clampZoom(host.zoom / scale, options);\n host.updateProjectionMatrix();\n pointer.set(cursor.x, cursor.y, 0).unproject(host);\n host.position.sub(pointer).add(before);\n }\n host.updateMatrixWorld();\n forward.set(0, 0, -1).transformDirection(host.matrix);\n if (options.screenSpacePanning) {\n target.copy(forward).multiplyScalar(radius).add(host.position);\n } else if (Math.abs(worldUp.dot(forward)) >= tiltLimit) {\n groundRay.set(host.position, forward);\n ground.setFromNormalAndCoplanarPoint(worldUp, target);\n groundRay.intersectPlane(ground, target);\n }\n const lookAt = toVec3(target);\n const placed = toVec3(host.position);\n return camera._tag === 'Perspective'\n ? { ...camera, position: placed, lookAt }\n : { ...camera, position: placed, lookAt, zoom: host.zoom };\n};\n\n/** `0.95 ^ (zoomSpeed * |delta| / 100)`: OrbitControls' `_getZoomScale`. */\nconst zoomScale = (delta: number, options: OrbitOptions): number =>\n 0.95 ** (options.zoomSpeed * Math.abs(delta * 0.01));\n\n/** Dollies by `scale`, toward the cursor when the options ask for it. */\nconst dollyAt = (camera: Camera, scale: number, cursor: Cursor, options: OrbitOptions): Camera =>\n options.zoomToCursor\n ? dollyCameraToward(camera, scale, cursor, options)\n : dollyCamera(camera, scale, options);\n\n/** A dolly by a wheel or vertical drag of `delta` pixels: up or forward moves closer. */\nconst dollyBy = (camera: Camera, delta: number, cursor: Cursor, options: OrbitOptions): Camera => {\n if (delta === 0 || !options.enableZoom) return camera;\n const scale = zoomScale(delta, options);\n return dollyAt(camera, delta < 0 ? scale : 1 / scale, cursor, options);\n};\n\nconst modified = (modifiers: Modifiers): boolean =>\n modifiers.shift || modifiers.control || modifiers.meta;\n\ntype DragGesture = Extract<Gesture, { readonly _tag: 'Drag' }>;\n\nconst rotateBy = (camera: Camera, gesture: DragGesture, options: OrbitOptions): Camera =>\n options.enableRotate\n ? rotateCamera(camera, gesture.deltaX, gesture.deltaY, gesture.height, options)\n : camera;\n\nconst panBy = (\n camera: Camera,\n gesture: Extract<Gesture, { readonly deltaX: number }>,\n options: OrbitOptions,\n): Camera =>\n options.enablePan ? panCamera(camera, gesture.deltaX, gesture.deltaY, gesture, options) : camera;\n\n/** A drag by button: left rotates, middle dollies, right pans; a modifier swaps the two. */\nconst drag = (camera: Camera, gesture: DragGesture, options: OrbitOptions): Camera => {\n switch (gesture.button) {\n case 0:\n return modified(gesture.modifiers)\n ? panBy(camera, gesture, options)\n : rotateBy(camera, gesture, options);\n case 1:\n return dollyBy(camera, gesture.deltaY, gesture, options);\n case 2:\n return modified(gesture.modifiers)\n ? rotateBy(camera, gesture, options)\n : panBy(camera, gesture, options);\n default:\n return camera;\n }\n};\n\n/**\n * The camera after one gesture, as three.js's `OrbitControls` would move it. Apply it in\n * `update` and keep the result in the Model:\n *\n * ```ts\n * GotGesture: ({ gesture }) => ({ model: { ...model, camera: orbit(model.camera, gesture) } })\n * ```\n *\n * A wheel with control held (how trackpads report a pinch) dollies ten times as far.\n */\nexport const orbit = (\n camera: Camera,\n gesture: Gesture,\n options: OrbitOptions = defaultOrbit,\n): Camera => {\n switch (gesture._tag) {\n case 'Drag':\n return drag(camera, gesture, options);\n case 'Wheel':\n return dollyBy(\n camera,\n gesture.modifiers.control ? gesture.deltaY * 10 : gesture.deltaY,\n gesture,\n options,\n );\n case 'Pinch': {\n const dollied =\n options.enableZoom && gesture.scale > 0\n ? dollyAt(camera, 1 / gesture.scale ** options.zoomSpeed, gesture, options)\n : camera;\n return panBy(dollied, gesture, options);\n }\n }\n};\n\n/** The arrow keys OrbitControls listens to (`keys`). */\nexport type OrbitKey = 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight';\n\n/**\n * The camera after an arrow key, as OrbitControls' `_handleKeyDown`: up, down, left and\n * right pan by `keyPanSpeed` pixels, or with shift, control or meta held turn by\n * `keyRotateSpeed`. Map key presses to Messages (a Foldkit key subscription) and apply it.\n */\nexport const orbitKey = (\n camera: Camera,\n key: OrbitKey,\n modifiers: Modifiers,\n area: { readonly width: number; readonly height: number },\n options: OrbitOptions = defaultOrbit,\n): Camera => {\n const turn = (twoPi * options.keyRotateSpeed) / Math.max(1, area.height);\n const step = options.keyPanSpeed;\n const rotating = modified(modifiers);\n if (rotating && !options.enableRotate) return camera;\n if (!rotating && !options.enablePan) return camera;\n // A turn here is in radians; rotateCamera takes pixels over the area's height.\n const turned = (left: number, up: number): Camera => {\n readSpherical(camera, options);\n spherical.theta -= left;\n spherical.phi -= up;\n return place(camera, options, zoomOf(camera, options));\n };\n switch (key) {\n case 'ArrowUp':\n return rotating ? turned(0, turn) : panCamera(camera, 0, step, area, options);\n case 'ArrowDown':\n return rotating ? turned(0, -turn) : panCamera(camera, 0, -step, area, options);\n case 'ArrowLeft':\n return rotating ? turned(turn, 0) : panCamera(camera, step, 0, area, options);\n case 'ArrowRight':\n return rotating ? turned(-turn, 0) : panCamera(camera, -step, 0, area, options);\n }\n};\n\n/** A world-space box, as `Measured` events report a node's. */\nexport type Box = { readonly min: Vec3; readonly max: Vec3 };\n\nconst corner = new Vector3();\nconst view = new Matrix4();\n\n/**\n * How far from a box's centre a camera must be to fit it, as Drei's `Bounds`\n * (`src/core/Bounds.tsx` at `bf6f4ad`, `getSize`): the larger of the distances that fit\n * its largest side vertically and horizontally, times `margin`.\n */\nconst fitDistance = (\n camera: Camera,\n box: Box,\n area: { readonly width: number; readonly height: number },\n margin: number,\n): number => {\n const largest = Math.max(\n box.max[0] - box.min[0],\n box.max[1] - box.min[1],\n box.max[2] - box.min[2],\n );\n if (camera._tag === 'Orthographic') return margin * largest * 4;\n const height = largest / (2 * Math.atan((Math.PI * camera.fov) / 360));\n const width = height / (area.width / Math.max(1, area.height));\n return margin * Math.max(height, width);\n};\n\nconst centreOf = (box: Box): Vec3 => [\n (box.min[0] + box.max[0]) / 2,\n (box.min[1] + box.max[1]) / 2,\n (box.min[2] + box.max[2]) / 2,\n];\n\n/**\n * The camera where turning by itself (`autoRotate`) took it, from an `AutoRotated`\n * event: keep it in the Model before orbiting, so the gesture goes on from where the\n * camera was shown.\n *\n * ```ts\n * AutoRotated: ({ position }) => ({ model: { ...model, camera: autoRotated(model.camera, { position }) } })\n * ```\n */\nexport const autoRotated = <C extends Camera>(\n camera: C,\n turned: { readonly position: Vec3 },\n): C => ({ ...camera, position: turned.position });\n\n/**\n * The camera framing a box, as Drei's `Bounds` `fit` (margin 1.2 by default). A\n * perspective camera keeps its direction and moves to the distance that fits the box,\n * looking at its centre; an orthographic one keeps its place and zooms so the box's\n * corners, seen from it, fit the area. Set the camera's `damping` to ease there.\n */\nexport const fitCamera = (\n camera: Camera,\n box: Box,\n area: { readonly width: number; readonly height: number },\n margin = 1.2,\n): Camera => {\n const centre = centreOf(box);\n if (camera._tag === 'Orthographic') {\n position.fromArray(camera.position);\n target.fromArray(camera.lookAt);\n view.lookAt(position, target, worldUp).setPosition(position).invert();\n let halfWidth = 0;\n let halfHeight = 0;\n for (const x of [box.min[0], box.max[0]])\n for (const y of [box.min[1], box.max[1]])\n for (const z of [box.min[2], box.max[2]]) {\n corner.set(x, y, z).applyMatrix4(view);\n halfWidth = Math.max(halfWidth, Math.abs(corner.x));\n halfHeight = Math.max(halfHeight, Math.abs(corner.y));\n }\n const zoom =\n Math.min(\n area.height / Math.max(1e-9, 2 * halfHeight),\n area.width / Math.max(1e-9, 2 * halfWidth),\n ) / margin;\n return { ...camera, zoom };\n }\n position.fromArray(camera.position);\n target.fromArray(centre);\n forward.copy(position).sub(target);\n if (forward.lengthSq() === 0) forward.set(0, 0, 1);\n forward.normalize();\n position.copy(target).addScaledVector(forward, fitDistance(camera, box, area, margin));\n return { ...camera, position: toVec3(position), lookAt: centre };\n};\n\n/**\n * Near and far planes that suit a box at its fitting distance, as Drei's `Bounds` `clip`:\n * a hundredth of it and a hundred times it.\n */\nexport const clipCamera = (\n camera: Camera,\n box: Box,\n area: { readonly width: number; readonly height: number },\n margin = 1.2,\n): Camera => {\n const distance = fitDistance(camera, box, area, margin);\n return { ...camera, near: distance / 100, far: distance * 100 };\n};\n",
|
|
22
|
+
"/**\n * Where each overlay's point is on the canvas, worked out for every frame the scene draws.\n *\n * Behavioural reference: Drei `src/web/Html.tsx` at `bf6f4ad`, without `transform`:\n * `defaultCalculatePosition` (project to CSS pixels), `isObjectBehindCamera`,\n * `isObjectVisible` (raycast occlusion against the scene), `objectScale` with\n * `distanceFactor`, and `objectZIndex` over `zIndexRange`.\n *\n * @module\n */\nimport {\n type Camera,\n type Object3D,\n OrthographicCamera,\n PerspectiveCamera,\n Raycaster,\n Vector2,\n Vector3,\n} from 'three';\n\nimport type { Overlay } from './description.ts';\nimport type { HostedView, SceneGraph } from './sceneGraph.ts';\n\n/** Where to show one overlay's HTML, in CSS pixels from the canvas's top left. */\nexport type OverlayPlacement = {\n readonly key: string;\n readonly x: number;\n readonly y: number;\n /** 1, or the distance scale when the overlay has a `distanceFactor`. */\n readonly scale: number;\n readonly zIndex: number;\n /** False behind the camera, or behind a mesh when the overlay occludes. */\n readonly visible: boolean;\n readonly center: boolean;\n};\n\nconst point = new Vector3();\nconst cameraPosition = new Vector3();\nconst direction = new Vector3();\nconst toPoint = new Vector3();\nconst ndc = new Vector2();\nconst raycaster = new Raycaster();\n\n/** The camera and area an overlay is shown through. */\ntype Lens = {\n readonly camera: Camera;\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n};\n\nconst lensFor = (graph: SceneGraph, overlay: Overlay): Lens => {\n const views = graph.views();\n const view: HostedView | undefined =\n overlay.view === null ? views[0] : views.find((candidate) => candidate.key === overlay.view);\n if (view !== undefined) return { camera: view.camera, ...view.area };\n const { width, height } = graph.viewport();\n return { camera: graph.camera, x: 0, y: 0, width, height };\n};\n\n/** The overlay's point in world space: relative to its node, or as given. */\nconst worldPoint = (graph: SceneGraph, overlay: Overlay): Vector3 => {\n point.fromArray(overlay.position);\n const node: Object3D | undefined = overlay.node === null ? undefined : graph.object(overlay.node);\n return node === undefined ? point : node.localToWorld(point);\n};\n\n/** Drei's `isObjectBehindCamera`: more than 90° from where the camera looks. */\nconst behind = (camera: Camera, at: Vector3): boolean => {\n cameraPosition.setFromMatrixPosition(camera.matrixWorld);\n toPoint.copy(at).sub(cameraPosition);\n return toPoint.angleTo(camera.getWorldDirection(direction)) > Math.PI / 2;\n};\n\n/** Drei's `isObjectVisible`: nothing in the scene is hit before the point. */\nconst unoccluded = (graph: SceneGraph, camera: Camera, at: Vector3): boolean => {\n toPoint.copy(at).project(camera);\n ndc.set(toPoint.x, toPoint.y);\n raycaster.setFromCamera(ndc, camera);\n const [nearest] = raycaster.intersectObjects(graph.scene.children, true);\n return nearest === undefined || at.distanceTo(raycaster.ray.origin) < nearest.distance;\n};\n\n/** Drei's `objectScale`: one over the height of the view at the point's distance. */\nconst objectScale = (camera: Camera, at: Vector3): number => {\n if (camera instanceof OrthographicCamera) return camera.zoom;\n if (!(camera instanceof PerspectiveCamera)) return 1;\n cameraPosition.setFromMatrixPosition(camera.matrixWorld);\n const height = 2 * Math.tan((camera.fov * Math.PI) / 360) * at.distanceTo(cameraPosition);\n return 1 / height;\n};\n\n/** Drei's `objectZIndex`: linear in distance from near (`range[0]`) to far (`range[1]`). */\nconst zIndexOf = (camera: Camera, at: Vector3, range: readonly [number, number]): number => {\n if (!(camera instanceof PerspectiveCamera || camera instanceof OrthographicCamera)) return 0;\n cameraPosition.setFromMatrixPosition(camera.matrixWorld);\n const slope = (range[1] - range[0]) / (camera.far - camera.near);\n const offset = range[1] - slope * camera.far;\n return Math.round(slope * at.distanceTo(cameraPosition) + offset);\n};\n\nconst place = (graph: SceneGraph, overlay: Overlay): OverlayPlacement => {\n const lens = lensFor(graph, overlay);\n lens.camera.updateMatrixWorld();\n const at = worldPoint(graph, overlay);\n const visible =\n !behind(lens.camera, at) && (!overlay.occlude || unoccluded(graph, lens.camera, at));\n const scale =\n overlay.distanceFactor === null ? 1 : objectScale(lens.camera, at) * overlay.distanceFactor;\n const zIndex = zIndexOf(lens.camera, at, overlay.zIndexRange);\n toPoint.copy(at).project(lens.camera);\n return {\n key: overlay.key,\n x: lens.x + ((toPoint.x + 1) / 2) * lens.width,\n y: lens.y + ((1 - toPoint.y) / 2) * lens.height,\n scale,\n zIndex,\n visible,\n center: overlay.center,\n };\n};\n\n/** Places every overlay of the graph's scene, after its world matrices are current. */\nexport const placeOverlays = (graph: SceneGraph): ReadonlyArray<OverlayPlacement> => {\n const overlays = graph.overlays();\n if (overlays.length === 0) return [];\n graph.scene.updateMatrixWorld();\n return overlays.map((overlay) => place(graph, overlay));\n};\n",
|
|
23
|
+
"/**\n * The kernel's side of physics: an engine-neutral world contract, and colliders worked\n * out from geometry. An engine package (Rapier, in `@opsydyn/effect-three-rapier`)\n * implements `PhysicsEngine`; the scene graph steps it and moves meshes to its poses.\n *\n * Behavioural reference: react-three-rapier at `ae5c3fe` (2.2.0):\n * `getColliderArgsFromGeometry` in `src/utils/utils-collider.ts` for colliders (a cuboid\n * from the bounding box, a ball from the bounding sphere, a hull or trimesh from the\n * vertices, each scaled by the mesh's world scale), and the step loop in\n * `src/components/Physics.tsx` (fixed steps, delta clamped to 0.5 s, poses interpolated\n * between the last two steps).\n *\n * @module\n */\nimport {\n type BufferGeometry,\n Euler,\n Matrix4,\n type Mesh,\n type Object3D,\n Quaternion,\n Vector3,\n} from 'three';\n\nimport type {\n Body,\n BodyCollider,\n ColliderDescription,\n ColliderShapeDescription,\n InteractionGroups,\n JointKind,\n Physics,\n Vec3,\n} from './description.ts';\n\n/** A quaternion, `[x, y, z, w]`. */\nexport type Quat = readonly [x: number, y: number, z: number, w: number];\n\n/** Where a body is, in world space. */\nexport type BodyPose = { readonly position: Vec3; readonly quaternion: Quat };\n\n/** A collider's shape, scaled as its mesh is, centred on its own origin. */\nexport type ColliderShape =\n | { readonly _tag: 'Cuboid'; readonly halfExtents: Vec3 }\n | { readonly _tag: 'Ball'; readonly radius: number }\n | { readonly _tag: 'Hull'; readonly points: Float32Array }\n /** Along y: a cylinder `halfHeight` each way, capped by `radius` (Rapier's capsule). */\n | { readonly _tag: 'Capsule'; readonly halfHeight: number; readonly radius: number }\n | { readonly _tag: 'Cylinder'; readonly halfHeight: number; readonly radius: number }\n | { readonly _tag: 'Cone'; readonly halfHeight: number; readonly radius: number }\n | { readonly _tag: 'Trimesh'; readonly vertices: Float32Array; readonly indices: Uint32Array };\n\n/** A collider placed in its body's space: one per mesh in the body. */\nexport type Collider = {\n readonly shape: ColliderShape;\n readonly translation: Vec3;\n readonly rotation: Quat;\n /** The part of its body it is, for collisions to name: a mesh's or collider's name. */\n readonly part?: string;\n};\n\n/**\n * Two bodies began (`started`) or stopped touching, by the ids they were added with: a\n * node's key, or for an instance the node's and instance's keys joined by a NUL.\n */\nexport type Collision = {\n readonly a: string;\n readonly b: string;\n /** The colliders' parts, when they have names. */\n readonly aPart?: string;\n readonly bPart?: string;\n readonly started: boolean;\n};\n\n/** A joint as an engine makes it: a fixed joint's frames as quaternions. */\nexport type PhysicsJoint = {\n readonly anchorA: Vec3;\n readonly anchorB: Vec3;\n readonly contacts: boolean;\n readonly kind:\n | Exclude<JointKind, { readonly _tag: 'Fixed' }>\n | { readonly _tag: 'Fixed'; readonly frameA: Quat; readonly frameB: Quat };\n};\n\n/**\n * Groups as Rapier packs them (react-three-rapier's `interactionGroups`): memberships in\n * the high 16 bits, filters in the low 16 (all when `null`). `null` groups are all-all.\n */\nexport const interactionBits = (groups: InteractionGroups | null): number => {\n const mask = (list: ReadonlyArray<number>): number =>\n list.reduce((bits, group) => bits | (1 << group), 0);\n if (groups === null) return 0xffff_ffff;\n const filters = groups.filters === null ? 0xffff : mask(groups.filters);\n return ((mask(groups.memberships) << 16) | filters) >>> 0;\n};\n\n/**\n * Two bodies pushing on each other harder than a body's `contactForces` threshold in one\n * step, by the ids they were added with: Rapier's contact force event.\n */\nexport type ContactForce = {\n readonly a: string;\n readonly b: string;\n readonly aPart?: string;\n readonly bPart?: string;\n readonly totalForce: Vec3;\n readonly totalForceMagnitude: number;\n readonly maxForceDirection: Vec3;\n readonly maxForceMagnitude: number;\n};\n\n/** Lines drawing a world's colliders and joints: segment ends, and RGBA per end. */\nexport type DebugLines = { readonly vertices: Float32Array; readonly colors: Float32Array };\n\n/** One physics world, its bodies keyed by id. Every method is synchronous. */\nexport type PhysicsWorld = {\n readonly configure: (physics: Physics) => void;\n /** Adds a body with its colliders (none, for a model not yet loaded). */\n readonly add: (\n key: string,\n body: Body,\n colliders: ReadonlyArray<Collider>,\n pose: BodyPose,\n ) => void;\n /** Applies a body's settings that need no new collider: type, mass, friction and so on. */\n readonly update: (key: string, body: Body) => void;\n /** Puts a body at `pose`, at rest. */\n readonly teleport: (key: string, pose: BodyPose) => void;\n /** Where a kinematic body is to be after the next step. */\n readonly moveKinematic: (key: string, pose: BodyPose) => void;\n readonly applyImpulse: (key: string, impulse: Vec3) => void;\n /** Removes a body, and any joint holding it. */\n readonly remove: (key: string) => void;\n /** Joins bodies `a` and `b` (both added). */\n readonly addJoint: (id: string, joint: PhysicsJoint, a: string, b: string) => void;\n /** Removes a joint; nothing if it is gone already (with one of its bodies). */\n readonly removeJoint: (id: string) => void;\n /** Advances by `seconds` and returns the collisions that began or ended. */\n readonly step: (seconds: number) => ReadonlyArray<Collision>;\n /** Contact forces over their bodies' thresholds in the steps since the last call. */\n readonly contactForces: () => ReadonlyArray<ContactForce>;\n /** The world as lines, for `physics({ debug: true })`. */\n readonly debugLines: () => DebugLines;\n readonly pose: (key: string) => BodyPose | undefined;\n /** Whether any dynamic body is still moving (not asleep). */\n readonly awake: () => boolean;\n readonly dispose: () => void;\n};\n\n/** Makes physics worlds. Provide one to the scene graph (in Foldkit, the environment). */\nexport type PhysicsEngine = { readonly createWorld: (physics: Physics) => PhysicsWorld };\n\nconst toVec3 = (vector: Vector3): Vec3 => [vector.x, vector.y, vector.z];\n\nconst size = new Vector3();\n\n/** The geometry's positions, scaled. */\nconst scaledPositions = (geometry: BufferGeometry, scale: Vector3): Float32Array => {\n const positions = geometry.getAttribute('position');\n const points = new Float32Array(positions.count * 3);\n for (let i = 0; i < positions.count; i++) {\n points[i * 3] = positions.getX(i) * scale.x;\n points[i * 3 + 1] = positions.getY(i) * scale.y;\n points[i * 3 + 2] = positions.getZ(i) * scale.z;\n }\n return points;\n};\n\n/** Triangle indices: the geometry's own, or one triangle per three positions. */\nconst triangles = (geometry: BufferGeometry): Uint32Array => {\n const index = geometry.getIndex();\n if (index !== null) return Uint32Array.from(index.array);\n return Uint32Array.from({ length: geometry.getAttribute('position').count }, (_, i) => i);\n};\n\n/** A tiny ball for an empty geometry (text before its font, say). */\nconst speck: { readonly shape: ColliderShape; readonly offset: Vector3 } = {\n shape: { _tag: 'Ball', radius: 1e-3 },\n offset: new Vector3(),\n};\n\n/**\n * The shape for a geometry at world `scale`, and where its centre is (scaled), as\n * react-three-rapier's `getColliderArgsFromGeometry` sizes auto colliders.\n */\nconst shapeFor = (\n geometry: BufferGeometry,\n collider: BodyCollider,\n scale: Vector3,\n): { readonly shape: ColliderShape; readonly offset: Vector3 } => {\n if (geometry.getAttribute('position') === undefined) return speck;\n switch (collider) {\n case 'cuboid': {\n geometry.computeBoundingBox();\n const box = geometry.boundingBox;\n if (box === null) return speck;\n box.getSize(size).multiply(scale).multiplyScalar(0.5);\n return {\n shape: { _tag: 'Cuboid', halfExtents: toVec3(size) },\n offset: box.getCenter(new Vector3()).multiply(scale),\n };\n }\n case 'ball': {\n geometry.computeBoundingSphere();\n const sphere = geometry.boundingSphere;\n if (sphere === null) return speck;\n const largest = Math.max(Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z));\n return {\n shape: { _tag: 'Ball', radius: sphere.radius * largest },\n offset: sphere.center.clone().multiply(scale),\n };\n }\n case 'hull':\n return {\n shape: { _tag: 'Hull', points: scaledPositions(geometry, scale) },\n offset: new Vector3(),\n };\n case 'trimesh':\n return {\n shape: {\n _tag: 'Trimesh',\n vertices: scaledPositions(geometry, scale),\n indices: triangles(geometry),\n },\n offset: new Vector3(),\n };\n }\n};\n\n/**\n * The collider for one geometry at world `scale`, centred where its geometry is: what a\n * mesh with a body of its own gets.\n */\nexport const colliderFor = (\n geometry: BufferGeometry,\n collider: BodyCollider,\n scale: Vector3,\n): Collider => {\n const { shape, offset } = shapeFor(geometry, collider, scale);\n return { shape, translation: toVec3(offset), rotation: [0, 0, 0, 1] };\n};\n\nconst turn3 = new Quaternion();\nconst turnEuler = new Euler();\nconst largest = (a: number, b: number): number => Math.max(Math.abs(a), Math.abs(b));\n\n/** A described shape at world `scale`: lengths along an axis by that axis's scale. */\nconst scaledShape = (shape: ColliderShapeDescription, scale: Vector3): ColliderShape => {\n switch (shape._tag) {\n case 'Cuboid': {\n const [x, y, z] = shape.halfExtents;\n return { _tag: 'Cuboid', halfExtents: [x * scale.x, y * scale.y, z * scale.z] };\n }\n case 'Ball':\n return {\n _tag: 'Ball',\n radius: shape.radius * Math.max(Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z)),\n };\n case 'Capsule':\n case 'Cylinder':\n case 'Cone':\n return {\n _tag: shape._tag,\n halfHeight: shape.halfHeight * Math.abs(scale.y),\n radius: shape.radius * largest(scale.x, scale.z),\n };\n }\n};\n\n/**\n * A body's own colliders at its world `scale`: each shape scaled, its position too. Unlike\n * react-three-rapier's `scaleColliderArgs`, which scales arguments by position (x, y, z,\n * x, x), each length scales along its own axis.\n */\nexport const describedColliders = (\n colliders: ReadonlyArray<ColliderDescription>,\n scale: Vector3,\n): ReadonlyArray<Collider> => colliders.map((collider) => describedCollider(collider, scale));\n\n/** One of a body's own colliders at its world `scale`. */\nfunction describedCollider(collider: ColliderDescription, scale: Vector3): Collider {\n const [x, y, z] = collider.position;\n turn3.setFromEuler(turnEuler.fromArray([...collider.rotation]));\n return {\n shape: scaledShape(collider.shape, scale),\n translation: [x * scale.x, y * scale.y, z * scale.z],\n rotation: [turn3.x, turn3.y, turn3.z, turn3.w],\n ...(collider.name === null ? {} : { part: collider.name }),\n };\n}\n\nconst relative = new Matrix4();\nconst bodyInverse = new Matrix4();\nconst where = new Vector3();\nconst turn = new Quaternion();\nconst relativeScale = new Vector3();\nconst worldScale = new Vector3();\nconst worldPosition = new Vector3();\nconst worldTurn = new Quaternion();\n\nconst isMesh = (object: Object3D): object is Mesh => 'isMesh' in object && object.isMesh === true;\n\n/** A mesh's collider in the body whose inverse world matrix is `bodyInverse`. */\nfunction placedCollider(child: Mesh, collider: BodyCollider, body: Object3D): Collider {\n child.matrixWorld.decompose(worldPosition, worldTurn, worldScale);\n relative.copy(child.matrixWorld).premultiply(bodyInverse).decompose(where, turn, relativeScale);\n const { shape, offset } = shapeFor(child.geometry, collider, worldScale);\n where.add(offset.applyQuaternion(turn));\n return {\n shape,\n translation: toVec3(where),\n rotation: [turn.x, turn.y, turn.z, turn.w],\n // A mesh inside a group or model is a part of it; the body's own mesh is the body.\n ...(child === body || child.name === '' ? {} : { part: child.name }),\n };\n}\n\n/**\n * A number as signature text, to five places with `-0` as `0`: the simulation turns a body,\n * and its matrices pick up rounding that must not read as a change of shape.\n */\nconst settled = (value: number): string => (Math.round(value * 1e5) / 1e5 || 0).toString();\n\n/** A mesh's geometry and placement in the body whose inverse is `bodyInverse`. */\nfunction meshSignature(child: Mesh): string {\n relative.copy(child.matrixWorld).premultiply(bodyInverse);\n child.matrixWorld.decompose(worldPosition, worldTurn, worldScale);\n const placed = relative.elements.map(settled).join(',');\n return `${child.geometry.uuid}:${placed}:${worldScale.toArray().map(settled).join(',')}`;\n}\n\n/** The visible meshes in `body`, itself included. */\nfunction visibleMeshes(body: Object3D): ReadonlyArray<Mesh> {\n const meshes: Array<Mesh> = [];\n body.traverseVisible((child) => {\n if (isMesh(child)) meshes.push(child);\n });\n return meshes;\n}\n\n/**\n * A collider for every visible mesh in `body` (itself included), placed by its transform\n * relative to the body and sized by its world scale, as react-three-rapier's\n * `createColliderPropsFromChildren` makes a group's or a model's colliders. Unlike there,\n * a geometry's off-centre middle is turned with its mesh.\n */\nexport const collidersFor = (body: Object3D, collider: BodyCollider): ReadonlyArray<Collider> => {\n body.updateWorldMatrix(true, true);\n bodyInverse.copy(body.matrixWorld).invert();\n return visibleMeshes(body).map((child) => placedCollider(child, collider, body));\n};\n\n/**\n * What a body's colliders are made from: each visible mesh's geometry and placement.\n * When it changes, the colliders must be made again.\n */\nexport const colliderSignature = (body: Object3D): string => {\n body.updateWorldMatrix(true, true);\n bodyInverse.copy(body.matrixWorld).invert();\n return visibleMeshes(body).map(meshSignature).join('|');\n};\n",
|
|
24
|
+
"/**\n * Moving the player in an immersive session, as functions from the scene's `xr` settings\n * to new ones: the Model keeps where the player stands, and the session follows it.\n *\n * Behavioural reference: pmndrs/xr at `0e1acd8`, `controller-locomotion.ts`: the right\n * thumbstick snap-turns 45° once pushed past halfway (and must come back before turning\n * again), and the left one moves the player along where they face. Here moving is a step\n * per push, not a glide: sticks arrive as `XrStick` events when pushed and let back.\n * `teleport` is `@react-three/xr`'s `TeleportTarget`: the player stands where they point.\n *\n * @module\n */\nimport type { Vec3, Xr } from './description.ts';\nimport type { XrHand, XrStickDirection } from './xrInput.ts';\n\nexport type LocomotionOptions = {\n /** Degrees a snap turn turns by. Default 45, as pmndrs/xr's. */\n readonly snapDegrees?: number;\n /** Metres a step moves. Default 1. */\n readonly step?: number;\n /** The hand whose stick turns; the other moves. Default `right`, as pmndrs/xr's. */\n readonly turnHand?: Exclude<XrHand, 'none'>;\n};\n\n/** A step `forward` (`-1` back) and `right` (`-1` left) of the player facing `heading`. */\nconst stepped = (settings: Xr, forward: number, right: number): Vec3 => {\n const [x, y, z] = settings.origin;\n const sin = Math.sin(settings.heading);\n const cos = Math.cos(settings.heading);\n // Facing `heading` about +y from −z: forward is (−sin, −cos), right is (cos, −sin).\n return [x - forward * sin + right * cos, y, z - forward * cos - right * sin];\n};\n\n/**\n * The settings after a stick is pushed: the turning hand's left and right snap-turn, the\n * other hand's stick steps forward, back, left or right. Centring changes nothing.\n */\nexport const locomote = (\n settings: Xr,\n stick: { readonly hand: XrHand; readonly direction: XrStickDirection },\n options: LocomotionOptions = {},\n): Xr => {\n const turnHand = options.turnHand ?? 'right';\n const step = options.step ?? 1;\n const snap = ((options.snapDegrees ?? 45) * Math.PI) / 180;\n if (stick.hand === turnHand) {\n if (stick.direction === 'left') return { ...settings, heading: settings.heading + snap };\n if (stick.direction === 'right') return { ...settings, heading: settings.heading - snap };\n return settings;\n }\n const moves: Readonly<Record<XrStickDirection, readonly [number, number] | undefined>> = {\n center: undefined,\n forward: [step, 0],\n back: [-step, 0],\n left: [0, -step],\n right: [0, step],\n };\n const move = moves[stick.direction];\n return move === undefined ? settings : { ...settings, origin: stepped(settings, ...move) };\n};\n\n/** The settings with the player standing at `point` (on the floor there), facing as before. */\nexport const teleport = (settings: Xr, point: Vec3): Xr => ({\n ...settings,\n origin: [point[0], settings.origin[1], point[2]],\n});\n\n/** The settings where gliding left the player (an `XrMoved` event): its origin and heading. */\nexport const glided = (\n settings: Xr,\n moved: { readonly origin: Vec3; readonly heading: number },\n): Xr => ({ ...settings, origin: moved.origin, heading: moved.heading });\n",
|
|
25
|
+
"/**\n * XR input as the scene's events: controllers and hands pointing, selecting, dragging,\n * pushing sticks and pressing buttons, and (in AR) selecting a real surface.\n *\n * Behavioural reference: pmndrs/xr at `0e1acd8`. Its pointers ray-cast along each input\n * source's target ray every frame (`packages/xr/src/pointer`), entering and leaving what\n * they point at, capturing the object a select starts on so moving drags it, and turning\n * select start and end into pointer down, up and click. Its controller locomotion\n * (`controller-locomotion.ts`) reads the thumbstick each frame; here a stick reports when\n * it is pushed past halfway in a direction and when it comes back, so a Model can snap\n * turn and teleport by changing `xr({ origin, heading })`.\n *\n * @module\n */\nimport type { Vec3 } from './description.ts';\nimport type { Hit, Picker, Ray, SceneEvent } from './pointer.ts';\n\n/** Which hand an input source is held in or is, as WebXR's `handedness`. */\nexport type XrHand = 'left' | 'right' | 'none';\n\n/** Where a thumbstick is pushed: `forward` is away from the player. */\nexport type XrStickDirection = 'center' | 'left' | 'right' | 'forward' | 'back';\n\n/**\n * A controller's buttons, by the `xr-standard` gamepad mapping: the trigger, the grip\n * (`squeeze`), a touchpad, the thumbstick pressed, and the face buttons (A and B on the\n * right controller, X and Y on the left: `primary` and `secondary`).\n */\nexport type XrButtonName =\n | 'trigger'\n | 'squeeze'\n | 'touchpad'\n | 'thumbstick'\n | 'primary'\n | 'secondary';\n\n/**\n * A plane the session detected (`xr({ planes: true })`): a floor, wall or table, in the\n * scene's space. `polygon` is its outline in its own space (on its x–z plane); `label` is\n * what the device took it for (`floor`, `wall`, `table`…), or `''` when it did not say.\n * Follow one with `group({ follow: planeSpace(id) })`.\n */\nexport type XrPlane = {\n readonly id: string;\n readonly orientation: 'horizontal' | 'vertical';\n readonly label: string;\n readonly position: Vec3;\n readonly rotation: Vec3;\n readonly polygon: ReadonlyArray<Vec3>;\n};\n\n/**\n * A mesh the session detected (`xr({ meshes: true })`): furniture, a wall, the room. Its\n * pose is in the scene's space; its geometry is lent for `xrMesh(id)` rather than sent.\n */\nexport type XrMesh = {\n readonly id: string;\n readonly label: string;\n readonly position: Vec3;\n readonly rotation: Vec3;\n};\n\n/** Input from an immersive session, each from an input source (`source` tells them apart). */\nexport type XrInput =\n /** A select (the trigger, or a pinch) beginning or ending, along the source's ray. */\n | { readonly _tag: 'SelectStart' | 'SelectEnd'; readonly source: number; readonly ray: Ray }\n /** Where the source points this frame. */\n | { readonly _tag: 'Aim'; readonly source: number; readonly ray: Ray }\n /** The source went away (put down, or the session ended). */\n | { readonly _tag: 'Lost'; readonly source: number }\n | {\n readonly _tag: 'Stick';\n readonly source: number;\n readonly hand: XrHand;\n readonly direction: XrStickDirection;\n }\n | {\n readonly _tag: 'Button';\n readonly source: number;\n readonly hand: XrHand;\n readonly button: XrButtonName;\n readonly pressed: boolean;\n }\n /** Gliding (`xr({ glide })`) stopped: where the player stands now, for the Model. */\n | { readonly _tag: 'Moved'; readonly origin: Vec3; readonly heading: number }\n /** The detected planes changed: all of them, as they are now. */\n | { readonly _tag: 'Planes'; readonly planes: ReadonlyArray<XrPlane> }\n /** The detected meshes changed: all of them, as they are now. */\n | { readonly _tag: 'Meshes'; readonly meshes: ReadonlyArray<XrMesh> }\n /** In AR, a select whose ray met a real surface: where, and the surface's normal. */\n | {\n readonly _tag: 'Surface';\n readonly source: number;\n readonly hand: XrHand;\n readonly point: Vec3;\n readonly normal: Vec3;\n };\n\n/** One source's state: what it points at, the select it holds, and its last ray. */\ntype Source = {\n hovered: string | undefined;\n /** The key a held select started on (`undefined` for nothing) and its ray, while held. */\n pressed: { readonly key: string | undefined; readonly ray: Ray } | undefined;\n dragged: boolean;\n ray: Ray | undefined;\n};\n\nconst none: ReadonlyArray<SceneEvent> = [];\n\n/**\n * How far a held source must move before it drags, as the mouse must travel a few pixels:\n * its ray turned by a degree, or moved a centimetre. Hands and controllers never hold\n * perfectly still, and a select that does not move is a click.\n */\nconst dragStart = { turn: Math.cos((1 * Math.PI) / 180), shift: 0.01 } as const;\n\nconst moved = (from: Ray, to: Ray): boolean => {\n const [a, b, c] = from.direction;\n const [x, y, z] = to.direction;\n const [p, q, r] = from.origin;\n const [u, v, w] = to.origin;\n return (\n a * x + b * y + c * z < dragStart.turn || Math.hypot(u - p, v - q, w - r) > dragStart.shift\n );\n};\n\n/** Creates the tracker turning one session's XR input into scene events. */\nexport const createXrTracker = (picker: Picker) => {\n const sources = new Map<number, Source>();\n\n const sourceOf = (id: number): Source => {\n const known = sources.get(id);\n if (known !== undefined) return known;\n const created: Source = {\n hovered: undefined,\n pressed: undefined,\n dragged: false,\n ray: undefined,\n };\n sources.set(id, created);\n return created;\n };\n\n /** Leaves and enters as what the source points at changes. */\n const hover = (source: Source, hit: Hit | undefined, events: Array<SceneEvent>): void => {\n const next = hit?.key;\n if (next === source.hovered) return;\n if (source.hovered !== undefined) events.push({ _tag: 'PointerLeave', key: source.hovered });\n if (hit !== undefined) events.push({ _tag: 'PointerEnter', ...hit });\n source.hovered = next;\n };\n\n const aim = (source: Source, ray: Ray): ReadonlyArray<SceneEvent> => {\n source.ray = ray;\n const events: Array<SceneEvent> = [];\n const pressed = source.pressed;\n // A select held on a mesh captures it: moving drags it, wherever the ray now points.\n if (pressed?.key !== undefined && (source.dragged || moved(pressed.ray, ray))) {\n source.dragged = true;\n events.push({ _tag: 'Drag', key: pressed.key, button: 0, ray });\n }\n hover(source, picker.pickRay(ray), events);\n return events;\n };\n\n const selectStart = (source: Source, ray: Ray): ReadonlyArray<SceneEvent> => {\n const hit = picker.pickRay(ray);\n source.pressed = { key: hit?.key, ray };\n source.dragged = false;\n return hit === undefined ? none : [{ _tag: 'PointerDown', button: 0, ...hit }];\n };\n\n const selectEnd = (source: Source, ray: Ray): ReadonlyArray<SceneEvent> => {\n const from = source.pressed?.key;\n const dragged = source.dragged;\n source.pressed = undefined;\n source.dragged = false;\n const events: Array<SceneEvent> = [];\n if (from !== undefined && dragged) events.push({ _tag: 'DragEnd', key: from, button: 0, ray });\n const hit = picker.pickRay(ray);\n if (hit === undefined) {\n if (from === undefined) events.push({ _tag: 'PointerMissed', button: 0 });\n return events;\n }\n events.push({ _tag: 'PointerUp', button: 0, ...hit });\n if (from === hit.key) events.push({ _tag: 'Click', button: 0, ...hit });\n return events;\n };\n\n /** A source gone: it leaves what it pointed at, and a drag ends where it last aimed. */\n const lost = (id: number): ReadonlyArray<SceneEvent> => {\n const source = sources.get(id);\n sources.delete(id);\n if (source === undefined) return none;\n const events: Array<SceneEvent> = [];\n const held = source.pressed?.key;\n if (held !== undefined && source.dragged && source.ray !== undefined) {\n events.push({ _tag: 'DragEnd', key: held, button: 0, ray: source.ray });\n }\n if (source.hovered !== undefined) events.push({ _tag: 'PointerLeave', key: source.hovered });\n return events;\n };\n\n return (input: XrInput): ReadonlyArray<SceneEvent> => {\n switch (input._tag) {\n case 'Aim':\n return aim(sourceOf(input.source), input.ray);\n case 'SelectStart':\n return selectStart(sourceOf(input.source), input.ray);\n case 'SelectEnd':\n return selectEnd(sourceOf(input.source), input.ray);\n case 'Lost':\n return lost(input.source);\n case 'Stick':\n return [{ _tag: 'XrStick', hand: input.hand, direction: input.direction }];\n case 'Button':\n return [\n { _tag: 'XrButton', hand: input.hand, button: input.button, pressed: input.pressed },\n ];\n case 'Moved':\n return [{ _tag: 'XrMoved', origin: input.origin, heading: input.heading }];\n case 'Planes':\n return [{ _tag: 'XrPlanes', planes: input.planes }];\n case 'Meshes':\n return [{ _tag: 'XrMeshes', meshes: input.meshes }];\n case 'Surface':\n return [{ _tag: 'XrSurface', hand: input.hand, point: input.point, normal: input.normal }];\n }\n };\n};\n",
|
|
26
|
+
"/**\n * Drei's environment presets (`src/helpers/environment-assets.ts` and the `CUBEMAP_ROOT` of\n * `src/core/useEnvironment.tsx` at `bf6f4ad`): Poly Haven HDR panoramas (CC0) on Drei's\n * asset repository at the commit Drei pins, served by a CDN. Nothing is fetched until an\n * application loads one, as an environment map lent like any other:\n *\n * ```ts\n * environment.assets.loadEnvironment('sky', environmentPresetUrl('city'));\n * scene({ environment: environment({ map: 'sky' }) });\n * ```\n *\n * @module\n */\n\n/** Each preset's file. */\nexport const environmentPresets = {\n apartment: 'lebombo_1k.hdr',\n city: 'potsdamer_platz_1k.hdr',\n dawn: 'kiara_1_dawn_1k.hdr',\n forest: 'forest_slope_1k.hdr',\n lobby: 'st_fagans_interior_1k.hdr',\n night: 'dikhololo_night_1k.hdr',\n park: 'rooitou_park_1k.hdr',\n studio: 'studio_small_03_1k.hdr',\n sunset: 'venice_sunset_1k.hdr',\n warehouse: 'empty_warehouse_01_1k.hdr',\n} satisfies Readonly<Record<string, string>>;\n\nexport type EnvironmentPreset = keyof typeof environmentPresets;\n\n/** Where Drei's presets are served from: its asset repository at the commit it pins. */\nconst dreiAssets = {\n hdri: 'https://raw.githack.com/pmndrs/drei-assets/456060a26bbeb8fdf79326f224b6d99b8bcce736/hdri/',\n} as const;\n\n/** The URL of a preset's HDR file, for `assets.loadEnvironment`. */\nexport const environmentPresetUrl = (preset: EnvironmentPreset): string =>\n `${dreiAssets.hdri}${environmentPresets[preset]}`;\n",
|
|
27
|
+
"/**\n * A ready-lit stage for a model, as Drei's `Stage` (`src/core/Stage.tsx` at `bf6f4ad`):\n * an ambient light, a main spot light and a fill point light placed by a lighting preset\n * and scaled by the content's size, contact shadows at its base, and an environment.\n *\n * Drei's `Stage` measures and centres its children and can fit the camera to them. Here\n * that is a loop through the Model, as controls are (ADR-006): measure the content\n * (`scene({ measure })` reports its box), place it at `centerOffset(box)` as Drei's\n * `Center` would, light it with `stage(stageBounds(box))`, and frame it with `fitCamera`\n * as Drei's `Bounds` would.\n *\n * @module\n */\nimport {\n ambientLight,\n contactShadows as contactShadowsOf,\n environment as environmentOf,\n pointLight,\n spotLight,\n} from './build.ts';\nimport type { ContactShadows, Environment, SceneNode, Vec3 } from './description.ts';\nimport type { Box } from './orbit.ts';\n\n/** Where the main and fill lights sit, in multiples of the content's radius. */\nexport type StageLighting = { readonly main: Vec3; readonly fill: Vec3 };\n\n/** Drei's lighting presets. */\nexport const stagePresets = {\n rembrandt: { main: [1, 2, 1], fill: [-2, -0.5, -2] },\n portrait: { main: [-1, 2, 0.5], fill: [-1, 0.5, -1.5] },\n upfront: { main: [0, 2, 1], fill: [-1, 0.5, -1.5] },\n soft: { main: [-2, 4, 4], fill: [-1, 0.5, -1.5] },\n} satisfies Record<string, StageLighting>;\n\nexport type StagePreset = keyof typeof stagePresets;\n\n/** The scene parts a stage contributes: spread them into `scene`. */\nexport type Stage = {\n /** The stage's lights; add them to the scene's children. */\n readonly lights: ReadonlyArray<SceneNode>;\n readonly contactShadows: ContactShadows | null;\n readonly environment: Environment | null;\n};\n\nconst scaled = (point: Vec3, by: number): Vec3 => [point[0] * by, point[1] * by, point[2] * by];\n\n/**\n * Lights, ground shadows and an environment for content centred on the origin with\n * bounding radius `radius` and height `height`. Defaults as Drei's `Stage`: the\n * Rembrandt preset, intensity 0.5, contact shadows (`radius × 4` across, reaching\n * `radius` up, blur 2) and a spot light that casts shadow maps when the scene enables\n * them (bias −0.0001, 1024 texels). Drei's default environment is the \"city\" HDR from a\n * CDN; here it is three.js's `RoomEnvironment`, built in code. `keyPrefix` names the\n * lights (`stage-ambient`, `stage-main`, `stage-fill` by default).\n */\nexport const stage = (options: {\n readonly radius: number;\n readonly height: number;\n readonly preset?: StagePreset | StageLighting;\n readonly intensity?: number;\n readonly shadows?: 'contact' | 'none';\n readonly environment?: Environment | null;\n readonly keyPrefix?: string;\n}): Stage => {\n const { radius, height } = options;\n const lighting =\n typeof options.preset === 'object'\n ? options.preset\n : stagePresets[options.preset ?? 'rembrandt'];\n const intensity = options.intensity ?? 0.5;\n const prefix = options.keyPrefix ?? 'stage';\n const shadowed = (options.shadows ?? 'contact') === 'contact';\n return {\n lights: [\n ambientLight({ key: `${prefix}-ambient`, intensity: intensity / 3 }),\n spotLight({\n key: `${prefix}-main`,\n position: scaled(lighting.main, radius),\n penumbra: 1,\n intensity: intensity * 2,\n castShadow: shadowed,\n shadowBias: -0.0001,\n shadowMapSize: 1024,\n }),\n pointLight({ key: `${prefix}-fill`, position: scaled(lighting.fill, radius), intensity }),\n ],\n contactShadows: shadowed\n ? contactShadowsOf({ position: [0, -height / 2, 0], size: radius * 4, far: radius, blur: 2 })\n : null,\n environment: options.environment === undefined ? environmentOf() : options.environment,\n };\n};\n\n/**\n * Which way to align content instead of centring it, per axis, as Drei's `Center` props:\n * `top` stands it on y = 0 (on top of the origin), `bottom` hangs it below; `left` puts\n * it left of x = 0, `right` right of it; `front` before z = 0, `back` behind. `disableY`\n * leaves that axis as it is.\n */\nexport type CenterAlign = {\n readonly top?: boolean;\n readonly bottom?: boolean;\n readonly left?: boolean;\n readonly right?: boolean;\n readonly front?: boolean;\n readonly back?: boolean;\n readonly disableX?: boolean;\n readonly disableY?: boolean;\n readonly disableZ?: boolean;\n};\n\n/**\n * One axis of Drei's `Center`: the shift that puts the box's middle at 0, moved half its\n * size up the axis (`above`, so its low side is at 0) or down it (`below`).\n */\nconst alignAxis = (\n min: number,\n max: number,\n above: boolean | undefined,\n below: boolean | undefined,\n disabled: boolean | undefined,\n): number => {\n if (disabled === true) return 0;\n const half = (max - min) / 2;\n const shift = above === true ? half : below === true ? -half : 0;\n return -(min + max) / 2 + shift;\n};\n\n/**\n * Where to put content whose box (as measured where it is drawn now, at no offset) is\n * `box` so that it is centred on the origin, or aligned by `align`: Drei's `Center`\n * (`src/core/Center.tsx` at `bf6f4ad`), which sets its inner group to this position.\n */\nexport const centerOffset = (box: Box, align: CenterAlign = {}): Vec3 => [\n alignAxis(box.min[0], box.max[0], align.right, align.left, align.disableX),\n alignAxis(box.min[1], box.max[1], align.top, align.bottom, align.disableY),\n alignAxis(box.min[2], box.max[2], align.front, align.back, align.disableZ),\n];\n\n/**\n * The sizes Drei's `Stage` takes from `Center`'s report: the box's bounding sphere radius\n * (half its diagonal) and its width, height and depth. Pass to `stage` for lights and\n * shadows scaled to the content.\n */\nexport const stageBounds = (\n box: Box,\n): {\n readonly radius: number;\n readonly width: number;\n readonly height: number;\n readonly depth: number;\n} => {\n const width = box.max[0] - box.min[0];\n const height = box.max[1] - box.min[1];\n const depth = box.max[2] - box.min[2];\n return { radius: Math.hypot(width, height, depth) / 2, width, height, depth };\n};\n",
|
|
28
|
+
"import { Box3, EquirectangularReflectionMapping, type Texture, UVMapping } from 'three';\n\nimport type { RenderSettings } from './description.ts';\nimport { type OverlayPlacement, placeOverlays } from './overlays.ts';\nimport { createPerformanceMonitor, type PerformanceOptions } from './performance.ts';\n/**\n * The per-frame step and pointer routing for one scene. Plain synchronous code: the\n * Effect runtime owns its lifetime (ADR-003: Effect owns lifetimes, not frames).\n *\n * @module\n */\nimport {\n createPicker,\n createPointerTracker,\n type PointerInput,\n type SceneEvent,\n} from './pointer.ts';\nimport type { RenderTarget, SceneRenderer } from './renderer.ts';\nimport type { ContactShadowPasses } from './renderKit.ts';\nimport type { SceneGraph } from './sceneGraph.ts';\nimport { createXrTracker, type XrInput } from './xrInput.ts';\n\nexport type SceneLoopOptions = {\n readonly graph: SceneGraph;\n readonly renderer: SceneRenderer;\n /** Scene time in seconds. Behaviours are a pure function of it. */\n readonly elapsedSeconds: () => number;\n /** Receives every scene event. Must not throw. */\n readonly emit: (event: SceneEvent) => void;\n /** Wall-clock milliseconds, for the frame-rate monitor. Defaults to `Date.now`. */\n readonly now?: () => number;\n /** Tuning for the frame-rate monitor. */\n readonly performance?: PerformanceOptions;\n /**\n * Receives where the scene's overlays are after each drawn frame, for the host to move\n * their HTML there; once with none after the last overlay goes. Must not throw.\n */\n readonly placeOverlays?: (placements: ReadonlyArray<OverlayPlacement>) => void;\n};\n\nexport type SceneLoop = {\n /** Advances behaviours, re-tests hover and renders one frame. */\n readonly frame: () => void;\n /**\n * Whether frames should keep coming: always in `always` mode, while the graph needs one\n * in `demand` mode, never in `never` mode (frames then come only from `advance`).\n */\n readonly wantsFrames: () => boolean;\n /** Releases the render textures' targets and withdraws their textures. */\n readonly dispose: () => void;\n /**\n * Routes pointer input to hit testing, emits the resulting events and returns them, so\n * a DOM listener can decide synchronously whether the scene handled its event.\n */\n readonly pointer: (input: PointerInput) => ReadonlyArray<SceneEvent>;\n /** Routes XR input (aims, selects, sticks, buttons, surfaces), emitting the events. */\n readonly xrInput: (input: XrInput) => ReadonlyArray<SceneEvent>;\n};\n\n/** Creates the frame step and pointer router for one scene. */\nconst noContactShadows: ContactShadowPasses = { draw: () => undefined, dispose: () => undefined };\n\nexport const createSceneLoop = (options: SceneLoopOptions): SceneLoop => {\n const { graph, renderer, elapsedSeconds, emit } = options;\n const picker = createPicker(graph);\n const tracker = createPointerTracker(picker);\n const xrTracker = createXrTracker(picker);\n const monitor = createPerformanceMonitor(options.performance);\n const now = options.now ?? Date.now;\n let configured: RenderSettings | undefined;\n // Whether overlays were placed last frame, so their going is reported once.\n let placedAny = false;\n // One offscreen target per render texture, its texture lent to the store under its id.\n const targets = new Map<\n string,\n {\n readonly target: RenderTarget;\n readonly width: number;\n readonly height: number;\n readonly withdraw: () => void;\n fresh: boolean;\n }\n >();\n\n const release = (id: string): void => {\n const held = targets.get(id);\n if (held === undefined) return;\n held.withdraw();\n held.target.dispose();\n targets.delete(id);\n };\n\n /** Draws each render texture whose scene changed or animates, into its own target. */\n const drawTextures = (): void => {\n const textures = graph.renderTextures();\n for (const texture of textures) {\n const held = targets.get(texture.id);\n if (held === undefined || held.width !== texture.width || held.height !== texture.height) {\n release(texture.id);\n const target = renderer.createTarget(texture.width, texture.height);\n const withdraw = graph.store.lendTexture(texture.id, target.texture);\n targets.set(texture.id, {\n target,\n width: texture.width,\n height: texture.height,\n withdraw,\n fresh: true,\n });\n }\n const current = targets.get(texture.id);\n if (current !== undefined && (current.fresh || texture.graph.needsFrame())) {\n renderer.render(texture.graph.scene, texture.graph.camera, undefined, current.target);\n texture.graph.drawn();\n current.fresh = false;\n }\n }\n if (targets.size > textures.length) {\n const live = new Set(textures.map((texture) => texture.id));\n for (const id of targets.keys()) if (!live.has(id)) release(id);\n }\n };\n // Contact shadows are shaded: the render kit draws them, or nothing does.\n const contact = graph.kit?.contactShadows(graph, renderer) ?? noContactShadows;\n // The room environment, made by the renderer while a scene asks for it.\n let room: RenderTarget | undefined;\n\n const releaseRoom = (): void => {\n room?.dispose();\n room = undefined;\n };\n\n /** The environment's texture: the room, or the lent map (set to reflect as a panorama). */\n const environmentTexture = (map: string | null): Texture | null => {\n if (map === null) {\n room ??= renderer.createEnvironment();\n return room.texture;\n }\n releaseRoom();\n const texture = graph.store.texture(map) ?? null;\n // As Drei's useEnvironment: an equirectangular image maps as a reflection panorama.\n if (texture !== null && texture.mapping === UVMapping) {\n texture.mapping = EquirectangularReflectionMapping;\n texture.needsUpdate = true;\n }\n return texture;\n };\n\n /** Applies the scene's environment as Drei's `setEnvProps` does. */\n const applyEnvironment = (): void => {\n const environment = graph.environment();\n const { scene } = graph;\n if (environment === null) {\n releaseRoom();\n scene.environment = null;\n scene.background = null;\n return;\n }\n const texture = environmentTexture(environment.map);\n scene.environment = environment.background === 'only' ? null : texture;\n scene.background = environment.background === false ? null : texture;\n scene.backgroundBlurriness = environment.backgroundBlurriness;\n scene.backgroundIntensity = environment.backgroundIntensity;\n scene.environmentIntensity = environment.environmentIntensity;\n };\n\n // The last box reported for each measured key, so only changes are reported.\n const reported = new Map<string, Box3>();\n const box = new Box3();\n\n // The last layout reported for each measured label.\n const laidOut = new Map<string, string>();\n\n const measureLabel = (key: string): void => {\n const layout = graph.labelLayout(key);\n if (layout === undefined) return;\n const signature = [...layout.block, ...layout.visible].join(',');\n if (laidOut.get(key) === signature) return;\n laidOut.set(key, signature);\n emit({ _tag: 'LabelMeasured', key, block: layout.block, visible: layout.visible });\n };\n\n const measure = (): void => {\n const keys = graph.measured();\n if (keys.length === 0 && reported.size === 0 && laidOut.size === 0) return;\n for (const key of keys) {\n measureLabel(key);\n const object = graph.object(key);\n if (object === undefined) continue;\n box.setFromObject(object);\n if (box.isEmpty()) continue;\n const last = reported.get(key);\n if (last !== undefined && last.equals(box)) continue;\n reported.set(key, box.clone());\n emit({ _tag: 'Measured', key, min: box.min.toArray(), max: box.max.toArray() });\n }\n for (const key of reported.keys()) if (!keys.includes(key)) reported.delete(key);\n for (const key of laidOut.keys()) if (!keys.includes(key)) laidOut.delete(key);\n };\n\n return {\n frame: () => {\n graph.tick(elapsedSeconds());\n for (const event of tracker.frame()) emit(event);\n for (const collision of graph.collisions()) emit({ _tag: 'Collision', ...collision });\n for (const force of graph.contactForces()) emit({ _tag: 'ContactForce', ...force });\n // Settings change only through reconcile, which replaces the value: compare by reference.\n const settings = graph.renderSettings();\n if (settings !== configured) {\n renderer.configure(settings);\n configured = settings;\n }\n drawTextures();\n applyEnvironment();\n contact.draw();\n const views = graph.views();\n if (views.length === 0) renderer.render(graph.scene, graph.camera);\n for (const view of views) renderer.render(graph.scene, view.camera, view.area);\n graph.drawn();\n measure();\n const overlays = graph.overlays();\n if (options.placeOverlays !== undefined && (overlays.length > 0 || placedAny)) {\n options.placeOverlays(placeOverlays(graph));\n placedAny = overlays.length > 0;\n }\n const change = monitor.sample(now());\n if (change !== undefined) emit({ _tag: 'PerformanceChanged', ...change });\n },\n dispose: () => {\n for (const id of targets.keys()) release(id);\n releaseRoom();\n contact.dispose();\n },\n wantsFrames: () => {\n const mode = graph.renderSettings().frames;\n return mode === 'always' || (mode === 'demand' && graph.needsFrame());\n },\n pointer: (input) => {\n const events = tracker.input(input);\n for (const event of events) emit(event);\n return events;\n },\n xrInput: (input) => {\n const events = xrTracker(input);\n for (const event of events) emit(event);\n return events;\n },\n };\n};\n",
|
|
29
|
+
"/**\n * Pointer hit testing and the pointer state machine.\n *\n * Input arrives in normalised device coordinates (NDC: x and y in [-1, 1], y up), never\n * as DOM events, so this stays DOM-free. Hover is reported on transitions (enter, leave)\n * plus a move for each pointer movement over an interactive mesh.\n *\n * Behavioural reference: React Three Fiber `packages/fiber/src/core/events.ts` at\n * `d74622e`. As there, click, double-click and context-menu events go only to the mesh\n * that was also under the pointer when it was pressed, and a click that hits nothing and\n * moved at most two CSS pixels is a miss.\n *\n * @module\n */\nimport { type Object3D, Raycaster, Vector2, Vector3 } from 'three';\n\nimport type { Gestures, Vec3 } from './description.ts';\nimport type { SceneGraph } from './sceneGraph.ts';\nimport type { XrButtonName, XrHand, XrMesh, XrPlane, XrStickDirection } from './xrInput.ts';\n\n/** Modifier keys held during an input, as on `MouseEvent`. */\nexport type Modifiers = {\n readonly shift: boolean;\n readonly control: boolean;\n readonly meta: boolean;\n readonly alt: boolean;\n};\n\n/**\n * Pointer input in normalised device coordinates. `button` follows `MouseEvent.button`.\n * `pointer` is the input's `PointerEvent.pointerId` (0 when absent): with two pointers\n * pressed (two fingers), the second only takes part in pinches.\n */\nexport type PointerInput =\n | {\n readonly _tag: 'PointerMove';\n readonly x: number;\n readonly y: number;\n readonly pointer?: number;\n }\n | {\n readonly _tag: 'PointerDown';\n readonly x: number;\n readonly y: number;\n readonly button: number;\n readonly pointer?: number;\n readonly modifiers?: Modifiers;\n }\n | {\n readonly _tag: 'PointerUp';\n readonly x: number;\n readonly y: number;\n readonly button: number;\n readonly pointer?: number;\n }\n | {\n readonly _tag: 'DoubleClick';\n readonly x: number;\n readonly y: number;\n readonly button: number;\n }\n | { readonly _tag: 'ContextMenu'; readonly x: number; readonly y: number }\n | {\n readonly _tag: 'Wheel';\n readonly x: number;\n readonly y: number;\n /** In CSS pixels: line and page deltas are converted, as three.js's controls do. */\n readonly deltaX: number;\n readonly deltaY: number;\n readonly modifiers?: Modifiers;\n }\n | { readonly _tag: 'PointerLeave' };\n\n/**\n * A gesture on the canvas, reported when the scene claims gestures (`gestures: 'scene'`).\n * Distances are CSS pixels, right and down positive, since the previous gesture event;\n * `width` and `height` are the CSS size of the canvas, or of the view the gesture began\n * in, for turning pixels into angles and distances. `view` names that view. `x` and `y`\n * locate the gesture in it (−1 to 1, y up): where a drag was pressed, the wheel turned,\n * or a pinch's midpoint is, for zooming toward the cursor.\n *\n * - `Drag`: the pointer moved while pressed, with the button and modifiers of the press.\n * `key` names the interactive mesh the press landed on, if any, so a Model can leave\n * the camera alone while that mesh is dragged.\n * - `Wheel`: the wheel turned, anywhere over the canvas.\n * - `Pinch`: two pointers moved: `scale` is their new distance over the old (above 1\n * when spreading), and the deltas are how far their midpoint moved.\n */\nexport type Gesture =\n | {\n readonly _tag: 'Drag';\n readonly button: number;\n readonly modifiers: Modifiers;\n readonly key?: string;\n readonly view?: string;\n readonly deltaX: number;\n readonly deltaY: number;\n readonly width: number;\n readonly height: number;\n readonly x: number;\n readonly y: number;\n }\n | {\n readonly _tag: 'Wheel';\n readonly modifiers: Modifiers;\n readonly view?: string;\n readonly deltaX: number;\n readonly deltaY: number;\n readonly width: number;\n readonly height: number;\n readonly x: number;\n readonly y: number;\n }\n | {\n readonly _tag: 'Pinch';\n readonly view?: string;\n readonly scale: number;\n readonly deltaX: number;\n readonly deltaY: number;\n readonly width: number;\n readonly height: number;\n readonly x: number;\n readonly y: number;\n };\n\n/** No modifier keys held. */\nexport const noModifiers: Modifiers = { shift: false, control: false, meta: false, alt: false };\n\n/**\n * The nearest interactive mesh under a point.\n *\n * - `point`: world-space hit point. `distance`: from the camera, in world units.\n * - `normal`: world-space normal of the face hit. `uv`: texture coordinates at the hit.\n * Every kernel-built geometry has both; a geometry without them reports zeros.\n */\nexport type Hit = {\n readonly key: string;\n /** For an `instances` node, the key of the instance hit. */\n readonly instance?: string;\n /** For a `borrowed` node, the `name` of the object hit inside it, when it has one. */\n readonly part?: string;\n /** With several views, the key of the view the pointer was over. */\n readonly view?: string;\n /**\n * Keys of the hit mesh's ancestor groups, nearest first. Match on it to handle every\n * mesh in a group with one handler: React Three Fiber's bubbling, as data.\n */\n readonly path: ReadonlyArray<string>;\n readonly point: Vec3;\n readonly distance: number;\n readonly normal: Vec3;\n readonly uv: readonly [u: number, v: number];\n /** The world-space ray through the pointer, as on every React Three Fiber event. */\n readonly ray: Ray;\n};\n\n/** A world-space ray from the camera through the pointer. `direction` is unit length. */\nexport type Ray = { readonly origin: Vec3; readonly direction: Vec3 };\n\n/** A plane `normal · p + constant = 0`, as three.js's `Plane`. */\nexport type PlaneEquation = { readonly normal: Vec3; readonly constant: number };\n\n/**\n * Where a ray meets a plane, or `undefined` when it runs parallel or the plane is behind\n * it. Turns drag rays into points: `pointOnPlane(ray, { normal: [0, 1, 0], constant: 0 })`\n * is the point on the ground.\n */\nexport const pointOnPlane = (ray: Ray, plane: PlaneEquation): Vec3 | undefined => {\n const [nx, ny, nz] = plane.normal;\n const [ox, oy, oz] = ray.origin;\n const [dx, dy, dz] = ray.direction;\n const denominator = nx * dx + ny * dy + nz * dz;\n if (Math.abs(denominator) < 1e-12) return undefined;\n const t = -(nx * ox + ny * oy + nz * oz + plane.constant) / denominator;\n if (t < 0) return undefined;\n return [ox + dx * t, oy + dy * t, oz + dz * t];\n};\n\n/** A hit with a tag and extra fields, flattened into one object type. */\ntype HitEvent<Tag extends string, Extra = unknown> = {\n readonly [K in keyof ({ readonly _tag: Tag } & Hit & Extra)]: ({ readonly _tag: Tag } & Hit &\n Extra)[K];\n};\n\n/** Interaction with an interactive mesh, identified by its key, plus misses. */\nexport type SceneEvent =\n | HitEvent<'PointerEnter'>\n | { readonly _tag: 'PointerLeave'; readonly key: string }\n | HitEvent<'PointerMove'>\n | HitEvent<'PointerDown', { readonly button: number }>\n | HitEvent<'PointerUp', { readonly button: number }>\n | HitEvent<'Click', { readonly button: number }>\n | HitEvent<'DoubleClick', { readonly button: number }>\n | HitEvent<'ContextMenu'>\n | HitEvent<'Wheel', { readonly deltaX: number; readonly deltaY: number }>\n /** A click that hit no interactive mesh: useful for clearing a selection. */\n | { readonly _tag: 'PointerMissed'; readonly button: number }\n /**\n * The pointer moved while pressed on mesh `key`, anywhere: the press captures the\n * pointer, as React Three Fiber's `setPointerCapture` does, until release.\n */\n | { readonly _tag: 'Drag'; readonly key: string; readonly button: number; readonly ray: Ray }\n /** A drag on `key` ended: released anywhere, or the pointer left. Only after a `Drag`. */\n | {\n readonly _tag: 'DragEnd';\n readonly key: string;\n readonly button: number;\n readonly ray: Ray;\n }\n /** A drag, wheel or pinch on the canvas, when the scene claims gestures. */\n | { readonly _tag: 'Gesture'; readonly gesture: Gesture }\n /**\n * A gesture is about to begin on a camera that has turned by itself (`autoRotate`):\n * where it got to, so the Model can keep it (`autoRotated(camera, detail)`) and the\n * gesture moves on from there. `view` names a view's camera; without it, the scene's.\n */\n | { readonly _tag: 'AutoRotated'; readonly view?: string; readonly position: Vec3 }\n /** In an immersive session, a thumbstick pushed past halfway in a direction, or let back. */\n | { readonly _tag: 'XrStick'; readonly hand: XrHand; readonly direction: XrStickDirection }\n /** In an immersive session, a controller button pressed or released. */\n | {\n readonly _tag: 'XrButton';\n readonly hand: XrHand;\n readonly button: XrButtonName;\n readonly pressed: boolean;\n }\n /**\n * Gliding with the sticks (`xr({ glide })`) stopped: where the player stands, to keep\n * in the Model's `xr({ origin, heading })`.\n */\n | { readonly _tag: 'XrMoved'; readonly origin: Vec3; readonly heading: number }\n /** The session's detected planes changed (`xr({ planes: true })`): all of them, now. */\n | { readonly _tag: 'XrPlanes'; readonly planes: ReadonlyArray<XrPlane> }\n /** The session's detected meshes changed (`xr({ meshes: true })`): all of them, now. */\n | { readonly _tag: 'XrMeshes'; readonly meshes: ReadonlyArray<XrMesh> }\n /** In AR, a select whose ray met a real surface (`xr({ hitTest: true })`). */\n | {\n readonly _tag: 'XrSurface';\n readonly hand: XrHand;\n readonly point: Vec3;\n readonly normal: Vec3;\n }\n /**\n * Two bodies began (`started`) or stopped touching, by their nodes' keys (and, for a body\n * on an instance, the instance's): Rapier's collision events, as react-three-rapier's\n * `onCollisionEnter` and `onCollisionExit`. Not a pointer event: it travels with them so\n * one stream carries everything.\n */\n | {\n readonly _tag: 'Collision';\n readonly a: string;\n readonly aInstance?: string;\n readonly aPart?: string;\n readonly b: string;\n readonly bInstance?: string;\n readonly bPart?: string;\n readonly started: boolean;\n }\n /**\n * Two bodies pushed on each other harder than a body's `contactForces` threshold during\n * a step: react-three-rapier's `onContactForce` payload, named as collisions are.\n */\n | {\n readonly _tag: 'ContactForce';\n readonly a: string;\n readonly aInstance?: string;\n readonly aPart?: string;\n readonly b: string;\n readonly bInstance?: string;\n readonly bPart?: string;\n readonly totalForce: Vec3;\n readonly totalForceMagnitude: number;\n readonly maxForceDirection: Vec3;\n readonly maxForceMagnitude: number;\n }\n /**\n * A measured label's laid-out size changed (`scene({ measure })`, after its glyphs are\n * laid out): in its own units, before its scale, for sizing what goes behind it, as\n * Drei's `Text` `onSync` reads troika's `textRenderInfo`.\n */\n | {\n readonly _tag: 'LabelMeasured';\n readonly key: string;\n readonly block: readonly [number, number, number, number];\n readonly visible: readonly [number, number, number, number];\n }\n /**\n * A measured node's world bounding box changed (`scene({ measure })`): Drei's `Bounds`\n * `box.setFromObject`, reported rather than read. Not a pointer event either.\n */\n | {\n readonly _tag: 'Measured';\n readonly key: string;\n readonly min: Vec3;\n readonly max: Vec3;\n }\n /**\n * The frame-rate monitor moved the performance factor (0 to 1). Not a pointer event:\n * it travels with them so one stream carries everything the scene reports.\n */\n | { readonly _tag: 'PerformanceChanged'; readonly fps: number; readonly factor: number };\n\nexport type Picker = {\n /** Hit-tests at NDC `(x, y)`. Updates world matrices first, so it works headless. */\n readonly pick: (x: number, y: number) => Hit | undefined;\n /** The world-space ray through NDC `(x, y)`. */\n readonly ray: (x: number, y: number) => Ray;\n /** Hit-tests along a world-space ray: an XR controller's, say. */\n readonly pickRay: (ray: Ray) => Hit | undefined;\n /** The picked graph's viewport in CSS pixels, for pixel thresholds. */\n readonly viewport: () => { readonly width: number; readonly height: number };\n /**\n * The CSS size of what is under NDC `(x, y)`: the view there, with its key, or the\n * whole canvas.\n */\n readonly region: (x: number, y: number) => Region;\n /** Whether the scene claims the pointer's gestures. */\n readonly gestures: () => Gestures;\n /** Holds the cameras' turning (`autoRotate`) while a gesture is pressed. */\n readonly holdCameras: (held: boolean) => void;\n /** Where turning has taken a view's camera (or the scene's), if it has turned. */\n readonly turned: (view: string | undefined) => Vec3 | undefined;\n};\n\n/** A part of the canvas in CSS pixels: a view, named by `view`, or the whole canvas. */\nexport type Region = {\n readonly view?: string;\n readonly width: number;\n readonly height: number;\n /** The point in the region's own normalised coordinates: −1 to 1, y up. */\n readonly x: number;\n readonly y: number;\n};\n\nconst toVec3 = (vector: Vector3): Vec3 => [vector.x, vector.y, vector.z];\n\n/**\n * The nearest object with a key: the object itself for kernel-built meshes, or the\n * borrowed node wrapping an application object.\n */\nconst keyedOwner = (graph: SceneGraph, object: Object3D): Object3D | undefined => {\n for (let current: Object3D | null = object; current !== null; current = current.parent) {\n if (graph.keyOf(current) !== undefined) return current;\n }\n return undefined;\n};\n\n/** The name of the part hit inside a borrowed object, when the hit is inside one. */\nconst partOf = (owner: Object3D, hit: Object3D): { readonly part?: string } =>\n owner === hit || hit.name === '' ? {} : { part: hit.name };\n\n/** Keys of an object's keyed ancestors, nearest first. */\nconst pathOf = (graph: SceneGraph, object: Object3D): ReadonlyArray<string> => {\n const path: Array<string> = [];\n for (let parent = object.parent; parent !== null; parent = parent.parent) {\n const key = graph.keyOf(parent);\n if (key !== undefined) path.push(key);\n }\n return path;\n};\n\n/** Creates a raycasting picker over a graph's interactive meshes and groups. */\nexport const createPicker = (graph: SceneGraph): Picker => {\n const raycaster = new Raycaster();\n const ndc = new Vector2();\n const normal = new Vector3();\n /**\n * Aims the ray through canvas NDC `(x, y)`: with the main camera, or with the camera of\n * the topmost view under the point, in that view's own NDC. Returns the view's key, or\n * `false` when views exist but none is under the point.\n */\n const aim = (x: number, y: number): string | undefined | false => {\n graph.scene.updateMatrixWorld();\n const views = graph.views();\n if (views.length === 0) {\n graph.camera.updateMatrixWorld();\n ndc.set(x, y);\n raycaster.setFromCamera(ndc, graph.camera);\n return undefined;\n }\n const { width, height } = graph.viewport();\n const px = ((x + 1) / 2) * width;\n const py = ((1 - y) / 2) * height;\n for (let i = views.length - 1; i >= 0; i--) {\n const view = views[i];\n if (view === undefined) continue;\n const { area } = view;\n if (px < area.x || px > area.x + area.width || py < area.y || py > area.y + area.height) {\n continue;\n }\n view.camera.updateMatrixWorld();\n ndc.set(((px - area.x) / area.width) * 2 - 1, -(((py - area.y) / area.height) * 2 - 1));\n raycaster.setFromCamera(ndc, view.camera);\n return view.key;\n }\n return false;\n };\n // A world-space ray's origin and direction, as `Raycaster.set` takes them.\n const rayOrigin = new Vector3();\n const rayDirection = new Vector3();\n\n /** The nearest keyed hit along the raycaster's ray, reporting `view` when there is one. */\n const nearestHit = (view: string | undefined): Hit | undefined => {\n // Recursive, so an interactive group makes every mesh inside it pickable.\n for (const intersection of raycaster.intersectObjects(graph.interactiveObjects(), true)) {\n const owner = keyedOwner(graph, intersection.object);\n const key = owner === undefined ? undefined : graph.keyOf(owner);\n if (owner !== undefined && key !== undefined) {\n normal.set(0, 0, 0);\n if (intersection.face) {\n normal.copy(intersection.face.normal).transformDirection(intersection.object.matrixWorld);\n }\n const instance =\n intersection.instanceId === undefined\n ? undefined\n : graph.instanceKeyOf(intersection.object, intersection.instanceId);\n return {\n key,\n ...(instance === undefined ? {} : { instance }),\n ...partOf(owner, intersection.object),\n ...(view === undefined ? {} : { view }),\n path: pathOf(graph, owner),\n point: toVec3(intersection.point),\n distance: intersection.distance,\n normal: toVec3(normal),\n uv: [intersection.uv?.x ?? 0, intersection.uv?.y ?? 0],\n ray: currentRay(),\n };\n }\n }\n return undefined;\n };\n\n const currentRay = (): Ray => ({\n origin: toVec3(raycaster.ray.origin),\n direction: toVec3(raycaster.ray.direction),\n });\n return {\n ray: (x, y) => {\n aim(x, y);\n return currentRay();\n },\n region: (x, y) => {\n const { width, height } = graph.viewport();\n const px = ((x + 1) / 2) * width;\n const py = ((1 - y) / 2) * height;\n const view = graph\n .views()\n .findLast(\n ({ area }) =>\n px >= area.x && px <= area.x + area.width && py >= area.y && py <= area.y + area.height,\n );\n return view === undefined\n ? { width, height, x, y }\n : {\n view: view.key,\n width: view.area.width,\n height: view.area.height,\n x: ((px - view.area.x) / view.area.width) * 2 - 1,\n y: 1 - ((py - view.area.y) / view.area.height) * 2,\n };\n },\n gestures: graph.gestures,\n holdCameras: graph.holdCameras,\n turned: graph.turned,\n pick: (x, y) => {\n if (graph.interactiveObjects().length === 0) return undefined;\n const view = aim(x, y);\n if (view === false) return undefined;\n return nearestHit(view);\n },\n pickRay: (ray) => {\n if (graph.interactiveObjects().length === 0) return undefined;\n graph.scene.updateMatrixWorld();\n raycaster.set(\n rayOrigin.fromArray(ray.origin),\n rayDirection.fromArray(ray.direction).normalize(),\n );\n return nearestHit(undefined);\n },\n viewport: graph.viewport,\n };\n};\n\nexport type PointerTracker = {\n /** Applies one input and returns the resulting events. */\n readonly input: (input: PointerInput) => ReadonlyArray<SceneEvent>;\n /**\n * Re-tests hover at the last pointer position. Call once per frame: objects can move\n * under a stationary pointer. Returns only enter and leave transitions.\n */\n readonly frame: () => ReadonlyArray<SceneEvent>;\n};\n\nconst none: ReadonlyArray<SceneEvent> = [];\n\n/** A click moving further than this, in CSS pixels, is a drag and never a miss. */\nconst missTolerance = 2;\n\ntype Press = {\n readonly key: string | undefined;\n readonly button: number;\n readonly x: number;\n readonly y: number;\n};\n\n/** The press a gesture began with: its button, modifiers, mesh and region. */\ntype GesturePress = Region & {\n readonly button: number;\n readonly modifiers: Modifiers;\n readonly key?: string;\n};\n\ntype Point = { readonly x: number; readonly y: number };\n\nconst pointerOf = (input: PointerInput): number =>\n 'pointer' in input && input.pointer !== undefined ? input.pointer : 0;\n\n/** Creates the pointer state machine for one scene. */\nexport const createPointerTracker = (picker: Picker): PointerTracker => {\n let position: { x: number; y: number } | undefined;\n // Pressed pointers in NDC, for gestures. The first pressed is primary and drives the\n // press, click and drag machinery; others only take part in pinches.\n const pressedPointers = new Map<number, Point>();\n let primary: number | undefined;\n let gesturePress: GesturePress | undefined;\n let hovered: string | undefined;\n // The latest press, kept after release: double-click and context-menu events follow it.\n let press: Press | undefined;\n let pressing = false;\n // Whether the current press has dragged: only then does its release end a drag.\n let dragged = false;\n\n const hover = (hit: Hit | undefined, events: Array<SceneEvent>): void => {\n const next = hit?.key;\n if (next === hovered) return;\n if (hovered !== undefined) events.push({ _tag: 'PointerLeave', key: hovered });\n if (hit !== undefined) events.push({ _tag: 'PointerEnter', ...hit });\n hovered = next;\n };\n\n /** CSS pixels between the press and NDC `(x, y)`. */\n const travel = (from: Press, x: number, y: number): number => {\n const { width, height } = picker.viewport();\n return Math.hypot(((x - from.x) * width) / 2, ((y - from.y) * height) / 2);\n };\n\n const pressed = (hit: Hit): boolean => press !== undefined && press.key === hit.key;\n\n const release = (\n hit: Hit | undefined,\n event: { readonly x: number; readonly y: number; readonly button: number },\n events: Array<SceneEvent>,\n ): void => {\n const from = pressing ? press : undefined;\n pressing = false;\n if (hit !== undefined) {\n events.push({ _tag: 'PointerUp', button: event.button, ...hit });\n if (from?.key === hit.key && from.button === event.button) {\n events.push({ _tag: 'Click', button: event.button, ...hit });\n }\n return;\n }\n if (from?.button === event.button && travel(from, event.x, event.y) <= missTolerance) {\n events.push({ _tag: 'PointerMissed', button: event.button });\n }\n };\n\n /** The pressed mesh holding pointer capture, if any. */\n const captured = (): { readonly key: string; readonly button: number } | undefined =>\n pressing && press?.key !== undefined ? { key: press.key, button: press.button } : undefined;\n\n /** Ends a drag that moved; a press released without moving was a click, not a drag. */\n const endDrag = (\n drag: { readonly key: string; readonly button: number } | undefined,\n x: number,\n y: number,\n events: Array<SceneEvent>,\n ): void => {\n if (drag !== undefined && dragged) {\n events.push({ _tag: 'DragEnd', ...drag, ray: picker.ray(x, y) });\n }\n dragged = false;\n };\n\n /** NDC distance to CSS pixels on the canvas, down positive. */\n const pixels = (from: Point, to: Point): Point => {\n const { width, height } = picker.viewport();\n return { x: ((to.x - from.x) * width) / 2, y: (-(to.y - from.y) * height) / 2 };\n };\n\n const pixelDistance = (a: Point, b: Point): number => {\n const { x, y } = pixels(a, b);\n return Math.hypot(x, y);\n };\n\n /** Reports where the camera under `region` has turned to, before a gesture on it. */\n const reportTurned = (region: Region, events: Array<SceneEvent>): void => {\n const position = picker.turned(region.view);\n if (position === undefined) return;\n events.push({\n _tag: 'AutoRotated',\n ...(region.view === undefined ? {} : { view: region.view }),\n position,\n });\n };\n\n /** A gesture press begins: the first pointer down while the scene claims gestures. */\n const beginGesture = (\n event: Extract<PointerInput, { readonly _tag: 'PointerDown' }>,\n id: number,\n key: string | undefined,\n events: Array<SceneEvent>,\n ): void => {\n if (picker.gestures() !== 'scene') return;\n pressedPointers.clear();\n primary = id;\n pressedPointers.set(id, { x: event.x, y: event.y });\n const region = picker.region(event.x, event.y);\n reportTurned(region, events);\n // Cameras turning by themselves hold still while it is pressed, as `OrbitControls`.\n picker.holdCameras(true);\n gesturePress = {\n ...region,\n button: event.button,\n modifiers: event.modifiers ?? noModifiers,\n ...(key === undefined ? {} : { key }),\n };\n };\n\n /** Moves pointer `id` to `to`: a drag with one pointer pressed, a pinch with two. */\n const moveGesture = (id: number, to: Point, events: Array<SceneEvent>): void => {\n const from = pressedPointers.get(id);\n if (from === undefined || gesturePress === undefined) return;\n pressedPointers.set(id, to);\n const { view, width, height, x, y } = gesturePress;\n const region = { ...(view === undefined ? {} : { view }), width, height, x, y };\n const moved = pixels(from, to);\n const other = [...pressedPointers].find(([pointer]) => pointer !== id)?.[1];\n if (other === undefined) {\n if (id !== primary) return;\n const { button, modifiers, key } = gesturePress;\n events.push({\n _tag: 'Gesture',\n gesture: {\n _tag: 'Drag',\n button,\n modifiers,\n ...(key === undefined ? {} : { key }),\n ...region,\n deltaX: moved.x,\n deltaY: moved.y,\n },\n });\n return;\n }\n const before = pixelDistance(from, other);\n const after = pixelDistance(to, other);\n const middle = picker.region((to.x + other.x) / 2, (to.y + other.y) / 2);\n events.push({\n _tag: 'Gesture',\n gesture: {\n _tag: 'Pinch',\n ...region,\n x: middle.x,\n y: middle.y,\n scale: before === 0 ? 1 : after / before,\n // The midpoint moves half as far as the one pointer that moved.\n deltaX: moved.x / 2,\n deltaY: moved.y / 2,\n },\n });\n };\n\n const endGestures = (): void => {\n if (gesturePress !== undefined) picker.holdCameras(false);\n pressedPointers.clear();\n primary = undefined;\n gesturePress = undefined;\n };\n\n /**\n * Input from a pointer other than the primary one while that is pressed: it joins,\n * pinches or leaves, and touches nothing else.\n */\n const secondary = (event: PointerInput, id: number): ReadonlyArray<SceneEvent> => {\n const events: Array<SceneEvent> = [];\n if (event._tag === 'PointerDown' && gesturePress !== undefined) {\n pressedPointers.set(id, { x: event.x, y: event.y });\n } else if (event._tag === 'PointerMove') {\n moveGesture(id, event, events);\n } else if (event._tag === 'PointerUp') {\n pressedPointers.delete(id);\n }\n return events;\n };\n\n const isSecondary = (event: PointerInput, id: number): boolean =>\n primary !== undefined &&\n id !== primary &&\n (event._tag === 'PointerDown' ||\n ((event._tag === 'PointerMove' || event._tag === 'PointerUp') && pressedPointers.has(id)));\n\n const input = (event: PointerInput): ReadonlyArray<SceneEvent> => {\n const id = pointerOf(event);\n if (isSecondary(event, id)) return secondary(event, id);\n const events: Array<SceneEvent> = [];\n if (event._tag === 'PointerLeave') {\n endGestures();\n // A cancelled or abandoned press still ends its drag, at the last known position.\n if (position !== undefined) endDrag(captured(), position.x, position.y, events);\n dragged = false;\n position = undefined;\n press = undefined;\n pressing = false;\n hover(undefined, events);\n return events;\n }\n const drag = captured();\n position = { x: event.x, y: event.y };\n const hit = picker.pick(event.x, event.y);\n hover(hit, events);\n switch (event._tag) {\n case 'PointerMove':\n if (hit !== undefined) events.push({ _tag: 'PointerMove', ...hit });\n if (drag !== undefined) {\n dragged = true;\n events.push({ _tag: 'Drag', ...drag, ray: picker.ray(event.x, event.y) });\n }\n moveGesture(id, event, events);\n break;\n case 'PointerDown':\n press = { key: hit?.key, button: event.button, x: event.x, y: event.y };\n pressing = true;\n dragged = false;\n if (hit !== undefined) events.push({ _tag: 'PointerDown', button: event.button, ...hit });\n beginGesture(event, id, hit?.key, events);\n break;\n case 'PointerUp':\n release(hit, event, events);\n // Any release ends capture: a mouse's buttons share one pointer.\n endDrag(drag, event.x, event.y, events);\n endGestures();\n break;\n case 'DoubleClick':\n if (hit !== undefined && pressed(hit)) {\n events.push({ _tag: 'DoubleClick', button: event.button, ...hit });\n }\n break;\n case 'ContextMenu':\n if (hit !== undefined && pressed(hit)) events.push({ _tag: 'ContextMenu', ...hit });\n break;\n case 'Wheel':\n if (hit !== undefined) {\n events.push({ _tag: 'Wheel', deltaX: event.deltaX, deltaY: event.deltaY, ...hit });\n }\n if (picker.gestures() === 'scene') {\n const region = picker.region(event.x, event.y);\n // The wheel does not hold turning still, as `OrbitControls` keeps turning on it.\n reportTurned(region, events);\n events.push({\n _tag: 'Gesture',\n gesture: {\n _tag: 'Wheel',\n modifiers: event.modifiers ?? noModifiers,\n ...region,\n deltaX: event.deltaX,\n deltaY: event.deltaY,\n },\n });\n }\n break;\n }\n return events;\n };\n\n const frame = (): ReadonlyArray<SceneEvent> => {\n if (position === undefined) return none;\n const events: Array<SceneEvent> = [];\n hover(picker.pick(position.x, position.y), events);\n return events.length === 0 ? none : events;\n };\n\n return { input, frame };\n};\n",
|
|
30
|
+
"/**\n * The renderer boundary (requirement 7). Synchronous and backend-neutral: a WebGL or\n * WebGPU implementation lives outside the DOM-free core and is handed in as a factory.\n *\n * @module\n */\nimport { type Camera, type Scene, Texture } from 'three';\n\nimport type { RenderSettings } from './description.ts';\nimport type { RenderKit } from './renderKit.ts';\n\n/** Size of the drawing surface in CSS pixels, plus the device pixel ratio. */\nexport type Viewport = {\n readonly width: number;\n readonly height: number;\n readonly pixelRatio: number;\n};\n\n/** GPU memory counters, as reported by three.js `renderer.info.memory`. */\nexport type RendererMemory = {\n readonly geometries: number;\n readonly textures: number;\n};\n\n/** A live renderer bound to one drawing surface. */\n/** A rectangle of the drawing surface in CSS pixels, from the top left. */\nexport type RenderArea = {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n};\n\n/** An offscreen surface: render into it, then use its texture. Dispose exactly once. */\nexport type RenderTarget = {\n readonly texture: Texture;\n readonly dispose: () => void;\n};\n\nexport type SceneRenderer = {\n /**\n * Draws the scene through `camera`, into `area` when given (clearing only that area),\n * otherwise across the whole surface.\n */\n readonly render: (scene: Scene, camera: Camera, area?: RenderArea, target?: RenderTarget) => void;\n /** Creates an offscreen target of `width` × `height` pixels to render into. */\n readonly createTarget: (width: number, height: number) => RenderTarget;\n /**\n * Creates the environment map of three.js's `RoomEnvironment`, prefiltered for this\n * renderer (WebGL: `PMREMGenerator.fromScene(new RoomEnvironment(), 0.04)`).\n */\n readonly createEnvironment: () => RenderTarget;\n /** Applies scene-wide render settings. Called before the first frame and on each change. */\n readonly configure: (settings: RenderSettings) => void;\n readonly setViewport: (viewport: Viewport) => void;\n readonly memory: () => RendererMemory;\n /** Releases the renderer and its drawing context. Called exactly once. */\n readonly dispose: () => void;\n /**\n * Settles when the renderer can draw, for renderers that start asynchronously (three's\n * `WebGPURenderer.init()`); the runtime waits for it before the first frame. Absent for\n * renderers ready at once.\n */\n readonly ready?: (() => Promise<void>) | undefined;\n};\n\n/** Creates a renderer. `create` may throw when the backend is unavailable. */\nexport type RendererFactory = {\n readonly create: () => SceneRenderer;\n /**\n * The renderer's shaded parts, given to the scene graphs it draws (the sky, shader\n * grids, contact shadows). A factory wrapping another keeps its kit (`...factory`).\n */\n readonly kit?: RenderKit | undefined;\n};\n\n/** A renderer that records calls instead of drawing. For headless tests. */\nexport type RecordingRenderer = SceneRenderer & {\n readonly renders: () => number;\n /** Every `configure` call, in order. */\n readonly configured: () => ReadonlyArray<RenderSettings>;\n readonly viewport: () => Viewport | undefined;\n readonly disposed: () => boolean;\n};\n\n/** A factory of recording renderers that remembers every renderer it created. */\nexport type RecordingRendererFactory = RendererFactory & {\n readonly created: () => ReadonlyArray<RecordingRenderer>;\n};\n\nconst createRecordingRenderer = (): RecordingRenderer => {\n let renders = 0;\n const configured: Array<RenderSettings> = [];\n let viewport: Viewport | undefined;\n let disposed = false;\n return {\n render: () => {\n renders++;\n },\n configure: (settings) => {\n configured.push(settings);\n },\n createTarget: () => {\n const texture = new Texture();\n return { texture, dispose: () => texture.dispose() };\n },\n createEnvironment: () => {\n const texture = new Texture();\n return { texture, dispose: () => texture.dispose() };\n },\n setViewport: (next) => {\n viewport = next;\n },\n memory: () => ({ geometries: 0, textures: 0 }),\n dispose: () => {\n disposed = true;\n },\n renders: () => renders,\n configured: () => configured,\n viewport: () => viewport,\n disposed: () => disposed,\n };\n};\n\n/** Creates a factory of recording renderers. */\nexport const recordingRendererFactory = (): RecordingRendererFactory => {\n const created: Array<RecordingRenderer> = [];\n return {\n create: () => {\n const renderer = createRecordingRenderer();\n created.push(renderer);\n return renderer;\n },\n created: () => created,\n };\n};\n",
|
|
31
|
+
"/**\n * The hosted three.js scene graph: applies diff operations to real three.js objects.\n *\n * `reconcile` is atomic: an invalid description is rejected before anything changes.\n * Objects keep their identity across updates; only a change of node kind replaces one.\n *\n * @module\n */\nimport {\n AmbientLight,\n Color,\n AnimationClip,\n AnimationMixer,\n type BufferGeometry,\n DirectionalLight,\n Group,\n GridHelper,\n HemisphereLight,\n Mesh,\n type Object3D,\n OrthographicCamera,\n PerspectiveCamera,\n PointLight,\n Scene,\n SpotLight,\n Vector3,\n} from 'three';\n\nimport { clipRunning, clipTime } from './animation.ts';\nimport { writeRotation } from './behaviours.ts';\nimport { type BodyCollision, type BodyContactForce, createBodyHost } from './bodies.ts';\nimport { type BodySource, instanceSources, nodeSource, placeObject } from './bodySources.ts';\nimport { renderSettings, scene as describeScene } from './build.ts';\nimport { type CameraMotion, createCameraMotion } from './cameraMotion.ts';\nimport type {\n AmbientLightNode,\n BorrowedNode,\n DirectionalLightNode,\n GridNode,\n HemisphereLightNode,\n GroupNode,\n Instance,\n InstancesNode,\n LabelNode,\n MaterialRef,\n ShaderGridNode,\n MeshNode,\n Camera as CameraDescription,\n PointLightNode,\n RenderSettings,\n SceneDescription,\n SceneNode,\n SpotLightNode,\n ContactShadows,\n Environment,\n Gestures,\n Overlay,\n Physics,\n Sky,\n Xr,\n XrSpace,\n RenderTexture,\n Vec3,\n View,\n ViewRect,\n} from './description.ts';\nimport { diff, type Field, type Op } from './diff.ts';\nimport { contactShadowsEquals, environmentEquals, overlaysEqual, skyEquals } from './equality.ts';\nimport { createInstances, fits, type HostInstances, writeInstances } from './instances.ts';\nimport type { HostedLabel, LabelEngine, LabelLayout } from './labels.ts';\nimport type { HostMaterial } from './materials.ts';\nimport {\n type Behaviour,\n type BehaviourPose,\n builtinBehaviours,\n createPose,\n resetPose,\n} from './motion.ts';\nimport type { BodyPose, PhysicsEngine } from './physics.ts';\nimport type { HostedShaderGrid, HostedSky, RenderKit } from './renderKit.ts';\nimport { createResourceStore, type ResourceStore } from './resources.ts';\nimport {\n type DescriptionError,\n emptyIndex,\n indexScene,\n type ParentKey,\n type SceneIndex,\n} from './sceneIndex.ts';\nimport { applyTween, startTween, type Tween } from './tween.ts';\n\n/** The mesh type the kernel hosts. */\nexport type HostMesh = Mesh<BufferGeometry, HostMaterial>;\n\ntype Entry =\n | { readonly _tag: 'Group'; node: GroupNode; readonly object: Group }\n | { readonly _tag: 'Mesh'; node: MeshNode; readonly object: HostMesh }\n // Mutable: growing past capacity swaps in a larger InstancedMesh under the same entry.\n | { readonly _tag: 'Instances'; node: InstancesNode; object: HostInstances }\n // `shown` is the lent object (or a clone of it) inside the wrapper, when one is lent.\n | {\n readonly _tag: 'Borrowed';\n node: BorrowedNode;\n readonly object: Group;\n shown: Object3D | undefined;\n player: Player | undefined;\n }\n // `hosted` is what the label engine drew, inside the wrapper; none without an engine.\n | {\n readonly _tag: 'Label';\n node: LabelNode;\n readonly object: Group;\n readonly hosted: HostedLabel | undefined;\n /** The material lent to the engine (`label({ material })`), held from the store. */\n material: HostMaterial | undefined;\n }\n | { readonly _tag: 'AmbientLight'; node: AmbientLightNode; readonly object: AmbientLight }\n | {\n readonly _tag: 'DirectionalLight';\n node: DirectionalLightNode;\n readonly object: DirectionalLight;\n }\n | { readonly _tag: 'PointLight'; node: PointLightNode; readonly object: PointLight }\n | { readonly _tag: 'SpotLight'; node: SpotLightNode; readonly object: SpotLight }\n | {\n readonly _tag: 'Grid';\n node: GridNode;\n /** Positions the grid; the lines inside are rebuilt when their shape changes. */\n readonly object: Group;\n helper: GridHelper;\n }\n // `hosted` is what the render kit drew; without a kit the grid is an empty group.\n | {\n readonly _tag: 'ShaderGrid';\n node: ShaderGridNode;\n readonly object: Object3D;\n readonly hosted: HostedShaderGrid | undefined;\n }\n | {\n readonly _tag: 'HemisphereLight';\n node: HemisphereLightNode;\n readonly object: HemisphereLight;\n };\n\n/** Entries with a transform: position, rotation, scale and transitions. */\n/** A clip playing on a borrowed object: its mixer, length and scene-time start. */\ntype Borrowing = Extract<Entry, { readonly _tag: 'Borrowed' }>;\n\ntype Player = {\n readonly mixer: AnimationMixer;\n readonly duration: number;\n readonly startedAt: number;\n};\n\n/** Descriptions with a transform. */\ntype PlacedNode = GroupNode | MeshNode | InstancesNode | BorrowedNode | LabelNode;\n\ntype Placed = Extract<\n Entry,\n { readonly _tag: 'Group' | 'Mesh' | 'Instances' | 'Borrowed' | 'Label' }\n>;\n\n/** Entries drawing a geometry with a material. */\ntype Surfaced = Extract<Entry, { readonly _tag: 'Mesh' | 'Instances' }>;\n\nconst isPlaced = (entry: Entry): entry is Placed =>\n entry._tag === 'Group' ||\n entry._tag === 'Mesh' ||\n entry._tag === 'Instances' ||\n entry._tag === 'Borrowed' ||\n entry._tag === 'Label';\n\nconst isSurfaced = (entry: Entry): entry is Surfaced =>\n entry._tag === 'Mesh' || entry._tag === 'Instances';\n\n/** A render texture as hosted: its id, size and the nested graph that draws it. */\nexport type HostedTexture = {\n readonly id: string;\n readonly graph: SceneGraph;\n readonly width: number;\n readonly height: number;\n};\n\n/** A view as hosted: its key, its camera and its rectangle in CSS pixels from the top left. */\nexport type HostedView = {\n readonly key: string;\n readonly camera: HostCamera;\n readonly area: {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n };\n};\n\nexport type ReconcileResult =\n | { readonly _tag: 'Applied'; readonly ops: ReadonlyArray<Op> }\n | { readonly _tag: 'Invalid'; readonly error: DescriptionError };\n\nexport type SceneGraphOptions = {\n /** A store shared with other graphs. When omitted the graph owns a private store. */\n readonly store?: ResourceStore;\n /** Behaviours nodes may name, in addition to the built-in ones (`float`). */\n readonly behaviours?: Readonly<Record<string, Behaviour>>;\n /** Simulates meshes with a `body` when the scene has `physics`; without it they stay put. */\n readonly physics?: PhysicsEngine | undefined;\n /** Draws `label` nodes (distance-field text); without it they are empty. */\n readonly labels?: LabelEngine | undefined;\n /**\n * The renderer's shaded parts (sky, shader grids, contact shadows); without it they are\n * not drawn. `webglKit` from `@opsydyn/effect-three/webgl` for three's WebGL renderer.\n */\n readonly kit?: RenderKit | undefined;\n};\n\nexport type SceneGraph = {\n readonly scene: Scene;\n /** The render kit the graph was made with, for the frame loop's contact shadows. */\n readonly kit: RenderKit | undefined;\n /** The active camera. Changing the description's camera kind replaces it. */\n readonly camera: HostCamera;\n /** The scene's views, fitted to the viewport; empty when `camera` fills the canvas. */\n readonly views: () => ReadonlyArray<HostedView>;\n /** Holds every camera's turning (`autoRotate`) still while a gesture is pressed. */\n readonly holdCameras: (held: boolean) => void;\n /**\n * Where turning has taken the camera of `view` (or, without one, the scene's camera),\n * when it has turned since its description: for an `AutoRotated` event.\n */\n readonly turned: (view: string | undefined) => Vec3 | undefined;\n /** Render textures, each a nested graph to draw into its texture (by the frame loop). */\n readonly renderTextures: () => ReadonlyArray<HostedTexture>;\n /** Whether the scene claims the pointer's gestures from the page. */\n readonly gestures: () => Gestures;\n /** Points to show HTML at; the frame loop places them after drawing. */\n readonly overlays: () => ReadonlyArray<Overlay>;\n /** Image-based lighting and background; the frame loop applies it. */\n readonly environment: () => Environment | null;\n /** Soft ground shadows; the frame loop draws them. */\n readonly contactShadows: () => ContactShadows | null;\n /** Collisions between bodies since the last call, for the frame loop to report. */\n readonly collisions: () => ReadonlyArray<BodyCollision>;\n /** Contact forces over their bodies' thresholds since the last call. */\n readonly contactForces: () => ReadonlyArray<BodyContactForce>;\n /** How the scene is presented immersively, for the host; `null` if it never is. */\n readonly xr: () => Xr | null;\n /** Keys of the nodes whose bounds the frame loop reports. */\n readonly measured: () => ReadonlyArray<string>;\n /** A label's laid-out size, once its engine has laid it out. */\n readonly labelLayout: (key: string) => LabelLayout | undefined;\n /**\n * Places the groups that follow tracked spaces where `locate` says each space is (in the\n * scene), hiding those it cannot find. A presenting session calls it every frame, and\n * once with nothing found when it ends.\n */\n readonly follow: (locate: (space: XrSpace) => BodyPose | undefined) => void;\n readonly store: ResourceStore;\n /** Diffs against the last applied description and applies the result. */\n readonly reconcile: (next: SceneDescription) => ReconcileResult;\n /** Advances behaviours to `elapsedSeconds` of scene time. Allocation-free. */\n readonly tick: (elapsedSeconds: number) => void;\n /** Scene time of the last `tick`. */\n readonly elapsedSeconds: () => number;\n /**\n * The scene's current render settings. A new value (by reference) means they changed,\n * so the frame loop can reconfigure the renderer without comparing fields.\n */\n readonly renderSettings: () => RenderSettings;\n /**\n * While not animating (reduced motion, a paused debugger), transitions land at once and\n * any in flight finish, because frozen scene time would otherwise strand them mid-way.\n */\n readonly setAnimating: (animating: boolean) => void;\n /**\n * Whether the next frame would draw something new: after any change (reconcile, resize,\n * animation toggle, a shared resource changed elsewhere) or while something animates.\n */\n readonly needsFrame: () => boolean;\n /** Marks the current state as drawn. The frame loop calls it after each render. */\n readonly drawn: () => void;\n /** Calls `listener` whenever the graph changes in a way that needs a frame. */\n readonly onInvalidated: (listener: () => void) => () => void;\n /** The hosted object for a key. */\n readonly object: (key: string) => Object3D | undefined;\n /** The key of a hosted object. */\n readonly keyOf: (object: Object3D) => string | undefined;\n /** The key of instance `instanceId` of a hosted instances node, if it has one. */\n readonly instanceKeyOf: (object: Object3D, instanceId: number) => string | undefined;\n /**\n * Hosted objects of interactive meshes and groups (picking descends into groups). The\n * array is cached until the set changes and is mutable only because three's\n * `Raycaster.intersectObjects` requires it: don't modify it.\n */\n readonly interactiveObjects: () => Array<Object3D>;\n /** Fits the camera to a viewport of `width` by `height` CSS pixels. */\n readonly resize: (width: number, height: number) => void;\n /** The last `resize`, in CSS pixels. `1 × 1` until the first resize. */\n readonly viewport: () => { readonly width: number; readonly height: number };\n /** Removes every node and releases its resources. Disposes the store if the graph owns it. */\n readonly dispose: () => void;\n};\n\nconst writeVec3 = (\n target: { set: (x: number, y: number, z: number) => unknown },\n v: Vec3,\n): void => {\n target.set(v[0], v[1], v[2]);\n};\n\ntype ShadowFields = {\n readonly castShadow: boolean;\n readonly shadowMapSize: number;\n readonly shadowBias: number;\n};\n\n/** Writes a light's shadow settings. A new map size drops the old map so three reallocates it. */\nconst writeShadow = (\n light: DirectionalLight | PointLight | SpotLight,\n fields: ShadowFields,\n): void => {\n light.castShadow = fields.castShadow;\n light.shadow.bias = fields.shadowBias;\n if (light.shadow.mapSize.x !== fields.shadowMapSize) {\n light.shadow.mapSize.set(fields.shadowMapSize, fields.shadowMapSize);\n light.shadow.map?.dispose();\n light.shadow.map = null;\n }\n};\n\nconst writeDirectionalLight = (light: DirectionalLight, node: DirectionalLightNode): void => {\n light.color.setHex(node.color);\n light.intensity = node.intensity;\n writeVec3(light.position, node.position);\n writeShadow(light, node);\n const camera = light.shadow.camera;\n if (camera.right !== node.shadowArea) {\n camera.left = -node.shadowArea;\n camera.right = node.shadowArea;\n camera.top = node.shadowArea;\n camera.bottom = -node.shadowArea;\n camera.updateProjectionMatrix();\n }\n};\n\n// Lights are cheap to write in full, so an update rewrites every field from the node.\nconst writePointLight = (light: PointLight, node: PointLightNode): void => {\n light.color.setHex(node.color);\n light.intensity = node.intensity;\n writeVec3(light.position, node.position);\n light.distance = node.distance;\n light.decay = node.decay;\n writeShadow(light, node);\n};\n\nconst writeSpotLight = (light: SpotLight, node: SpotLightNode): void => {\n light.color.setHex(node.color);\n light.intensity = node.intensity;\n writeVec3(light.position, node.position);\n light.distance = node.distance;\n light.angle = node.angle;\n light.penumbra = node.penumbra;\n light.decay = node.decay;\n writeShadow(light, node);\n // The target is not in the scene graph (it is world space), so three never updates its\n // matrix: do it here, once per change.\n writeVec3(light.target.position, node.target);\n light.target.updateMatrixWorld();\n};\n\n/** Lines for a grid node: three.js's `GridHelper` takes its shape when constructed. */\nconst gridLines = (node: GridNode): GridHelper =>\n new GridHelper(node.size, node.divisions, node.centerColor, node.color);\n\nconst disposeGridLines = (lines: GridHelper): void => {\n lines.removeFromParent();\n lines.dispose();\n};\n\nconst writeHemisphereLight = (light: HemisphereLight, node: HemisphereLightNode): void => {\n light.color.setHex(node.color);\n light.groundColor.setHex(node.groundColor);\n light.intensity = node.intensity;\n writeVec3(light.position, node.position);\n};\n\n/** The three.js camera kinds the kernel hosts. */\nexport type HostCamera = PerspectiveCamera | OrthographicCamera;\n\ntype Viewport = { readonly width: number; readonly height: number };\n\n/**\n * Fits a camera's projection to the viewport. Perspective cameras take its aspect ratio;\n * orthographic frustums span it in CSS pixels, scaled by `zoom` (as React Three Fiber's\n * `updateCamera` in `core/utils.tsx` at `d74622e`).\n */\nconst fitCamera = (camera: HostCamera, viewport: Viewport): void => {\n if (camera instanceof OrthographicCamera) {\n camera.left = viewport.width / -2;\n camera.right = viewport.width / 2;\n camera.top = viewport.height / 2;\n camera.bottom = viewport.height / -2;\n } else {\n camera.aspect = viewport.width / viewport.height;\n }\n camera.updateProjectionMatrix();\n};\n\n/** A camera of the description's kind: `current` when it already is one, else a new one. */\nconst cameraFor = (current: HostCamera, description: CameraDescription): HostCamera => {\n if (description._tag === 'Perspective') {\n return current instanceof PerspectiveCamera ? current : new PerspectiveCamera();\n }\n return current instanceof OrthographicCamera ? current : new OrthographicCamera();\n};\n\n/** Applies the lens: field of view, near and far. Position, aim and zoom are the pose. */\nconst applyLens = (camera: HostCamera, description: CameraDescription): void => {\n if (camera instanceof PerspectiveCamera && description._tag === 'Perspective') {\n camera.fov = description.fov;\n }\n camera.near = description.near;\n camera.far = description.far;\n};\n\nconst noInstances: ReadonlyArray<Instance> = [];\n\nconst emptyScene = describeScene({});\n\n/** Creates an empty scene graph. */\nexport const createSceneGraph = (options: SceneGraphOptions = {}): SceneGraph => {\n const store = options.store ?? createResourceStore();\n const ownsStore = options.store === undefined;\n const scene = new Scene();\n let camera: HostCamera = new PerspectiveCamera();\n let views: ReadonlyArray<HostedView> = [];\n const textureGraphs = new Map<\n string,\n { readonly graph: SceneGraph; description: RenderTexture }\n >();\n let textureList: ReadonlyArray<HostedTexture> = [];\n let viewDescriptions: ReadonlyArray<View> = [];\n let gestures: Gestures = emptyScene.gestures;\n let overlayList: ReadonlyArray<Overlay> = emptyScene.overlays;\n let environmentDescription: Environment | null = emptyScene.environment;\n let skyDescription: Sky | null = emptyScene.sky;\n let contactDescription: ContactShadows | null = emptyScene.contactShadows;\n let xrDescription: Xr | null = emptyScene.xr;\n let measured: ReadonlyArray<string> = emptyScene.measure;\n let hostedSky: HostedSky | undefined;\n\n /**\n * Shows, updates or removes the sky, drawn by the render kit (none without one). It\n * belongs to the scene, never picked.\n */\n const applySky = (description: Sky | null): void => {\n if (description === null) {\n removeSky();\n return;\n }\n if (hostedSky === undefined) {\n hostedSky = options.kit?.sky();\n if (hostedSky !== undefined) scene.add(hostedSky.object);\n }\n hostedSky?.update(description);\n };\n\n function removeSky(): void {\n if (hostedSky === undefined) return;\n hostedSky.object.removeFromParent();\n hostedSky.dispose();\n hostedSky = undefined;\n }\n const cameraMotion = createCameraMotion();\n /** Each view's camera motion, by the view's key. */\n const viewMotions = new Map<string, CameraMotion>();\n const viewsMoving = (): boolean => {\n for (const motion of viewMotions.values()) if (motion.moving()) return true;\n return false;\n };\n const bodyHost = createBodyHost(options.physics, scene);\n\n /** Every body the hosted nodes describe: one per bodied node, one per bodied instance. */\n function* bodySources(): Generator<BodySource> {\n for (const [key, entry] of entries) {\n if (entry._tag === 'Mesh' || entry._tag === 'Group' || entry._tag === 'Borrowed') {\n const source = nodeSource(key, entry.node, entry.object);\n if (source !== undefined) yield source;\n } else if (entry._tag === 'Instances') {\n yield* instanceSources(key, entry.node, entry, entry.object);\n }\n }\n }\n let physicsDescription: Physics | null = null;\n\n /** The view's rectangle in CSS pixels, from its fractional rect and the viewport. */\n const areaOf = (rect: ViewRect): HostedView['area'] => ({\n x: rect.x * viewport.width,\n y: rect.y * viewport.height,\n width: Math.max(1, rect.width * viewport.width),\n height: Math.max(1, rect.height * viewport.height),\n });\n\n /** Hosts one described view, reusing `previous` when its kind is unchanged. */\n const hostView = (description: View, previous: HostCamera | undefined): HostedView => {\n const hostedCamera = cameraFor(previous ?? new PerspectiveCamera(), description.camera);\n applyLens(hostedCamera, description.camera);\n const motion = viewMotions.get(description.key) ?? createCameraMotion();\n viewMotions.set(description.key, motion);\n // As the scene's camera: a new kind of camera has nothing on screen to travel from.\n motion.aim(hostedCamera, description.camera, elapsed, hostedCamera !== previous || !animating);\n const area = areaOf(description.rect);\n fitCamera(hostedCamera, area);\n return { key: description.key, camera: hostedCamera, area };\n };\n\n /** Hosts the described views, reusing each key's camera when its kind is unchanged. */\n const hostViews = (described: ReadonlyArray<View>): void => {\n const previous = new Map(views.map((hosted) => [hosted.key, hosted.camera]));\n viewDescriptions = described;\n views = described.map((description) => hostView(description, previous.get(description.key)));\n for (const key of viewMotions.keys()) {\n if (!described.some((description) => description.key === key)) viewMotions.delete(key);\n }\n };\n const entries = new Map<string, Entry>();\n const keys = new WeakMap<Object3D, string>();\n const spinning = new Set<Entry>();\n const playing = new Set<Borrowing>();\n const registry: Readonly<Record<string, Behaviour>> = {\n ...builtinBehaviours,\n ...options.behaviours,\n };\n const knownBehaviours: ReadonlySet<string> = new Set(Object.keys(registry));\n // Each behaving entry keeps the pose last applied, so it can be taken off again.\n const behaving = new Map<\n Placed,\n { readonly behaviour: Behaviour; readonly pose: BehaviourPose }\n >();\n const moving = new Map<Entry, Tween>();\n const reparented = new Set<Entry>();\n const worldPosition = new Vector3();\n const interactive = new Set<Object3D>();\n let interactiveList: Array<Object3D> | undefined;\n let index: SceneIndex = emptyIndex;\n let elapsed = 0;\n let animating = true;\n let dirty = true;\n const invalidationListeners = new Set<() => void>();\n const invalidate = (): void => {\n dirty = true;\n for (const listener of invalidationListeners) listener();\n };\n let settings: RenderSettings = renderSettings();\n let viewport = { width: 1, height: 1 };\n\n const unsubscribeGeometry = store.onGeometryReplaced(({ previous, next }) => {\n for (const entry of entries.values()) {\n if (isSurfaced(entry) && entry.object.geometry === previous) entry.object.geometry = next;\n }\n });\n const unsubscribeShared = store.onSharedChanged(invalidate);\n const unsubscribeMaterial = store.onMaterialReplaced(({ previous, next }) => {\n for (const entry of entries.values()) {\n if (isSurfaced(entry) && entry.object.material === previous) entry.object.material = next;\n if (entry._tag === 'Label' && entry.material === previous) {\n entry.material = next;\n entry.hosted?.setMaterial(next);\n }\n }\n });\n\n const trackInteractive = (object: Object3D, enabled: boolean): void => {\n const changed = enabled ? !interactive.has(object) : interactive.has(object);\n if (!changed) return;\n if (enabled) interactive.add(object);\n else interactive.delete(object);\n interactiveList = undefined;\n };\n\n const trackRotation = (entry: Entry, node: PlacedNode): void => {\n writeRotation(entry.object.rotation, node.rotation, elapsed);\n if (node.rotation._tag === 'Spin') spinning.add(entry);\n else spinning.delete(entry);\n };\n\n const build = (node: SceneNode): Entry => {\n switch (node._tag) {\n case 'Group': {\n const entry: Entry = { _tag: 'Group', node, object: new Group() };\n writeVec3(entry.object.position, node.position);\n writeVec3(entry.object.scale, node.scale);\n trackRotation(entry, node);\n trackBehaviour(entry, node);\n trackInteractive(entry.object, node.interactive);\n // A group following a tracked space shows only once the space is found.\n if (node.follow !== null) entry.object.visible = false;\n return entry;\n }\n case 'Mesh': {\n const object: HostMesh = new Mesh(\n store.acquireGeometry(node.geometry),\n store.acquireMaterial(node.material),\n );\n const entry: Entry = { _tag: 'Mesh', node, object };\n writeVec3(object.position, node.position);\n writeVec3(object.scale, node.scale);\n trackRotation(entry, node);\n trackBehaviour(entry, node);\n trackInteractive(object, node.interactive);\n object.castShadow = node.castShadow;\n object.receiveShadow = node.receiveShadow;\n return entry;\n }\n case 'Instances': {\n const object = createInstances(\n store.acquireGeometry(node.geometry),\n store.acquireMaterial(node.material),\n node.instances.length,\n );\n writeInstances(object, noInstances, node.instances);\n const entry: Entry = { _tag: 'Instances', node, object };\n writeVec3(object.position, node.position);\n writeVec3(object.scale, node.scale);\n trackRotation(entry, node);\n trackBehaviour(entry, node);\n trackInteractive(object, node.interactive);\n object.castShadow = node.castShadow;\n object.receiveShadow = node.receiveShadow;\n return entry;\n }\n case 'Borrowed': {\n const entry: Borrowing = {\n _tag: 'Borrowed',\n node,\n object: new Group(),\n shown: undefined,\n player: undefined,\n };\n writeVec3(entry.object.position, node.position);\n writeVec3(entry.object.scale, node.scale);\n trackRotation(entry, node);\n trackBehaviour(entry, node);\n trackInteractive(entry.object, node.interactive);\n showLoan(entry);\n return entry;\n }\n case 'Label': {\n // A renderer that cannot draw the engine's labels (WebGPU and troika) gets none.\n const hosted =\n options.kit?.drawsLabels === false ? undefined : options.labels?.create(node, invalidate);\n const material = node.material === null ? undefined : store.acquireMaterial(node.material);\n hosted?.setMaterial(material);\n const entry: Entry = { _tag: 'Label', node, object: new Group(), hosted, material };\n if (hosted !== undefined) entry.object.add(hosted.object);\n writeVec3(entry.object.position, node.position);\n writeVec3(entry.object.scale, node.scale);\n trackRotation(entry, node);\n trackBehaviour(entry, node);\n trackInteractive(entry.object, node.interactive);\n return entry;\n }\n case 'AmbientLight':\n return { _tag: 'AmbientLight', node, object: new AmbientLight(node.color, node.intensity) };\n case 'DirectionalLight': {\n const object = new DirectionalLight();\n writeDirectionalLight(object, node);\n return { _tag: 'DirectionalLight', node, object };\n }\n case 'PointLight': {\n const object = new PointLight();\n writePointLight(object, node);\n return { _tag: 'PointLight', node, object };\n }\n case 'SpotLight': {\n const object = new SpotLight();\n writeSpotLight(object, node);\n return { _tag: 'SpotLight', node, object };\n }\n case 'Grid': {\n const object = new Group();\n const helper = gridLines(node);\n object.add(helper);\n writeVec3(object.position, node.position);\n return { _tag: 'Grid', node, object, helper };\n }\n case 'ShaderGrid': {\n const hosted = options.kit?.shaderGrid(node);\n return { _tag: 'ShaderGrid', node, object: hosted?.object ?? new Group(), hosted };\n }\n case 'HemisphereLight': {\n const object = new HemisphereLight();\n writeHemisphereLight(object, node);\n return { _tag: 'HemisphereLight', node, object };\n }\n }\n };\n\n /**\n * Shows what is lent under the entry's id: the object itself, or a clone when another\n * borrowed node already shows it (an object can have only one parent).\n */\n const showLoan = (entry: Borrowing): void => {\n stopPlayer(entry);\n entry.shown?.removeFromParent();\n entry.shown = undefined;\n const lent = store.lent(entry.node.id);\n if (lent === undefined) return;\n const shown = lent.parent === null ? lent : lent.clone();\n entry.object.add(shown);\n entry.shown = shown;\n startPlayer(entry);\n };\n\n const stopPlayer = (entry: Borrowing): void => {\n if (entry.player === undefined) return;\n entry.player.mixer.stopAllAction();\n if (entry.shown !== undefined) entry.player.mixer.uncacheRoot(entry.shown);\n entry.player = undefined;\n playing.delete(entry);\n };\n\n /** Starts the node's clip on what it shows, from now in scene time, if both exist. */\n const startPlayer = (entry: Borrowing): void => {\n stopPlayer(entry);\n const animation = entry.node.animation;\n const shown = entry.shown;\n if (animation === null || shown === undefined) return;\n const clip = AnimationClip.findByName(shown.animations, animation.clip);\n if (clip === null) return;\n const mixer = new AnimationMixer(shown);\n mixer.clipAction(clip).play();\n entry.player = { mixer, duration: clip.duration, startedAt: elapsed };\n playing.add(entry);\n pose(entry);\n };\n\n /** Shows the clip's pose for the current scene time. */\n const pose = (entry: Borrowing): void => {\n const animation = entry.node.animation;\n if (entry.player === undefined || animation === null) return;\n const since = elapsed - entry.player.startedAt;\n entry.player.mixer.setTime(clipTime(animation, entry.player.duration, since));\n };\n\n /** Whether any clip still changes its pose, so frames are needed. */\n const clipsRunning = (): boolean => {\n for (const entry of playing) {\n const animation = entry.node.animation;\n if (entry.player === undefined || animation === null) continue;\n const since = elapsed - entry.player.startedAt;\n if (clipRunning(animation, entry.player.duration, since)) return true;\n }\n return false;\n };\n\n /** Re-applies owned materials that use a texture whose loan changed. */\n const refreshTexture = (id: string): void => {\n for (const entry of entries.values()) {\n if (!isSurfaced(entry)) continue;\n const material = entry.node.material;\n if (material._tag !== 'SharedMaterial' && 'map' in material && material.map === id) {\n store.updateOwnedMaterial(entry.object.material, material);\n }\n }\n };\n\n /** Rebuilds owned text whose font's loan changed; shared text the store rebuilds. */\n const refreshFont = (id: string): void => {\n for (const entry of entries.values()) {\n if (!isSurfaced(entry)) continue;\n const geometry = entry.node.geometry;\n if (geometry._tag === 'Text' && geometry.font === id) {\n store.releaseGeometry(geometry, entry.object.geometry);\n entry.object.geometry = store.acquireGeometry(geometry);\n }\n }\n };\n\n /** Shows a newly lent (or withdrawn) geometry on the meshes that name it. */\n const refreshLentGeometry = (id: string): void => {\n for (const entry of entries.values()) {\n if (!isSurfaced(entry)) continue;\n const geometry = entry.node.geometry;\n if (geometry._tag === 'LentGeometry' && geometry.id === id) {\n entry.object.geometry = store.acquireGeometry(geometry);\n }\n }\n };\n\n const unsubscribeLoans = store.onLoanChanged((loan) => {\n if (loan.kind === 'texture') refreshTexture(loan.id);\n else if (loan.kind === 'font') refreshFont(loan.id);\n else if (loan.kind === 'geometry') refreshLentGeometry(loan.id);\n else {\n for (const entry of entries.values()) {\n if (entry._tag === 'Borrowed' && entry.node.id === loan.id) showLoan(entry);\n }\n }\n // A model or font arriving changes what bodies are made of: remake their colliders.\n if (loan.kind !== 'texture') bodyHost.sync(physicsDescription, bodySources());\n invalidate();\n });\n\n /** Removes the last behaviour pose from the object, leaving its base transform. */\n const liftPose = (entry: Entry): void => {\n const motion = isPlaced(entry) ? behaving.get(entry) : undefined;\n if (motion === undefined) return;\n entry.object.position.sub(motion.pose.offset);\n const { x, y, z } = motion.pose.scale;\n if (x !== 0 && y !== 0 && z !== 0) entry.object.scale.divide(motion.pose.scale);\n resetPose(motion.pose);\n };\n\n /** Starts, changes or stops the node's behaviour. */\n const trackBehaviour = (entry: Placed, node: PlacedNode): void => {\n liftPose(entry);\n behaving.delete(entry);\n if (node.behaviour === null) {\n trackRotation(entry, node);\n return;\n }\n const behaviour = registry[node.behaviour.name];\n if (behaviour !== undefined) behaving.set(entry, { behaviour, pose: createPose() });\n };\n\n /** Composes the node's behaviour pose on top of its base transform for this frame. */\n const applyBehaviour = (\n motion: { readonly behaviour: Behaviour; readonly pose: BehaviourPose },\n entry: Placed,\n ): void => {\n const node = entry.node;\n if (node.behaviour === null) return;\n const object = entry.object;\n // Tweens have written this frame's base already; otherwise the base is the target.\n if (!moving.has(entry)) {\n writeVec3(object.position, node.position);\n writeVec3(object.scale, node.scale);\n }\n writeRotation(object.rotation, node.rotation, elapsed);\n resetPose(motion.pose);\n motion.behaviour(motion.pose, elapsed, node.behaviour.params);\n object.position.add(motion.pose.offset);\n object.scale.multiply(motion.pose.scale);\n object.rotation.x += motion.pose.rotation.x;\n object.rotation.y += motion.pose.rotation.y;\n object.rotation.z += motion.pose.rotation.z;\n };\n\n const release = (entry: Entry): void => {\n if (isPlaced(entry)) behaving.delete(entry);\n spinning.delete(entry);\n moving.delete(entry);\n reparented.delete(entry);\n trackInteractive(entry.object, false);\n if (isSurfaced(entry)) {\n store.releaseGeometry(entry.node.geometry, entry.object.geometry);\n store.releaseMaterial(entry.node.material, entry.object.material);\n }\n // Frees the instance buffers on the GPU; geometry and material belong to the store.\n if (entry._tag === 'Instances') entry.object.dispose();\n // A grid's lines are its own.\n if (entry._tag === 'Grid') disposeGridLines(entry.helper);\n if (entry._tag === 'ShaderGrid') entry.hosted?.dispose();\n if (entry._tag === 'Label') {\n entry.hosted?.dispose();\n if (entry.node.material !== null && entry.material !== undefined) {\n store.releaseMaterial(entry.node.material, entry.material);\n }\n }\n // A borrowed object belongs to the application: detach it, never dispose it.\n if (entry._tag === 'Borrowed') {\n stopPlayer(entry);\n entry.shown?.removeFromParent();\n entry.shown = undefined;\n }\n };\n\n /**\n * Moves an instances entry into a larger InstancedMesh: same place in the tree, same\n * transform and key, geometry and material carried over, every slot rewritten.\n */\n const growInstances = (\n entry: Extract<Entry, { readonly _tag: 'Instances' }>,\n next: InstancesNode,\n ): void => {\n const old = entry.object;\n const grown = createInstances(old.geometry, old.material, next.instances.length);\n grown.position.copy(old.position);\n grown.quaternion.copy(old.quaternion);\n grown.scale.copy(old.scale);\n grown.castShadow = old.castShadow;\n grown.receiveShadow = old.receiveShadow;\n grown.name = old.name;\n const parent = old.parent;\n if (parent !== null) {\n const slot = parent.children.indexOf(old);\n old.removeFromParent();\n parent.add(grown);\n parent.children.pop();\n parent.children.splice(slot, 0, grown);\n }\n const key = keys.get(old);\n keys.delete(old);\n if (key !== undefined) keys.set(grown, key);\n const wasInteractive = interactive.has(old);\n trackInteractive(old, false);\n trackInteractive(grown, wasInteractive);\n // Keep each slot as it is shown (a simulated pose, say) and write only what changed.\n const kept = Math.min(entry.node.instances.length, next.instances.length);\n grown.instanceMatrix.array.set(old.instanceMatrix.array.subarray(0, kept * 16));\n if (old.instanceColor !== null && grown.instanceColor !== null) {\n grown.instanceColor.array.set(old.instanceColor.array.subarray(0, kept * 3));\n }\n old.dispose();\n entry.object = grown;\n writeInstances(grown, entry.node.instances.slice(0, kept), next.instances);\n };\n\n /**\n * Moves the object towards a new position and scale: at once for `Instant` or while not\n * animating, otherwise by restarting the tween from the current rendered pose at the last\n * frame's time.\n */\n const retarget = (entry: Entry, node: PlacedNode): void => {\n liftPose(entry);\n if (!animating || node.transition._tag === 'Instant') {\n moving.delete(entry);\n writeVec3(entry.object.position, node.position);\n writeVec3(entry.object.scale, node.scale);\n return;\n }\n moving.set(entry, startTween(entry.object, node, elapsed, node.transition));\n };\n\n const movesTransform = (entry: Entry, fields: ReadonlyArray<Field>): boolean =>\n fields.includes('position') ||\n fields.includes('scale') ||\n (fields.includes('transition') && moving.has(entry));\n\n /** Lends a label its next material: updated in place when both are its own, as a mesh's. */\n const relendLabelMaterial = (\n entry: Extract<Entry, { readonly _tag: 'Label' }>,\n next: MaterialRef | null,\n ): void => {\n const prev = entry.node.material;\n if (\n prev !== null &&\n next !== null &&\n entry.material !== undefined &&\n prev._tag !== 'SharedMaterial' &&\n next._tag !== 'SharedMaterial' &&\n store.updateOwnedMaterial(entry.material, next)\n ) {\n return;\n }\n if (prev !== null && entry.material !== undefined) store.releaseMaterial(prev, entry.material);\n entry.material = next === null ? undefined : store.acquireMaterial(next);\n entry.hosted?.setMaterial(entry.material);\n };\n\n const update = (entry: Entry, next: SceneNode, fields: ReadonlyArray<Field>): void => {\n if (entry._tag === 'Instances' && next._tag === 'Instances' && fields.includes('instances')) {\n if (fits(entry.object, next.instances.length)) {\n writeInstances(entry.object, entry.node.instances, next.instances);\n } else {\n growInstances(entry, next);\n }\n }\n if (\n (entry._tag === 'Mesh' && next._tag === 'Mesh') ||\n (entry._tag === 'Instances' && next._tag === 'Instances')\n ) {\n const prev = entry.node;\n const mesh = entry.object;\n for (const field of fields) {\n if (field === 'geometry') {\n store.releaseGeometry(prev.geometry, mesh.geometry);\n mesh.geometry = store.acquireGeometry(next.geometry);\n } else if (field === 'material') {\n const updatedInPlace =\n prev.material._tag !== 'SharedMaterial' &&\n next.material._tag !== 'SharedMaterial' &&\n store.updateOwnedMaterial(mesh.material, next.material);\n if (!updatedInPlace) {\n store.releaseMaterial(prev.material, mesh.material);\n mesh.material = store.acquireMaterial(next.material);\n }\n }\n }\n entry.node = next;\n if (movesTransform(entry, fields)) retarget(entry, next);\n if (fields.includes('rotation')) trackRotation(entry, next);\n if (fields.includes('behaviour')) trackBehaviour(entry, next);\n if (fields.includes('interactive')) trackInteractive(mesh, next.interactive);\n mesh.castShadow = next.castShadow;\n mesh.receiveShadow = next.receiveShadow;\n return;\n }\n if (entry._tag === 'Borrowed' && next._tag === 'Borrowed') {\n entry.node = next;\n if (movesTransform(entry, fields)) retarget(entry, next);\n if (fields.includes('rotation')) trackRotation(entry, next);\n if (fields.includes('behaviour')) trackBehaviour(entry, next);\n if (fields.includes('interactive')) trackInteractive(entry.object, next.interactive);\n if (fields.includes('id')) showLoan(entry);\n else if (fields.includes('animation')) startPlayer(entry);\n return;\n }\n if (entry._tag === 'Label' && next._tag === 'Label') {\n if (fields.includes('material')) relendLabelMaterial(entry, next.material);\n entry.node = next;\n if (movesTransform(entry, fields)) retarget(entry, next);\n if (fields.includes('rotation')) trackRotation(entry, next);\n if (fields.includes('behaviour')) trackBehaviour(entry, next);\n if (fields.includes('interactive')) trackInteractive(entry.object, next.interactive);\n if (fields.includes('text')) entry.hosted?.update(next);\n return;\n }\n if (entry._tag === 'Group' && next._tag === 'Group') {\n entry.node = next;\n if (movesTransform(entry, fields)) retarget(entry, next);\n if (fields.includes('rotation')) trackRotation(entry, next);\n if (fields.includes('behaviour')) trackBehaviour(entry, next);\n if (fields.includes('interactive')) trackInteractive(entry.object, next.interactive);\n if (fields.includes('follow')) {\n // Back to its own transform, or hidden until the new space is found.\n entry.object.visible = next.follow === null;\n if (next.follow === null) {\n writeVec3(entry.object.position, next.position);\n trackRotation(entry, next);\n }\n }\n return;\n }\n if (entry._tag === 'AmbientLight' && next._tag === 'AmbientLight') {\n entry.object.color.setHex(next.color);\n entry.object.intensity = next.intensity;\n entry.node = next;\n return;\n }\n if (entry._tag === 'DirectionalLight' && next._tag === 'DirectionalLight') {\n writeDirectionalLight(entry.object, next);\n entry.node = next;\n return;\n }\n if (entry._tag === 'PointLight' && next._tag === 'PointLight') {\n writePointLight(entry.object, next);\n entry.node = next;\n return;\n }\n if (entry._tag === 'SpotLight' && next._tag === 'SpotLight') {\n writeSpotLight(entry.object, next);\n entry.node = next;\n return;\n }\n if (entry._tag === 'HemisphereLight' && next._tag === 'HemisphereLight') {\n writeHemisphereLight(entry.object, next);\n entry.node = next;\n return;\n }\n if (entry._tag === 'ShaderGrid' && next._tag === 'ShaderGrid') {\n entry.hosted?.update(entry.node, next);\n entry.node = next;\n return;\n }\n if (entry._tag === 'Grid' && next._tag === 'Grid') {\n writeVec3(entry.object.position, next.position);\n if (fields.some((field) => field !== 'position')) {\n disposeGridLines(entry.helper);\n entry.helper = gridLines(next);\n entry.object.add(entry.helper);\n }\n entry.node = next;\n return;\n }\n throw new Error(`effect-three: update kind mismatch for \"${next.key}\"`);\n };\n\n const parentObject = (parent: ParentKey): Object3D => {\n if (parent === null) return scene;\n const entry = entries.get(parent);\n if (entry === undefined) throw new Error(`effect-three: missing parent \"${parent}\"`);\n return entry.object;\n };\n\n const register = (key: string, entry: Entry): void => {\n entries.set(key, entry);\n entry.object.name = key;\n keys.set(entry.object, key);\n };\n\n const apply = (op: Op): void => {\n switch (op._tag) {\n case 'SetCamera': {\n const previous = camera;\n camera = cameraFor(camera, op.camera);\n applyLens(camera, op.camera);\n // A new kind of camera has nothing on screen to travel from.\n cameraMotion.aim(camera, op.camera, elapsed, camera !== previous || !animating);\n fitCamera(camera, viewport);\n return;\n }\n case 'SetRenderSettings':\n settings = op.settings;\n return;\n case 'SetViews':\n hostViews(op.views);\n return;\n case 'DefineResources':\n store.define(op.resources);\n return;\n case 'Create': {\n const entry = build(op.node);\n register(op.node.key, entry);\n parentObject(op.parent).add(entry.object);\n return;\n }\n case 'Replace': {\n const old = entries.get(op.node.key);\n if (old === undefined) throw new Error(`effect-three: missing node \"${op.node.key}\"`);\n const entry = build(op.node);\n const target = parentObject(op.parent);\n // Children follow their parent key. Later Move/Remove ops settle any that leave.\n // Copy first: add() removes each child from the array being iterated.\n for (const child of old.object.children.slice()) entry.object.add(child);\n const position = old.object.parent === target ? target.children.indexOf(old.object) : -1;\n old.object.removeFromParent();\n target.add(entry.object);\n if (position >= 0) {\n target.children.pop();\n target.children.splice(position, 0, entry.object);\n }\n release(old);\n keys.delete(old.object);\n register(op.node.key, entry);\n return;\n }\n case 'Move': {\n const entry = entries.get(op.key);\n if (entry === undefined) throw new Error(`effect-three: missing node \"${op.key}\"`);\n const target = parentObject(op.parent);\n if (isPlaced(entry)) {\n // Keep the world position across the move; settle() then takes the node to its\n // new local position, instantly or along its transition.\n entry.object.getWorldPosition(worldPosition);\n target.add(entry.object);\n target.updateWorldMatrix(true, false);\n entry.object.position.copy(target.worldToLocal(worldPosition));\n reparented.add(entry);\n } else {\n target.add(entry.object);\n }\n return;\n }\n case 'Update': {\n const entry = entries.get(op.node.key);\n if (entry === undefined) throw new Error(`effect-three: missing node \"${op.node.key}\"`);\n update(entry, op.node, op.fields);\n return;\n }\n case 'Remove': {\n const entry = entries.get(op.key);\n if (entry === undefined) return;\n entry.object.removeFromParent();\n release(entry);\n entries.delete(op.key);\n keys.delete(entry.object);\n return;\n }\n case 'Order': {\n const parent = parentObject(op.parent);\n const ordered: Array<Object3D> = [];\n for (const key of op.keys) {\n const entry = entries.get(key);\n if (entry !== undefined) ordered.push(entry.object);\n }\n const managed = new Set(ordered);\n const unmanaged = parent.children.filter((child) => !managed.has(child));\n parent.children.splice(0, parent.children.length, ...ordered, ...unmanaged);\n return;\n }\n }\n };\n\n /** The scene a render texture draws: its camera and nodes, with the parent's resources. */\n const textureScene = (texture: RenderTexture, parent: SceneDescription): SceneDescription => ({\n camera: texture.camera,\n gestures: 'page',\n views: [],\n renderTextures: [],\n overlays: [],\n environment: null,\n sky: null,\n contactShadows: null,\n physics: null,\n xr: null,\n measure: [],\n render: parent.render,\n resources: parent.resources,\n children: texture.children,\n });\n\n /** A hosted render texture as the loop sees it; none if it is not hosted. */\n function hostedTexture(texture: RenderTexture): ReadonlyArray<HostedTexture> {\n const hosted = textureGraphs.get(texture.id);\n if (hosted === undefined) return [];\n return [{ id: texture.id, graph: hosted.graph, width: texture.width, height: texture.height }];\n }\n\n /**\n * Brings the hosted render textures in line with the description: nested graphs on the\n * same store, created, reconciled or disposed. Returns their operations.\n */\n const syncTextures = (next: SceneDescription): ReadonlyArray<Op> => {\n const ops: Array<Op> = [];\n const kept = new Set<string>();\n for (const texture of next.renderTextures) {\n kept.add(texture.id);\n const existing = textureGraphs.get(texture.id);\n const hosted = existing ?? {\n graph: createSceneGraph({\n store,\n ...(options.behaviours === undefined ? {} : { behaviours: options.behaviours }),\n }),\n description: texture,\n };\n const result = hosted.graph.reconcile(textureScene(texture, next));\n const reframed =\n existing === undefined ||\n existing.description.width !== texture.width ||\n existing.description.height !== texture.height ||\n existing.description.background !== texture.background;\n if (reframed) {\n hosted.graph.resize(texture.width, texture.height);\n hosted.graph.scene.background =\n texture.background === null ? null : new Color(texture.background);\n }\n hosted.description = texture;\n textureGraphs.set(texture.id, hosted);\n const subOps = result._tag === 'Applied' ? result.ops : [];\n if (reframed || subOps.length > 0) {\n ops.push({ _tag: 'UpdateRenderTexture', id: texture.id, ops: subOps });\n }\n }\n for (const [id, hosted] of textureGraphs) {\n if (kept.has(id)) continue;\n hosted.graph.dispose();\n textureGraphs.delete(id);\n ops.push({ _tag: 'RemoveRenderTexture', id });\n }\n // In the description's order, so a host draws them in the order they were written.\n // In the description's order, so a host draws them in the order they were written.\n textureList = next.renderTextures.flatMap((texture) => hostedTexture(texture));\n return ops;\n };\n\n const reconcile = (next: SceneDescription): ReconcileResult => {\n // Validate every render texture's scene first, so a bad one changes nothing at all.\n for (const texture of next.renderTextures) {\n const checked = indexScene(textureScene(texture, next), knownBehaviours);\n if (checked._tag === 'Invalid') return checked;\n }\n const result = diff(index, next, knownBehaviours);\n if (result._tag === 'Invalid') return result;\n for (const op of result.ops) apply(op);\n for (const entry of reparented) {\n if (isPlaced(entry)) retarget(entry, entry.node);\n }\n reparented.clear();\n index = result.index;\n // Gestures change how input is read, not what is drawn: no operation, no frame.\n gestures = next.gestures;\n // Overlays are placed when a frame is drawn: a change needs one, but no operation.\n if (!overlaysEqual(overlayList, next.overlays)) invalidate();\n overlayList = next.overlays;\n // The frame loop applies the environment, which may need the renderer: ask for a frame.\n if (!environmentEquals(environmentDescription, next.environment)) invalidate();\n environmentDescription = next.environment;\n if (!skyEquals(skyDescription, next.sky)) {\n applySky(next.sky);\n invalidate();\n }\n skyDescription = next.sky;\n // The frame loop draws contact shadows with the renderer: a change needs a frame.\n if (!contactShadowsEquals(contactDescription, next.contactShadows)) invalidate();\n contactDescription = next.contactShadows;\n // The debug lines appear or go with the next frame: ask for one, for an asleep world.\n if ((physicsDescription?.debug ?? false) !== (next.physics?.debug ?? false)) invalidate();\n physicsDescription = next.physics;\n bodyHost.sync(next.physics, bodySources());\n // Read by the host when it presents the scene immersively: no operation, no frame.\n xrDescription = next.xr;\n // Measured after the next drawn frame; a new list needs one.\n if (next.measure.join('\\u0000') !== measured.join('\\u0000')) invalidate();\n measured = next.measure;\n const ops = [...result.ops, ...syncTextures(next)];\n if (ops.length > 0) invalidate();\n return { _tag: 'Applied', ops };\n };\n\n // Defined once so ticking allocates nothing; deleting during Map.forEach is safe.\n const stepTween = (tween: Tween, entry: Entry): void => {\n if (applyTween(entry.object, tween, elapsed)) moving.delete(entry);\n };\n\n const tick = (elapsedSeconds: number): void => {\n elapsed = elapsedSeconds;\n for (const texture of textureList) texture.graph.tick(elapsedSeconds);\n for (const entry of spinning) {\n if (isPlaced(entry)) {\n writeRotation(entry.object.rotation, entry.node.rotation, elapsed);\n }\n }\n moving.forEach(stepTween);\n for (const entry of playing) pose(entry);\n behaving.forEach(applyBehaviour);\n cameraMotion.step(camera, elapsed);\n for (const view of views) viewMotions.get(view.key)?.step(view.camera, elapsed);\n // Last: a dynamic body's pose is the simulation's, whatever else moved the mesh.\n bodyHost.tick(elapsed, animating);\n };\n\n const finishTween = (tween: Tween, entry: Entry): void => {\n applyTween(entry.object, tween, Number.POSITIVE_INFINITY);\n };\n\n const setAnimating = (next: boolean): void => {\n if (next !== animating) invalidate();\n for (const texture of textureList) texture.graph.setAnimating(next);\n animating = next;\n if (next) return;\n moving.forEach(finishTween);\n moving.clear();\n cameraMotion.settle(camera);\n for (const view of views) viewMotions.get(view.key)?.settle(view.camera);\n };\n\n const dispose = (): void => {\n removeSky();\n bodyHost.dispose();\n for (const texture of textureList) texture.graph.dispose();\n textureGraphs.clear();\n textureList = [];\n for (const entry of entries.values()) {\n entry.object.removeFromParent();\n release(entry);\n }\n entries.clear();\n index = emptyIndex;\n unsubscribeGeometry();\n unsubscribeMaterial();\n unsubscribeShared();\n unsubscribeLoans();\n invalidationListeners.clear();\n if (ownsStore) store.dispose();\n };\n\n return {\n scene,\n kit: options.kit,\n get camera() {\n return camera;\n },\n views: () => views,\n holdCameras: (held) => {\n cameraMotion.hold(held);\n for (const motion of viewMotions.values()) motion.hold(held);\n },\n turned: (view) => {\n if (view === undefined) return cameraMotion.turned();\n return viewMotions.get(view)?.turned();\n },\n renderTextures: () => textureList,\n gestures: () => gestures,\n overlays: () => overlayList,\n environment: () => environmentDescription,\n contactShadows: () => contactDescription,\n collisions: bodyHost.drainCollisions,\n contactForces: bodyHost.drainContactForces,\n xr: () => xrDescription,\n measured: () => measured,\n labelLayout: (key) => {\n const entry = entries.get(key);\n return entry?._tag === 'Label' ? entry.hosted?.layout() : undefined;\n },\n follow: (locate) => {\n scene.updateMatrixWorld();\n for (const entry of entries.values()) {\n if (entry._tag !== 'Group' || entry.node.follow === null) continue;\n const pose = locate(entry.node.follow);\n entry.object.visible = pose !== undefined;\n if (pose !== undefined) placeObject(entry.object, pose);\n }\n },\n store,\n reconcile,\n tick,\n elapsedSeconds: () => elapsed,\n renderSettings: () => settings,\n needsFrame: () =>\n dirty ||\n textureList.some((texture) => texture.graph.needsFrame()) ||\n (animating &&\n (spinning.size > 0 ||\n moving.size > 0 ||\n behaving.size > 0 ||\n clipsRunning() ||\n cameraMotion.moving() ||\n viewsMoving() ||\n bodyHost.needsFrame())),\n drawn: () => {\n dirty = false;\n },\n onInvalidated: (listener) => {\n invalidationListeners.add(listener);\n return () => {\n invalidationListeners.delete(listener);\n };\n },\n setAnimating,\n object: (key) => entries.get(key)?.object,\n keyOf: (object) => keys.get(object),\n instanceKeyOf: (object, instanceId) => {\n const key = keys.get(object);\n const entry = key === undefined ? undefined : entries.get(key);\n return entry?._tag === 'Instances' ? entry.node.instances[instanceId]?.key : undefined;\n },\n interactiveObjects: () => {\n interactiveList ??= [...interactive];\n return interactiveList;\n },\n viewport: () => viewport,\n resize: (width, height) => {\n viewport = { width, height };\n fitCamera(camera, viewport);\n hostViews(viewDescriptions);\n invalidate();\n },\n dispose,\n };\n};\n",
|
|
32
|
+
"/**\n * Rigid bodies for a scene graph's nodes: a physics world kept in step with the\n * description, advanced on scene time, its poses written back to the nodes (or, for an\n * instances node, to each instance's matrix).\n *\n * Behavioural reference: react-three-rapier at `ae5c3fe`, `src/components/Physics.tsx`:\n * fixed steps from an accumulator, the frame delta clamped to 0.5 s, nothing stepped while\n * paused, and each body placed between its last two simulated poses (`interpolate`),\n * converted from world space into its parent's space.\n *\n * @module\n */\nimport { Euler, Quaternion, type Scene } from 'three';\n\nimport { bodyId, type BodySource } from './bodySources.ts';\nimport type { Body, Joint, Physics, Vec3 } from './description.ts';\nimport { bodyEquals, collidersEqual, jointEquals, physicsEquals } from './equality.ts';\nimport type { BodyPose, PhysicsEngine, PhysicsJoint, PhysicsWorld, Quat } from './physics.ts';\nimport { createPhysicsDebug } from './physicsDebug.ts';\n\n/** Two bodies began (`started`) or stopped touching: their nodes' keys, and instances'. */\nexport type BodyCollision = {\n readonly a: string;\n readonly aInstance?: string;\n /** The part of body `a` that touched (a mesh's or collider's name), when it has one. */\n readonly aPart?: string;\n readonly b: string;\n readonly bInstance?: string;\n readonly bPart?: string;\n readonly started: boolean;\n};\n\n/**\n * Two bodies pushing on each other harder than a threshold: their nodes' keys (and\n * instances'), and Rapier's contact force payload, as react-three-rapier's\n * `onContactForce`.\n */\nexport type BodyContactForce = {\n readonly a: string;\n readonly aInstance?: string;\n readonly aPart?: string;\n readonly b: string;\n readonly bInstance?: string;\n readonly bPart?: string;\n readonly totalForce: Vec3;\n readonly totalForceMagnitude: number;\n readonly maxForceDirection: Vec3;\n readonly maxForceMagnitude: number;\n};\n\ntype Hosted = {\n source: BodySource;\n /** What its colliders were made from; a change makes them again. */\n signature: string;\n previous: BodyPose;\n current: BodyPose;\n /** Where it was last placed, between `previous` and `current`. */\n shown: BodyPose;\n};\n\nexport type BodyHost = {\n /** Brings the world in line with the description's physics and its bodies. */\n readonly sync: (physics: Physics | null, sources: Iterable<BodySource>) => void;\n /** Steps the world to scene time `elapsed` and moves dynamic bodies to their poses. */\n readonly tick: (elapsed: number, animating: boolean) => void;\n /** Whether the simulation still moves anything. */\n readonly needsFrame: () => boolean;\n /** Collisions since the last call. */\n readonly drainCollisions: () => ReadonlyArray<BodyCollision>;\n /** Contact forces over their thresholds since the last call. */\n readonly drainContactForces: () => ReadonlyArray<BodyContactForce>;\n readonly dispose: () => void;\n};\n\nconst from = new Quaternion();\nconst to = new Quaternion();\nconst euler = new Euler();\n\nconst quatOf = (angles: Vec3): Quat => {\n from.setFromEuler(euler.fromArray([...angles]));\n return [from.x, from.y, from.z, from.w];\n};\n\n/** A joint for the engine: a fixed joint's frames turned into quaternions. */\nconst physicsJoint = ({ anchorA, anchorB, kind, contacts }: Joint): PhysicsJoint => ({\n anchorA,\n anchorB,\n contacts,\n kind:\n kind._tag === 'Fixed'\n ? { _tag: 'Fixed', frameA: quatOf(kind.frameA), frameB: quatOf(kind.frameB) }\n : kind,\n});\n\n/** The pose `alpha` of the way from `a` to `b`: positions lerped, rotations slerped. */\nconst between = (a: BodyPose, b: BodyPose, alpha: number): BodyPose => {\n if (alpha >= 1) return b;\n from.fromArray(a.quaternion);\n to.fromArray(b.quaternion);\n from.slerp(to, alpha);\n return {\n position: [\n a.position[0] + (b.position[0] - a.position[0]) * alpha,\n a.position[1] + (b.position[1] - a.position[1]) * alpha,\n a.position[2] + (b.position[2] - a.position[2]) * alpha,\n ],\n quaternion: [from.x, from.y, from.z, from.w],\n };\n};\n\n/** A change that needs a new body: another holder or kind, or colliders made otherwise. */\nconst remade = (hosted: Hosted, source: BodySource, signature: string): boolean =>\n hosted.source.holder !== source.holder ||\n hosted.source.body.collider !== source.body.collider ||\n !collidersEqual(hosted.source.body.colliders, source.body.colliders) ||\n hosted.signature !== signature;\n\n/** Body settings other than its impulse differ. */\nconst resettled = (a: Body, b: Body): boolean =>\n !bodyEquals({ ...a, impulse: null }, { ...b, impulse: null });\n\n/** Bodies `a` and `b` (by id) named by their nodes, instances and parts, where they have them. */\nconst named = (\n a: BodySource | undefined,\n b: BodySource | undefined,\n ids: {\n readonly a: string;\n readonly b: string;\n readonly aPart?: string;\n readonly bPart?: string;\n },\n): Pick<BodyCollision, 'a' | 'aInstance' | 'aPart' | 'b' | 'bInstance' | 'bPart'> => {\n const aInstance = a?.instance;\n const bInstance = b?.instance;\n return {\n a: a?.key ?? ids.a,\n ...(aInstance === undefined ? {} : { aInstance }),\n ...(ids.aPart === undefined ? {} : { aPart: ids.aPart }),\n b: b?.key ?? ids.b,\n ...(bInstance === undefined ? {} : { bInstance }),\n ...(ids.bPart === undefined ? {} : { bPart: ids.bPart }),\n };\n};\n\n/** Creates the body host for a scene. Without an engine, bodies are ignored. */\nexport const createBodyHost = (engine: PhysicsEngine | undefined, scene: Scene): BodyHost => {\n let world: PhysicsWorld | undefined;\n let settings: Physics | null = null;\n const hosted = new Map<string, Hosted>();\n /** Joints made, by key. */\n const joined = new Map<string, Joint>();\n /** Bodies (re)made by the current sync: their joints went with the old ones. */\n const fresh = new Set<string>();\n let collisions: Array<BodyCollision> = [];\n let contactForces: Array<BodyContactForce> = [];\n const debug = createPhysicsDebug(scene);\n let last: number | undefined;\n let accumulator = 0;\n\n /** Draws the world's lines while the description asks for them. */\n const drawDebug = (): void => {\n if (world !== undefined && settings?.debug === true) debug.show(world.debugLines());\n else debug.hide();\n };\n\n const dispose = (): void => {\n debug.hide();\n world?.dispose();\n world = undefined;\n settings = null;\n hosted.clear();\n joined.clear();\n accumulator = 0;\n last = undefined;\n };\n\n const add = (active: PhysicsWorld, source: BodySource, signature: string): void => {\n const pose = source.pose();\n active.add(source.id, source.body, source.colliders(), pose);\n if (source.body.impulse !== null) active.applyImpulse(source.id, source.body.impulse.impulse);\n hosted.set(source.id, { source, signature, previous: pose, current: pose, shown: pose });\n fresh.add(source.id);\n };\n\n const syncBody = (active: PhysicsWorld, source: BodySource): void => {\n const existing = hosted.get(source.id);\n const signature = source.signature();\n if (existing === undefined || remade(existing, source, signature)) {\n if (existing !== undefined) active.remove(source.id);\n add(active, source, signature);\n return;\n }\n const before = existing.source.body;\n const { body } = source;\n if (resettled(before, body)) active.update(source.id, body);\n if (body.type !== 'kinematic' && existing.source.placement !== source.placement) {\n const pose = source.described();\n active.teleport(source.id, pose);\n existing.previous = pose;\n existing.current = pose;\n existing.shown = pose;\n source.place(pose);\n } else if (body.type === 'dynamic') {\n // A description change elsewhere (an instance's colour, say) may have rewritten it.\n source.place(existing.shown);\n }\n if (body.impulse !== null && body.impulse.id !== before.impulse?.id) {\n active.applyImpulse(source.id, body.impulse.impulse);\n }\n existing.source = source;\n };\n\n /** Makes each joint whose bodies both exist, again when either was remade or it changed. */\n const syncJoints = (active: PhysicsWorld, joints: ReadonlyArray<Joint>): void => {\n const seen = new Set<string>();\n for (const joint of joints) {\n seen.add(joint.key);\n const a = bodyId(joint.a.key, joint.a.instance);\n const b = bodyId(joint.b.key, joint.b.instance);\n const ready = hosted.has(a) && hosted.has(b);\n const made = joined.get(joint.key);\n if (\n made !== undefined &&\n ready &&\n !fresh.has(a) &&\n !fresh.has(b) &&\n jointEquals(made, joint)\n ) {\n continue;\n }\n if (made !== undefined) {\n active.removeJoint(joint.key);\n joined.delete(joint.key);\n }\n if (ready) {\n active.addJoint(joint.key, physicsJoint(joint), a, b);\n joined.set(joint.key, joint);\n }\n }\n for (const key of joined.keys()) {\n if (seen.has(key)) continue;\n active.removeJoint(key);\n joined.delete(key);\n }\n };\n\n const sync: BodyHost['sync'] = (physics, sources) => {\n if (physics === null || engine === undefined) {\n dispose();\n return;\n }\n if (world === undefined) world = engine.createWorld(physics);\n // Joints are made below, not configured.\n else if (!physicsEquals(settings && { ...settings, joints: physics.joints }, physics)) {\n world.configure(physics);\n }\n settings = physics;\n scene.updateMatrixWorld();\n fresh.clear();\n const seen = new Set<string>();\n for (const source of sources) {\n seen.add(source.id);\n syncBody(world, source);\n }\n for (const id of hosted.keys()) {\n if (seen.has(id)) continue;\n world.remove(id);\n hosted.delete(id);\n }\n syncJoints(world, physics.joints);\n drawDebug();\n };\n\n const kinematicTargets = (active: PhysicsWorld): void => {\n for (const [id, { source }] of hosted) {\n if (source.body.type === 'kinematic') active.moveKinematic(id, source.pose());\n }\n };\n\n const step = (active: PhysicsWorld, seconds: number): void => {\n for (const body of hosted.values()) body.previous = body.current;\n kinematicTargets(active);\n for (const collision of active.step(seconds)) {\n collisions.push({\n ...named(hosted.get(collision.a)?.source, hosted.get(collision.b)?.source, collision),\n started: collision.started,\n });\n }\n for (const force of active.contactForces()) {\n const { a, b, aPart, bPart, ...payload } = force;\n contactForces.push({\n ...named(hosted.get(a)?.source, hosted.get(b)?.source, force),\n ...payload,\n });\n }\n for (const [id, body] of hosted) body.current = active.pose(id) ?? body.current;\n };\n\n const tick: BodyHost['tick'] = (elapsed, animating) => {\n const delta = last === undefined ? 0 : Math.min(0.5, Math.max(0, elapsed - last));\n last = elapsed;\n if (world === undefined || settings === null || settings.paused || !animating) return;\n const timeStep = settings.timeStep;\n accumulator += delta;\n scene.updateMatrixWorld();\n while (accumulator >= timeStep) {\n step(world, timeStep);\n accumulator -= timeStep;\n }\n const alpha = settings.interpolate ? accumulator / timeStep : 1;\n for (const body of hosted.values()) {\n if (body.source.body.type === 'dynamic') {\n body.shown = between(body.previous, body.current, alpha);\n body.source.place(body.shown);\n }\n }\n if (settings.debug) drawDebug();\n };\n\n return {\n sync,\n tick,\n needsFrame: () => world !== undefined && settings !== null && !settings.paused && world.awake(),\n drainCollisions: () => {\n if (collisions.length === 0) return collisions;\n const drained = collisions;\n collisions = [];\n return drained;\n },\n drainContactForces: () => {\n if (contactForces.length === 0) return contactForces;\n const drained = contactForces;\n contactForces = [];\n return drained;\n },\n dispose,\n };\n};\n",
|
|
33
|
+
"/**\n * What the body host needs from each body in a scene: where it is, where the description\n * puts it, what its colliders are made from, and how to put a simulated pose back. A body\n * sits on a mesh, group or borrowed model, or on each instance of an instances node (as\n * react-three-rapier's `InstancedRigidBodies`, `ae5c3fe`).\n *\n * @module\n */\nimport { Euler, type InstancedMesh, Matrix4, type Object3D, Quaternion, Vector3 } from 'three';\n\nimport type {\n Body,\n BorrowedNode,\n GroupNode,\n Instance,\n InstancesNode,\n MeshNode,\n Rotation,\n} from './description.ts';\nimport {\n type BodyPose,\n type Collider,\n colliderFor,\n colliderSignature,\n collidersFor,\n describedColliders,\n} from './physics.ts';\n\n/** The id of a node's body (`instance` null) or an instance's, in the physics world. */\nexport const bodyId = (key: string, instance: string | null): string =>\n instance === null ? key : `${key}\\u0000${instance}`;\n\n/** A node a body can sit on directly. */\nexport type BodiedNode = MeshNode | GroupNode | BorrowedNode;\n\n/** One body, as the body host sees it. */\nexport type BodySource = {\n /** The body's id in the physics world. */\n readonly id: string;\n /** The node's key, and for an instance its key, as collisions report them. */\n readonly key: string;\n readonly instance?: string;\n readonly body: Body;\n /** What it lives on (a hosted object, or an instances node's entry): a new one means a new body. */\n readonly holder: object;\n /** Where the description puts it, as text: a change teleports a non-kinematic body. */\n readonly placement: string;\n /** What its colliders are made from: a change remakes them. */\n readonly signature: () => string;\n readonly colliders: () => ReadonlyArray<Collider>;\n /** Where it is now, in world space. */\n readonly pose: () => BodyPose;\n /** Where the description puts it, in world space. */\n readonly described: () => BodyPose;\n /** Puts it at a world pose (a simulated one). */\n readonly place: (pose: BodyPose) => void;\n};\n\nconst position = new Vector3();\nconst quaternion = new Quaternion();\nconst scale = new Vector3();\nconst matrix = new Matrix4();\nconst local = new Matrix4();\nconst inverse = new Matrix4();\nconst euler = new Euler();\nconst ownScale = new Vector3();\n\nconst toPose = (from: Matrix4): BodyPose => {\n from.decompose(position, quaternion, scale);\n return {\n position: [position.x, position.y, position.z],\n quaternion: [quaternion.x, quaternion.y, quaternion.z, quaternion.w],\n };\n};\n\n/** A world matrix's scale. */\nconst worldScale = (from: Matrix4): Vector3 => {\n from.decompose(position, quaternion, ownScale);\n return ownScale;\n};\n\n/** A world matrix's scale as text, to five places (a turning body's matrix rounds). */\nconst scaleText = (from: Matrix4): string =>\n worldScale(from)\n .toArray()\n .map((value) => (Math.round(value * 1e5) / 1e5 || 0).toString())\n .join(',');\n\nconst rotationText = (rotation: Rotation): string =>\n rotation._tag === 'Fixed' ? rotation.euler.join(',') : 'spin';\n\n/** A world pose written to an object in its parent's space, keeping its scale. */\nexport const placeObject = (object: Object3D, pose: BodyPose): void => {\n object.matrixWorld.decompose(position, quaternion, scale);\n matrix.compose(position.fromArray(pose.position), quaternion.fromArray(pose.quaternion), scale);\n if (object.parent !== null) matrix.premultiply(inverse.copy(object.parent.matrixWorld).invert());\n matrix.decompose(object.position, object.quaternion, scale);\n};\n\n/** The body on a mesh, group or borrowed model, if it has one. */\nexport const nodeSource = (\n key: string,\n node: BodiedNode,\n object: Object3D,\n): BodySource | undefined => {\n const { body } = node;\n if (body === null) return undefined;\n return {\n id: key,\n key,\n body,\n holder: object,\n placement: `${node.position.join(',')}|${rotationText(node.rotation)}`,\n // Colliders of its own depend on its scale only; others, on its meshes.\n signature: () =>\n body.colliders === null ? colliderSignature(object) : `own:${scaleText(object.matrixWorld)}`,\n colliders: () =>\n body.colliders === null\n ? collidersFor(object, body.collider)\n : describedColliders(body.colliders, worldScale(object.matrixWorld)),\n pose: () => toPose(object.matrixWorld),\n described: () => {\n position.fromArray(node.position);\n if (node.rotation._tag === 'Fixed') {\n quaternion.setFromEuler(euler.fromArray([...node.rotation.euler]));\n } else quaternion.copy(object.quaternion);\n matrix.compose(position, quaternion, object.scale);\n if (object.parent !== null) matrix.premultiply(object.parent.matrixWorld);\n return toPose(matrix);\n },\n place: (pose) => placeObject(object, pose),\n };\n};\n\n/** An instance's matrix in its mesh, from its description. */\nconst instanceMatrix = (instance: Instance): Matrix4 =>\n local.compose(\n position.fromArray(instance.position),\n quaternion.setFromEuler(euler.fromArray([...instance.rotation])),\n scale.fromArray(instance.scale),\n );\n\n/** The body on one instance of an instances node with a body. */\nconst instanceSource = (\n key: string,\n body: Body,\n holder: object,\n mesh: InstancedMesh,\n instance: Instance,\n slot: number,\n): BodySource => ({\n id: bodyId(key, instance.key),\n key,\n instance: instance.key,\n body,\n holder,\n placement: `${instance.position.join(',')}|${instance.rotation.join(',')}`,\n signature: () => `${mesh.geometry.uuid}:${instance.scale.join(',')}`,\n colliders: () => {\n mesh.matrixWorld.decompose(position, quaternion, ownScale);\n ownScale.multiply(scale.fromArray(instance.scale));\n return body.colliders === null\n ? [colliderFor(mesh.geometry, body.collider, ownScale)]\n : describedColliders(body.colliders, ownScale);\n },\n pose: () => {\n mesh.getMatrixAt(slot, local);\n return toPose(matrix.copy(mesh.matrixWorld).multiply(local));\n },\n described: () => toPose(matrix.copy(mesh.matrixWorld).multiply(instanceMatrix(instance))),\n place: (pose) => {\n mesh.matrixWorld.decompose(position, quaternion, ownScale);\n ownScale.multiply(scale.fromArray(instance.scale));\n matrix.compose(\n position.fromArray(pose.position),\n quaternion.fromArray(pose.quaternion),\n ownScale,\n );\n matrix.premultiply(inverse.copy(mesh.matrixWorld).invert());\n mesh.setMatrixAt(slot, matrix);\n mesh.instanceMatrix.needsUpdate = true;\n // Picking and culling recompute these from the moved instances.\n mesh.boundingSphere = null;\n mesh.boundingBox = null;\n },\n});\n\n/**\n * A body per instance of an instances node with a body. `holder` outlives the mesh, which\n * is swapped for a larger one as instances are added: the bodies stay.\n */\nexport const instanceSources = (\n key: string,\n node: InstancesNode,\n holder: object,\n mesh: InstancedMesh,\n): ReadonlyArray<BodySource> => {\n const { body } = node;\n if (body === null) return [];\n return node.instances.map((instance, slot) =>\n instanceSource(key, body, holder, mesh, instance, slot),\n );\n};\n",
|
|
34
|
+
"/**\n * The physics world drawn as lines, as react-three-rapier's `Debug` (`ae5c3fe`,\n * `src/components/Debug.tsx`) draws `world.debugRender()`: one `LineSegments` with\n * per-vertex colours, never culled. Here its buffers are reused while their size holds.\n *\n * @module\n */\nimport {\n BufferAttribute,\n BufferGeometry,\n LineBasicMaterial,\n LineSegments,\n type Object3D,\n} from 'three';\n\nimport type { DebugLines } from './physics.ts';\n\nexport type PhysicsDebug = {\n /** Shows `lines` (adding the drawing to the scene the first time). */\n readonly show: (lines: DebugLines) => void;\n /** Takes the drawing away and frees it. */\n readonly hide: () => void;\n};\n\n/** Writes `values` into the geometry's attribute `name`, reusing it when it fits. */\nconst write = (\n geometry: BufferGeometry,\n name: 'position' | 'color',\n values: Float32Array,\n size: number,\n): void => {\n const current = geometry.getAttribute(name);\n if (current instanceof BufferAttribute && current.array.length === values.length) {\n current.array.set(values);\n current.needsUpdate = true;\n return;\n }\n geometry.setAttribute(name, new BufferAttribute(values.slice(), size));\n};\n\n/** Creates the debug drawing for a scene. */\nexport const createPhysicsDebug = (scene: Object3D): PhysicsDebug => {\n let lines: LineSegments<BufferGeometry, LineBasicMaterial> | undefined;\n return {\n show: ({ vertices, colors }) => {\n if (lines === undefined) {\n lines = new LineSegments(\n new BufferGeometry(),\n new LineBasicMaterial({ color: 0xffffff, vertexColors: true }),\n );\n lines.name = 'physics-debug';\n lines.frustumCulled = false;\n lines.raycast = () => undefined;\n scene.add(lines);\n }\n write(lines.geometry, 'position', vertices, 3);\n write(lines.geometry, 'color', colors, 4);\n lines.geometry.setDrawRange(0, vertices.length / 3);\n },\n hide: () => {\n if (lines === undefined) return;\n lines.removeFromParent();\n lines.geometry.dispose();\n lines.material.dispose();\n lines = undefined;\n },\n };\n};\n",
|
|
35
|
+
"/**\n * How the rendered camera reaches its description: at once, or damped round its target;\n * and how it turns round its target by itself (`autoRotate`).\n *\n * Behavioural reference: three.js `examples/jsm/controls/OrbitControls.js` at 0.186.1,\n * `update` with `enableDamping`: each update closes `dampingFactor` of the remaining\n * rotation and pan. Here the remaining way to the described pose closes by that fraction\n * every sixtieth of a second of scene time, so the motion is the same at any frame rate,\n * and the camera travels round the target (azimuth the short way) rather than through it.\n * `autoRotate` is `update` with `autoRotate`: `rotateLeft` by `2π / 60 * autoRotateSpeed`\n * a second, only while no gesture is in progress (`state === NONE`).\n *\n * @module\n */\nimport { OrthographicCamera, type PerspectiveCamera, Spherical, Vector3 } from 'three';\n\nimport type { Camera, Vec3 } from './description.ts';\n\ntype Pose = { readonly target: Vector3; readonly spherical: Spherical; zoom: number };\n\nconst createPose = (): Pose => ({ target: new Vector3(), spherical: new Spherical(), zoom: 1 });\n\nconst offset = new Vector3();\nconst position = new Vector3();\n\nconst readPose = (pose: Pose, description: Camera): void => {\n pose.target.fromArray(description.lookAt);\n offset.fromArray(description.position).sub(pose.target);\n pose.spherical.setFromVector3(offset);\n pose.zoom = description._tag === 'Orthographic' ? description.zoom : 1;\n};\n\nconst copyPose = (to: Pose, from: Pose): void => {\n to.target.copy(from.target);\n to.spherical.copy(from.spherical);\n to.zoom = from.zoom;\n};\n\n/** The signed angle from `from` to `to`, the short way round: within ±π. */\nconst turn = (from: number, to: number): number => {\n const difference = (to - from) % (2 * Math.PI);\n if (difference > Math.PI) return difference - 2 * Math.PI;\n if (difference < -Math.PI) return difference + 2 * Math.PI;\n return difference;\n};\n\n/** Close enough to the aim that the rest is invisible: snap and stop. */\nconst settled = (current: Pose, goal: Pose): boolean => {\n const scale = Math.max(1, goal.spherical.radius);\n return (\n current.target.distanceTo(goal.target) < 1e-5 * scale &&\n Math.abs(current.spherical.radius - goal.spherical.radius) < 1e-5 * scale &&\n Math.abs(turn(current.spherical.theta, goal.spherical.theta)) < 1e-6 &&\n Math.abs(current.spherical.phi - goal.spherical.phi) < 1e-6 &&\n Math.abs(current.zoom - goal.zoom) < 1e-6 * goal.zoom\n );\n};\n\nfunction writeZoom(camera: PerspectiveCamera | OrthographicCamera, zoom: number): void {\n if (!(camera instanceof OrthographicCamera) || camera.zoom === zoom) return;\n camera.zoom = zoom;\n camera.updateProjectionMatrix();\n}\n\n/** Writes a pose to a host camera. */\nconst write = (camera: PerspectiveCamera | OrthographicCamera, pose: Pose): void => {\n position.setFromSpherical(pose.spherical).add(pose.target);\n camera.position.copy(position);\n camera.lookAt(pose.target);\n writeZoom(camera, pose.zoom);\n};\n\nexport type CameraMotion = {\n /**\n * Aims at a described pose at scene time `now`. It is shown at once when `jump` is\n * true, the camera has no damping, or nothing was shown before; otherwise `step`\n * travels there. A new position, `lookAt` or zoom ends any turning (`autoRotate`).\n */\n readonly aim: (\n camera: PerspectiveCamera | OrthographicCamera,\n description: Camera,\n now: number,\n jump: boolean,\n ) => void;\n /**\n * Turns (`autoRotate`) and travels toward the aim up to scene time `now`. Returns\n * whether it is still moving.\n */\n readonly step: (camera: PerspectiveCamera | OrthographicCamera, now: number) => boolean;\n /** Lands on the aim at once. */\n readonly settle: (camera: PerspectiveCamera | OrthographicCamera) => void;\n readonly moving: () => boolean;\n /** Stops turning while `held` (a gesture is pressed), as `OrbitControls` turns only idle. */\n readonly hold: (held: boolean) => void;\n /** Where turning has taken the camera, when it has turned since its description. */\n readonly turned: () => Vec3 | undefined;\n};\n\n/** Radians a turning camera turns per second per unit of `autoRotate` (three's `2π / 60`). */\nconst turnRate = (2 * Math.PI) / 60;\n\n/** Creates the motion of one camera. Allocation-free once created. */\nexport const createCameraMotion = (): CameraMotion => {\n const current = createPose();\n // Where the description puts the camera, and where it is going: that, turned by `spun`.\n const described = createPose();\n const goal = createPose();\n // The described position, written exactly on landing rather than through angles.\n const goalPosition = new Vector3();\n const lookAt = new Vector3();\n let shown = false;\n let easing = false;\n let damping = 0;\n let spin = 0;\n let spun = 0;\n let held = false;\n let last = 0;\n\n const turning = (): boolean => spin !== 0 && !held;\n\n const aimGoal = (): void => {\n copyPose(goal, described);\n goal.spherical.theta += spun;\n };\n\n const land = (camera: PerspectiveCamera | OrthographicCamera): void => {\n copyPose(current, goal);\n easing = false;\n if (spun !== 0) {\n write(camera, goal);\n return;\n }\n camera.position.copy(goalPosition);\n camera.lookAt(goal.target);\n writeZoom(camera, goal.zoom);\n };\n\n const settle: CameraMotion['settle'] = (camera) => {\n if (shown) land(camera);\n };\n\n /** Whether `description` puts the camera somewhere other than the last description did. */\n const moved = (description: Camera): boolean =>\n !shown ||\n !goalPosition.equals(position.fromArray(description.position)) ||\n !described.target.equals(lookAt.fromArray(description.lookAt)) ||\n described.zoom !== (description._tag === 'Orthographic' ? description.zoom : 1);\n\n /** One step of easing toward the goal, `seconds` after the last. */\n const ease = (camera: PerspectiveCamera | OrthographicCamera, seconds: number): void => {\n const remaining = (1 - damping) ** (seconds * 60);\n const k = 1 - remaining;\n current.target.lerp(goal.target, k);\n current.spherical.radius += (goal.spherical.radius - current.spherical.radius) * k;\n current.spherical.phi += (goal.spherical.phi - current.spherical.phi) * k;\n current.spherical.theta += turn(current.spherical.theta, goal.spherical.theta) * k;\n current.zoom += (goal.zoom - current.zoom) * k;\n if (remaining < 1e-4 || settled(current, goal)) land(camera);\n else write(camera, current);\n };\n\n return {\n aim: (camera, description, now, jump) => {\n if (moved(description)) spun = 0;\n readPose(described, description);\n goalPosition.fromArray(description.position);\n damping = description.damping;\n spin = description.autoRotate;\n last = now;\n aimGoal();\n if (jump || damping === 0 || !shown) {\n shown = true;\n land(camera);\n return;\n }\n easing = !settled(current, goal);\n },\n step: (camera, now) => {\n const seconds = Math.max(0, now - last);\n last = now;\n if (turning() && seconds > 0) {\n // Clockwise seen from above for a positive speed, as `rotateLeft` turns.\n spun -= turnRate * spin * seconds;\n aimGoal();\n easing = damping !== 0;\n if (!easing) land(camera);\n }\n if (easing) ease(camera, seconds);\n return easing || turning();\n },\n settle,\n moving: () => easing || turning(),\n hold: (next) => {\n held = next;\n },\n turned: () => {\n if (spun === 0) return undefined;\n position.setFromSpherical(goal.spherical).add(goal.target);\n return [position.x, position.y, position.z];\n },\n };\n};\n"
|
|
36
|
+
],
|
|
37
|
+
"mappings": "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",
|
|
38
|
+
"debugId": "45D70156AEB5E57864756E2164756E21",
|
|
39
|
+
"names": []
|
|
40
|
+
}
|