@opsydyn/effect-three 0.0.0-stage → 0.2.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 +69 -0
- package/LICENSE +21 -0
- package/README.md +189 -2
- package/dist/index-01kwfekm.js +5118 -0
- package/dist/index-01kwfekm.js.map +40 -0
- package/dist/index-4045wme0.js +129 -0
- package/dist/index-4045wme0.js.map +10 -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 +51 -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 +49 -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 +54 -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 +54 -0
- package/src/kernel/renderer.ts +136 -0
- package/src/kernel/resources.ts +504 -0
- package/src/kernel/sceneGraph.ts +1442 -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,1197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene descriptions: plain, immutable data with no closures and no three.js objects.
|
|
3
|
+
*
|
|
4
|
+
* Descriptions are fully specified (normalised). Defaults are filled in by the public
|
|
5
|
+
* constructors and the runtime Schema, so the kernel can diff without guessing.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** A three-component vector `[x, y, z]`. */
|
|
11
|
+
export type Vec3 = readonly [x: number, y: number, z: number];
|
|
12
|
+
|
|
13
|
+
/** A rotation axis for behaviours. */
|
|
14
|
+
export type Axis = 'x' | 'y' | 'z';
|
|
15
|
+
|
|
16
|
+
/** A colour as a 24-bit RGB integer, for example `0x3366ff`. */
|
|
17
|
+
export type Rgb = number;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Rotation is owned by exactly one source (ADR: D4).
|
|
21
|
+
*
|
|
22
|
+
* - `Fixed`: the model owns the Euler angles.
|
|
23
|
+
* - `Spin`: a behaviour owns them. The angle is a pure function of elapsed scene time:
|
|
24
|
+
* `phase + radiansPerSecond * elapsedSeconds` about `axis`, other axes zero.
|
|
25
|
+
*/
|
|
26
|
+
export type Rotation =
|
|
27
|
+
| { readonly _tag: 'Fixed'; readonly euler: Vec3 }
|
|
28
|
+
| {
|
|
29
|
+
readonly _tag: 'Spin';
|
|
30
|
+
readonly axis: Axis;
|
|
31
|
+
readonly radiansPerSecond: number;
|
|
32
|
+
readonly phase: number;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/** Box geometry parameters. */
|
|
36
|
+
export type BoxGeometry = {
|
|
37
|
+
readonly _tag: 'Box';
|
|
38
|
+
readonly width: number;
|
|
39
|
+
readonly height: number;
|
|
40
|
+
readonly depth: number;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** UV sphere geometry parameters. */
|
|
44
|
+
export type SphereGeometry = {
|
|
45
|
+
readonly _tag: 'Sphere';
|
|
46
|
+
readonly radius: number;
|
|
47
|
+
readonly widthSegments: number;
|
|
48
|
+
readonly heightSegments: number;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** A flat rectangle in the XY plane, facing +Z. */
|
|
52
|
+
export type PlaneGeometry = {
|
|
53
|
+
readonly _tag: 'Plane';
|
|
54
|
+
readonly width: number;
|
|
55
|
+
readonly height: number;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** Cylinder (or cone, with one radius zero) along the Y axis. */
|
|
59
|
+
export type CylinderGeometry = {
|
|
60
|
+
readonly _tag: 'Cylinder';
|
|
61
|
+
readonly radiusTop: number;
|
|
62
|
+
readonly radiusBottom: number;
|
|
63
|
+
readonly height: number;
|
|
64
|
+
readonly radialSegments: number;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/** A torus (ring doughnut) in the XY plane, around the Z axis. */
|
|
68
|
+
export type TorusGeometry = {
|
|
69
|
+
readonly _tag: 'Torus';
|
|
70
|
+
readonly radius: number;
|
|
71
|
+
readonly tube: number;
|
|
72
|
+
readonly radialSegments: number;
|
|
73
|
+
readonly tubularSegments: number;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/** A cone along the Y axis, point up. */
|
|
77
|
+
export type ConeGeometry = {
|
|
78
|
+
readonly _tag: 'Cone';
|
|
79
|
+
readonly radius: number;
|
|
80
|
+
readonly height: number;
|
|
81
|
+
readonly radialSegments: number;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/** A capsule along the Y axis: a cylinder of `height` with hemispherical caps. */
|
|
85
|
+
export type CapsuleGeometry = {
|
|
86
|
+
readonly _tag: 'Capsule';
|
|
87
|
+
readonly radius: number;
|
|
88
|
+
readonly height: number;
|
|
89
|
+
readonly capSegments: number;
|
|
90
|
+
readonly radialSegments: number;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/** A flat ring (annulus) in the XY plane, facing +Z. */
|
|
94
|
+
export type RingGeometry = {
|
|
95
|
+
readonly _tag: 'Ring';
|
|
96
|
+
readonly innerRadius: number;
|
|
97
|
+
readonly outerRadius: number;
|
|
98
|
+
readonly thetaSegments: number;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/** A flat disc in the XY plane, facing +Z. */
|
|
102
|
+
export type CircleGeometry = {
|
|
103
|
+
readonly _tag: 'Circle';
|
|
104
|
+
readonly radius: number;
|
|
105
|
+
readonly segments: number;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/** Any geometry shape the kernel can build. */
|
|
109
|
+
/** A bevel on extruded text, as three.js's `TextGeometry` options. */
|
|
110
|
+
export type TextBevel = {
|
|
111
|
+
readonly thickness: number;
|
|
112
|
+
readonly size: number;
|
|
113
|
+
readonly offset: number;
|
|
114
|
+
readonly segments: number;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Text drawn from a typeface font lent to the store under `font`, as Drei's `Text3D`
|
|
119
|
+
* (three.js's `TextGeometry`). Flat (`ShapeGeometry`) when `depth` is 0 with no bevel.
|
|
120
|
+
* Until the font is lent the geometry is empty; lending it builds the text.
|
|
121
|
+
*/
|
|
122
|
+
export type TextGeometry = {
|
|
123
|
+
readonly _tag: 'Text';
|
|
124
|
+
readonly text: string;
|
|
125
|
+
readonly font: string;
|
|
126
|
+
readonly size: number;
|
|
127
|
+
readonly depth: number;
|
|
128
|
+
readonly curveSegments: number;
|
|
129
|
+
readonly bevel: TextBevel | null;
|
|
130
|
+
/** Centre the text on its origin, as `geometry.center()`; otherwise it starts there. */
|
|
131
|
+
readonly center: boolean;
|
|
132
|
+
/** Extra space after each letter, in ems (multiples of `size`). */
|
|
133
|
+
readonly letterSpacing: number;
|
|
134
|
+
/** Line spacing as a multiple of the font's own. */
|
|
135
|
+
readonly lineHeight: number;
|
|
136
|
+
/** Where each line sits within the widest. */
|
|
137
|
+
readonly align: TextAlign;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
/** Where each line of text sits within the widest: troika's `textAlign`. */
|
|
141
|
+
export type TextAlign = 'left' | 'center' | 'right';
|
|
142
|
+
|
|
143
|
+
export type ShapeGeometry =
|
|
144
|
+
| TextGeometry
|
|
145
|
+
| BoxGeometry
|
|
146
|
+
| SphereGeometry
|
|
147
|
+
| PlaneGeometry
|
|
148
|
+
| CylinderGeometry
|
|
149
|
+
| TorusGeometry
|
|
150
|
+
| ConeGeometry
|
|
151
|
+
| CapsuleGeometry
|
|
152
|
+
| RingGeometry
|
|
153
|
+
| CircleGeometry;
|
|
154
|
+
|
|
155
|
+
/** Which faces a material draws. */
|
|
156
|
+
export type MaterialSide = 'front' | 'back' | 'double';
|
|
157
|
+
|
|
158
|
+
/** An unlit material: flat colour, unaffected by lights. */
|
|
159
|
+
export type BasicMaterial = {
|
|
160
|
+
readonly _tag: 'Basic';
|
|
161
|
+
readonly color: Rgb;
|
|
162
|
+
/** Id of a texture lent to the store for the colour map, or `null` for none. */
|
|
163
|
+
readonly map: string | null;
|
|
164
|
+
readonly opacity: number;
|
|
165
|
+
readonly transparent: boolean;
|
|
166
|
+
readonly side: MaterialSide;
|
|
167
|
+
readonly wireframe: boolean;
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
/** A matte (Lambertian) material: cheap per-vertex lighting, no highlights. */
|
|
171
|
+
export type LambertMaterial = {
|
|
172
|
+
readonly _tag: 'Lambert';
|
|
173
|
+
readonly color: Rgb;
|
|
174
|
+
/** Id of a texture lent to the store for the colour map, or `null` for none. */
|
|
175
|
+
readonly map: string | null;
|
|
176
|
+
readonly emissive: Rgb;
|
|
177
|
+
readonly opacity: number;
|
|
178
|
+
readonly transparent: boolean;
|
|
179
|
+
readonly side: MaterialSide;
|
|
180
|
+
readonly wireframe: boolean;
|
|
181
|
+
readonly flatShading: boolean;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/** A shiny (Blinn-Phong) material with specular highlights. */
|
|
185
|
+
export type PhongMaterial = {
|
|
186
|
+
readonly _tag: 'Phong';
|
|
187
|
+
readonly color: Rgb;
|
|
188
|
+
/** Id of a texture lent to the store for the colour map, or `null` for none. */
|
|
189
|
+
readonly map: string | null;
|
|
190
|
+
readonly emissive: Rgb;
|
|
191
|
+
readonly specular: Rgb;
|
|
192
|
+
readonly shininess: number;
|
|
193
|
+
readonly opacity: number;
|
|
194
|
+
readonly transparent: boolean;
|
|
195
|
+
readonly side: MaterialSide;
|
|
196
|
+
readonly wireframe: boolean;
|
|
197
|
+
readonly flatShading: boolean;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
/** A physically based (metallic-roughness) material. */
|
|
201
|
+
export type StandardMaterial = {
|
|
202
|
+
readonly _tag: 'Standard';
|
|
203
|
+
readonly color: Rgb;
|
|
204
|
+
/** Id of a texture lent to the store for the colour map, or `null` for none. */
|
|
205
|
+
readonly map: string | null;
|
|
206
|
+
readonly roughness: number;
|
|
207
|
+
readonly metalness: number;
|
|
208
|
+
readonly emissive: Rgb;
|
|
209
|
+
readonly emissiveIntensity: number;
|
|
210
|
+
readonly opacity: number;
|
|
211
|
+
readonly transparent: boolean;
|
|
212
|
+
readonly side: MaterialSide;
|
|
213
|
+
readonly wireframe: boolean;
|
|
214
|
+
readonly flatShading: boolean;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
/** A standard material plus clearcoat, transmission (glass-like) and index of refraction. */
|
|
218
|
+
export type PhysicalMaterial = {
|
|
219
|
+
readonly _tag: 'Physical';
|
|
220
|
+
readonly color: Rgb;
|
|
221
|
+
/** Id of a texture lent to the store for the colour map, or `null` for none. */
|
|
222
|
+
readonly map: string | null;
|
|
223
|
+
readonly roughness: number;
|
|
224
|
+
readonly metalness: number;
|
|
225
|
+
readonly emissive: Rgb;
|
|
226
|
+
readonly emissiveIntensity: number;
|
|
227
|
+
readonly clearcoat: number;
|
|
228
|
+
readonly clearcoatRoughness: number;
|
|
229
|
+
readonly transmission: number;
|
|
230
|
+
readonly ior: number;
|
|
231
|
+
readonly opacity: number;
|
|
232
|
+
readonly transparent: boolean;
|
|
233
|
+
readonly side: MaterialSide;
|
|
234
|
+
readonly wireframe: boolean;
|
|
235
|
+
readonly flatShading: boolean;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
/** Colours each face by its normal: useful for debugging geometry. */
|
|
239
|
+
export type NormalMaterial = {
|
|
240
|
+
readonly _tag: 'Normal';
|
|
241
|
+
readonly opacity: number;
|
|
242
|
+
readonly transparent: boolean;
|
|
243
|
+
readonly side: MaterialSide;
|
|
244
|
+
readonly wireframe: boolean;
|
|
245
|
+
readonly flatShading: boolean;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Draws only the shadows falling on it, transparent elsewhere: three.js's
|
|
250
|
+
* `ShadowMaterial`, for grounding objects on a floor that is not drawn.
|
|
251
|
+
*/
|
|
252
|
+
export type ShadowMaterial = {
|
|
253
|
+
readonly _tag: 'Shadow';
|
|
254
|
+
readonly color: Rgb;
|
|
255
|
+
readonly opacity: number;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
/** Any material the kernel can build. */
|
|
259
|
+
export type SurfaceMaterial =
|
|
260
|
+
| ShadowMaterial
|
|
261
|
+
| BasicMaterial
|
|
262
|
+
| LambertMaterial
|
|
263
|
+
| PhongMaterial
|
|
264
|
+
| StandardMaterial
|
|
265
|
+
| PhysicalMaterial
|
|
266
|
+
| NormalMaterial;
|
|
267
|
+
|
|
268
|
+
/** A geometry owned by one mesh (a shape) or shared by id (`SharedGeometry`). */
|
|
269
|
+
export type GeometryRef =
|
|
270
|
+
| ShapeGeometry
|
|
271
|
+
| { readonly _tag: 'SharedGeometry'; readonly id: string }
|
|
272
|
+
/**
|
|
273
|
+
* A geometry the application (or an adapter) lends under `id` with
|
|
274
|
+
* `store.lendGeometry`: drawn while lent, empty until then. Never disposed by the scene.
|
|
275
|
+
*/
|
|
276
|
+
| { readonly _tag: 'LentGeometry'; readonly id: string };
|
|
277
|
+
|
|
278
|
+
/** A material owned by one mesh, or shared by id (`SharedMaterial`). */
|
|
279
|
+
export type MaterialRef =
|
|
280
|
+
| SurfaceMaterial
|
|
281
|
+
| { readonly _tag: 'SharedMaterial'; readonly id: string };
|
|
282
|
+
|
|
283
|
+
/** A shared geometry definition. */
|
|
284
|
+
export type GeometryDefinition = { readonly id: string; readonly geometry: ShapeGeometry };
|
|
285
|
+
|
|
286
|
+
/** A shared material definition. */
|
|
287
|
+
export type MaterialDefinition = { readonly id: string; readonly material: SurfaceMaterial };
|
|
288
|
+
|
|
289
|
+
/** Shared resource definitions referenced by `SharedGeometry` and `SharedMaterial`. */
|
|
290
|
+
export type ResourceDefinitions = {
|
|
291
|
+
readonly geometries: ReadonlyArray<GeometryDefinition>;
|
|
292
|
+
readonly materials: ReadonlyArray<MaterialDefinition>;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Names a behaviour registered with the scene, with its numeric parameters: React Three
|
|
297
|
+
* Fiber's `useFrame` animation, as data. The behaviour is a pure function of scene time
|
|
298
|
+
* and these parameters, adding a position offset, a rotation and a scale factor on top
|
|
299
|
+
* of the node's own transform (eased or not), as Drei's `Float` does with an inner group.
|
|
300
|
+
*/
|
|
301
|
+
export type Behave = {
|
|
302
|
+
readonly name: string;
|
|
303
|
+
readonly params: Readonly<Record<string, number>>;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/** How a transition progresses from 0 to 1. */
|
|
307
|
+
export type Easing = 'linear' | 'easeInOutCubic' | 'easeOutCubic' | 'easeOutBack';
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* How `position` and `scale` reach new values. The Model always owns the target; a
|
|
311
|
+
* transition only decides how the rendered value travels there.
|
|
312
|
+
*
|
|
313
|
+
* - `Instant`: jump to the new value.
|
|
314
|
+
* - `Ease`: travel over `seconds` of scene time. A new target mid-flight restarts the
|
|
315
|
+
* transition from the pose at the last frame, so nothing jumps.
|
|
316
|
+
*/
|
|
317
|
+
export type Transition =
|
|
318
|
+
| { readonly _tag: 'Instant' }
|
|
319
|
+
| { readonly _tag: 'Ease'; readonly seconds: number; readonly easing: Easing };
|
|
320
|
+
|
|
321
|
+
/** A transform node that may contain children. */
|
|
322
|
+
export type GroupNode = {
|
|
323
|
+
readonly _tag: 'Group';
|
|
324
|
+
readonly key: string;
|
|
325
|
+
readonly position: Vec3;
|
|
326
|
+
readonly rotation: Rotation;
|
|
327
|
+
readonly scale: Vec3;
|
|
328
|
+
readonly transition: Transition;
|
|
329
|
+
/** A registered behaviour moving the node on top of its transform, or `null`. */
|
|
330
|
+
readonly behaviour: Behave | null;
|
|
331
|
+
/**
|
|
332
|
+
* Makes every mesh inside the group pickable, interactive or not. Events still report
|
|
333
|
+
* the mesh hit; its `path` names this group, so one handler can serve the whole group.
|
|
334
|
+
*/
|
|
335
|
+
readonly interactive: boolean;
|
|
336
|
+
readonly children: ReadonlyArray<SceneNode>;
|
|
337
|
+
/** A rigid body whose colliders are every mesh inside the group, or `null`. */
|
|
338
|
+
readonly body: Body | null;
|
|
339
|
+
/**
|
|
340
|
+
* A tracked space the group follows while a session presents the scene (pmndrs/xr's
|
|
341
|
+
* `XRSpace`): it sits where the space is each frame, and is hidden while the space is
|
|
342
|
+
* not tracked (or no session presents). `null` for the group's own transform.
|
|
343
|
+
*/
|
|
344
|
+
readonly follow: XrSpace | null;
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
/** The joints of a tracked hand, as WebXR names them (`XRHandJoint`). */
|
|
348
|
+
export const handJoints = [
|
|
349
|
+
'wrist',
|
|
350
|
+
'thumb-metacarpal',
|
|
351
|
+
'thumb-phalanx-proximal',
|
|
352
|
+
'thumb-phalanx-distal',
|
|
353
|
+
'thumb-tip',
|
|
354
|
+
'index-finger-metacarpal',
|
|
355
|
+
'index-finger-phalanx-proximal',
|
|
356
|
+
'index-finger-phalanx-intermediate',
|
|
357
|
+
'index-finger-phalanx-distal',
|
|
358
|
+
'index-finger-tip',
|
|
359
|
+
'middle-finger-metacarpal',
|
|
360
|
+
'middle-finger-phalanx-proximal',
|
|
361
|
+
'middle-finger-phalanx-intermediate',
|
|
362
|
+
'middle-finger-phalanx-distal',
|
|
363
|
+
'middle-finger-tip',
|
|
364
|
+
'ring-finger-metacarpal',
|
|
365
|
+
'ring-finger-phalanx-proximal',
|
|
366
|
+
'ring-finger-phalanx-intermediate',
|
|
367
|
+
'ring-finger-phalanx-distal',
|
|
368
|
+
'ring-finger-tip',
|
|
369
|
+
'pinky-finger-metacarpal',
|
|
370
|
+
'pinky-finger-phalanx-proximal',
|
|
371
|
+
'pinky-finger-phalanx-intermediate',
|
|
372
|
+
'pinky-finger-phalanx-distal',
|
|
373
|
+
'pinky-finger-tip',
|
|
374
|
+
] as const;
|
|
375
|
+
|
|
376
|
+
export type HandJoint = (typeof handJoints)[number];
|
|
377
|
+
|
|
378
|
+
/** Which hand: a tracked hand's, or the controller held in it. */
|
|
379
|
+
export type Handedness = 'left' | 'right';
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* A space an immersive session tracks: the head, a hand's joint, a controller's grip or
|
|
383
|
+
* pointing ray, an anchor the scene placed (`xr({ anchors })`), a detected plane
|
|
384
|
+
* (`xr({ planes: true })`, ids from `XrPlanes` events) or a detected mesh
|
|
385
|
+
* (`xr({ meshes: true })`, ids from `XrMeshes` events).
|
|
386
|
+
*/
|
|
387
|
+
export type XrSpace =
|
|
388
|
+
| { readonly _tag: 'Head' }
|
|
389
|
+
| { readonly _tag: 'Joint'; readonly hand: Handedness; readonly joint: HandJoint }
|
|
390
|
+
| { readonly _tag: 'Controller'; readonly hand: Handedness; readonly space: 'grip' | 'ray' }
|
|
391
|
+
| { readonly _tag: 'Anchor'; readonly id: string }
|
|
392
|
+
| { readonly _tag: 'Plane'; readonly id: string }
|
|
393
|
+
| { readonly _tag: 'Mesh'; readonly id: string };
|
|
394
|
+
|
|
395
|
+
/** A renderable mesh. `interactive` meshes take part in pointer hit testing. */
|
|
396
|
+
export type MeshNode = {
|
|
397
|
+
readonly _tag: 'Mesh';
|
|
398
|
+
readonly key: string;
|
|
399
|
+
readonly position: Vec3;
|
|
400
|
+
readonly rotation: Rotation;
|
|
401
|
+
readonly scale: Vec3;
|
|
402
|
+
readonly transition: Transition;
|
|
403
|
+
/** A registered behaviour moving the node on top of its transform, or `null`. */
|
|
404
|
+
readonly behaviour: Behave | null;
|
|
405
|
+
readonly geometry: GeometryRef;
|
|
406
|
+
readonly material: MaterialRef;
|
|
407
|
+
readonly interactive: boolean;
|
|
408
|
+
/** Casts shadows from lights with `castShadow`, when the scene enables shadows. */
|
|
409
|
+
readonly castShadow: boolean;
|
|
410
|
+
/** Receives shadows, when the scene enables shadows. */
|
|
411
|
+
readonly receiveShadow: boolean;
|
|
412
|
+
/** A rigid body simulating the mesh, when the scene has `physics`; `null` for none. */
|
|
413
|
+
readonly body: Body | null;
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* How a body moves, as react-three-rapier's `RigidBody` `type`:
|
|
418
|
+
*
|
|
419
|
+
* - `dynamic`: the simulation owns its pose from its starting transform.
|
|
420
|
+
* - `fixed`: it never moves; other bodies hit it.
|
|
421
|
+
* - `kinematic`: it follows the node's own transform (with its transition and behaviour),
|
|
422
|
+
* pushing dynamic bodies out of the way.
|
|
423
|
+
*/
|
|
424
|
+
export type BodyType = 'dynamic' | 'fixed' | 'kinematic';
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* The collider made from the mesh's geometry (react-three-rapier's `colliders`):
|
|
428
|
+
* `cuboid` its bounding box, `ball` its bounding sphere, `hull` the convex hull of its
|
|
429
|
+
* vertices, `trimesh` its triangles (for fixed bodies).
|
|
430
|
+
*/
|
|
431
|
+
export type BodyCollider = 'cuboid' | 'ball' | 'hull' | 'trimesh';
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* A collider's own shape, as react-three-rapier's collider components take one
|
|
435
|
+
* (`CuboidCollider`, `BallCollider`, `CapsuleCollider`, `CylinderCollider`,
|
|
436
|
+
* `ConeCollider`): sizes in the body's units. Capsules, cylinders and cones stand along y.
|
|
437
|
+
*/
|
|
438
|
+
export type ColliderShapeDescription =
|
|
439
|
+
| { readonly _tag: 'Cuboid'; readonly halfExtents: Vec3 }
|
|
440
|
+
| { readonly _tag: 'Ball'; readonly radius: number }
|
|
441
|
+
| { readonly _tag: 'Capsule'; readonly halfHeight: number; readonly radius: number }
|
|
442
|
+
| { readonly _tag: 'Cylinder'; readonly halfHeight: number; readonly radius: number }
|
|
443
|
+
| { readonly _tag: 'Cone'; readonly halfHeight: number; readonly radius: number };
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* A collider placed in its body: where its middle is and how it is turned (Euler), and a
|
|
447
|
+
* name collisions report it by (`null` for none).
|
|
448
|
+
*/
|
|
449
|
+
export type ColliderDescription = {
|
|
450
|
+
readonly shape: ColliderShapeDescription;
|
|
451
|
+
readonly position: Vec3;
|
|
452
|
+
readonly rotation: Vec3;
|
|
453
|
+
readonly name: string | null;
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* A rigid body (react-three-rapier `RigidBody` at `ae5c3fe`). The node's transform is
|
|
458
|
+
* where a dynamic body starts; changing its position or rotation later teleports it there
|
|
459
|
+
* at rest. An `impulse` is applied once, when its `id` is new.
|
|
460
|
+
*/
|
|
461
|
+
export type Body = {
|
|
462
|
+
readonly type: BodyType;
|
|
463
|
+
readonly collider: BodyCollider;
|
|
464
|
+
/** Total mass; `null` for density 1 over the collider's volume (Rapier's default). */
|
|
465
|
+
readonly mass: number | null;
|
|
466
|
+
readonly friction: number;
|
|
467
|
+
readonly restitution: number;
|
|
468
|
+
readonly linearDamping: number;
|
|
469
|
+
readonly angularDamping: number;
|
|
470
|
+
readonly gravityScale: number;
|
|
471
|
+
/** Continuous collision detection, for fast small bodies. */
|
|
472
|
+
readonly ccd: boolean;
|
|
473
|
+
/** Reports overlaps as collisions without pushing anything. */
|
|
474
|
+
readonly sensor: boolean;
|
|
475
|
+
/** Velocities it starts with. */
|
|
476
|
+
readonly linearVelocity: Vec3;
|
|
477
|
+
readonly angularVelocity: Vec3;
|
|
478
|
+
readonly impulse: { readonly id: number; readonly impulse: Vec3 } | null;
|
|
479
|
+
/**
|
|
480
|
+
* Colliders of its own, replacing those worked out from its geometry (`collider`), as
|
|
481
|
+
* react-three-rapier's `colliders={false}` with collider children; `null` for those.
|
|
482
|
+
* Sized in the body's units and scaled with it.
|
|
483
|
+
*/
|
|
484
|
+
readonly colliders: ReadonlyArray<ColliderDescription> | null;
|
|
485
|
+
/**
|
|
486
|
+
* Report contact forces above this many newtons as `ContactForce` events
|
|
487
|
+
* (react-three-rapier's `onContactForce`, Rapier's `contactForceEventThreshold`); `null`
|
|
488
|
+
* for none. Rapier reports every step a contact pushes that hard, so set it high.
|
|
489
|
+
*/
|
|
490
|
+
readonly contactForces: number | null;
|
|
491
|
+
/**
|
|
492
|
+
* Which bodies it collides with at all (react-three-rapier's `collisionGroups`); `null`
|
|
493
|
+
* for every body. Two bodies collide when each is in a group the other's filters name.
|
|
494
|
+
*/
|
|
495
|
+
readonly collisionGroups: InteractionGroups | null;
|
|
496
|
+
/**
|
|
497
|
+
* Which bodies push it back (`solverGroups`): contacts still happen and are reported,
|
|
498
|
+
* but only these groups exert forces on each other; `null` for every body.
|
|
499
|
+
*/
|
|
500
|
+
readonly solverGroups: InteractionGroups | null;
|
|
501
|
+
};
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Groups for collision filtering, as react-three-rapier's `interactionGroups`: the groups
|
|
505
|
+
* (0 to 15) a body is in, and those it interacts with (`null` for all of them).
|
|
506
|
+
*/
|
|
507
|
+
export type InteractionGroups = {
|
|
508
|
+
readonly memberships: ReadonlyArray<number>;
|
|
509
|
+
readonly filters: ReadonlyArray<number> | null;
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* The scene's physics world (react-three-rapier `Physics`): gravity, pausing, and the
|
|
514
|
+
* fixed step it advances by, interpolating poses between steps.
|
|
515
|
+
*/
|
|
516
|
+
export type Physics = {
|
|
517
|
+
readonly gravity: Vec3;
|
|
518
|
+
readonly paused: boolean;
|
|
519
|
+
readonly timeStep: number;
|
|
520
|
+
readonly interpolate: boolean;
|
|
521
|
+
/** Draw every collider and joint as lines, as react-three-rapier's `<Physics debug>`. */
|
|
522
|
+
readonly debug: boolean;
|
|
523
|
+
/** Joints between bodies, each active while both its bodies exist. */
|
|
524
|
+
readonly joints: ReadonlyArray<Joint>;
|
|
525
|
+
};
|
|
526
|
+
|
|
527
|
+
/** A body a joint holds: a node's, or one instance's of an instances node. */
|
|
528
|
+
export type BodyRef = { readonly key: string; readonly instance: string | null };
|
|
529
|
+
|
|
530
|
+
/** A joint's range of motion, `[min, max]`: radians for a revolute joint, units for a prismatic one. */
|
|
531
|
+
export type JointLimits = readonly [min: number, max: number];
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Drives a hinge or slider toward `position` (radians or units) at `velocity`, as Rapier's
|
|
535
|
+
* `configureMotor(targetPos, targetVel, stiffness, damping)`: a spring of `stiffness` pulls
|
|
536
|
+
* toward the position, and `damping` toward the velocity. A velocity motor has stiffness 0;
|
|
537
|
+
* a position motor, velocity 0.
|
|
538
|
+
*/
|
|
539
|
+
export type JointMotor = {
|
|
540
|
+
readonly position: number;
|
|
541
|
+
readonly velocity: number;
|
|
542
|
+
readonly stiffness: number;
|
|
543
|
+
readonly damping: number;
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* How a joint holds its two bodies: Rapier's impulse joints, as react-three-rapier's
|
|
548
|
+
* `useFixedJoint`, `useSphericalJoint`, `useRevoluteJoint`, `usePrismaticJoint`,
|
|
549
|
+
* `useRopeJoint` and `useSpringJoint` make them (`ae5c3fe`, `src/hooks/joints.ts`).
|
|
550
|
+
*/
|
|
551
|
+
export type JointKind =
|
|
552
|
+
/** No relative motion: each body's frame (Euler angles) at its anchor coincide. */
|
|
553
|
+
| { readonly _tag: 'Fixed'; readonly frameA: Vec3; readonly frameB: Vec3 }
|
|
554
|
+
/** The anchors coincide; any rotation about them (a ball and socket). */
|
|
555
|
+
| { readonly _tag: 'Spherical' }
|
|
556
|
+
/** The anchors coincide; rotation about `axis` only (a hinge), driven by `motor`. */
|
|
557
|
+
| {
|
|
558
|
+
readonly _tag: 'Revolute';
|
|
559
|
+
readonly axis: Vec3;
|
|
560
|
+
readonly limits: JointLimits | null;
|
|
561
|
+
readonly motor: JointMotor | null;
|
|
562
|
+
}
|
|
563
|
+
/** Sliding along `axis` only, driven by `motor`. */
|
|
564
|
+
| {
|
|
565
|
+
readonly _tag: 'Prismatic';
|
|
566
|
+
readonly axis: Vec3;
|
|
567
|
+
readonly limits: JointLimits | null;
|
|
568
|
+
readonly motor: JointMotor | null;
|
|
569
|
+
}
|
|
570
|
+
/** The anchors at most `length` apart. */
|
|
571
|
+
| { readonly _tag: 'Rope'; readonly length: number }
|
|
572
|
+
/** A force pulling the anchors towards `restLength` apart. */
|
|
573
|
+
| {
|
|
574
|
+
readonly _tag: 'Spring';
|
|
575
|
+
readonly restLength: number;
|
|
576
|
+
readonly stiffness: number;
|
|
577
|
+
readonly damping: number;
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* A joint between bodies `a` and `b`. Each anchor is in its body's own space: from the
|
|
582
|
+
* node's origin, turned with it, unscaled.
|
|
583
|
+
*/
|
|
584
|
+
export type Joint = {
|
|
585
|
+
readonly key: string;
|
|
586
|
+
readonly a: BodyRef;
|
|
587
|
+
readonly b: BodyRef;
|
|
588
|
+
readonly anchorA: Vec3;
|
|
589
|
+
readonly anchorB: Vec3;
|
|
590
|
+
readonly kind: JointKind;
|
|
591
|
+
/** Whether the two bodies still collide with each other (Rapier's default: they do). */
|
|
592
|
+
readonly contacts: boolean;
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* One copy of an instanced mesh. `key` is unique within its `instances` node and comes
|
|
597
|
+
* back in hit events. `color` multiplies the material's colour, so use a white material
|
|
598
|
+
* for exact per-instance colours. Rotation is fixed Euler angles: instances have no
|
|
599
|
+
* behaviours or transitions of their own.
|
|
600
|
+
*/
|
|
601
|
+
export type Instance = {
|
|
602
|
+
readonly key: string;
|
|
603
|
+
readonly position: Vec3;
|
|
604
|
+
readonly rotation: Vec3;
|
|
605
|
+
readonly scale: Vec3;
|
|
606
|
+
readonly color: Rgb;
|
|
607
|
+
};
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Many copies of one geometry and material in a single draw call (three.js's
|
|
611
|
+
* `InstancedMesh`). The node itself is placed like a mesh; its instances are placed
|
|
612
|
+
* inside it. Changing instances rewrites only the slots that changed.
|
|
613
|
+
*/
|
|
614
|
+
export type InstancesNode = {
|
|
615
|
+
readonly _tag: 'Instances';
|
|
616
|
+
readonly key: string;
|
|
617
|
+
readonly position: Vec3;
|
|
618
|
+
readonly rotation: Rotation;
|
|
619
|
+
readonly scale: Vec3;
|
|
620
|
+
readonly transition: Transition;
|
|
621
|
+
/** A registered behaviour moving the node on top of its transform, or `null`. */
|
|
622
|
+
readonly behaviour: Behave | null;
|
|
623
|
+
readonly geometry: GeometryRef;
|
|
624
|
+
readonly material: MaterialRef;
|
|
625
|
+
readonly interactive: boolean;
|
|
626
|
+
readonly castShadow: boolean;
|
|
627
|
+
readonly receiveShadow: boolean;
|
|
628
|
+
readonly instances: ReadonlyArray<Instance>;
|
|
629
|
+
/**
|
|
630
|
+
* A rigid body for every instance, all with these settings, or `null`: react-three-rapier's
|
|
631
|
+
* `InstancedRigidBodies`. Each instance's collider is the geometry at its scale.
|
|
632
|
+
*/
|
|
633
|
+
readonly body: Body | null;
|
|
634
|
+
};
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* Shows a three.js object the application lent to the resource store under `id`: React
|
|
638
|
+
* Three Fiber's `<primitive>`, by reference rather than by value, so descriptions stay
|
|
639
|
+
* plain data. The node's transform applies to a wrapper, leaving the object's own as the
|
|
640
|
+
* application set it. The object is never disposed. Until something is lent under `id`
|
|
641
|
+
* the node is empty, so a description can name a model that is still loading.
|
|
642
|
+
*/
|
|
643
|
+
export type BorrowedNode = {
|
|
644
|
+
readonly _tag: 'Borrowed';
|
|
645
|
+
readonly key: string;
|
|
646
|
+
readonly id: string;
|
|
647
|
+
readonly position: Vec3;
|
|
648
|
+
readonly rotation: Rotation;
|
|
649
|
+
readonly scale: Vec3;
|
|
650
|
+
readonly transition: Transition;
|
|
651
|
+
/** A registered behaviour moving the node on top of its transform, or `null`. */
|
|
652
|
+
readonly behaviour: Behave | null;
|
|
653
|
+
/** Makes every mesh inside the object pickable; hits name the part by its `name`. */
|
|
654
|
+
readonly interactive: boolean;
|
|
655
|
+
/** An animation clip of the lent object to play, or `null` for none. */
|
|
656
|
+
readonly animation: Animation | null;
|
|
657
|
+
/** A rigid body whose colliders are the model's meshes, once it is lent; or `null`. */
|
|
658
|
+
readonly body: Body | null;
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
/** Where a label's origin is along its width: an edge, the middle, or a fraction of it. */
|
|
662
|
+
export type LabelAnchorX = 'left' | 'center' | 'right' | number;
|
|
663
|
+
|
|
664
|
+
/** Where a label's origin is along its height: an edge, a baseline, the middle, or a fraction. */
|
|
665
|
+
export type LabelAnchorY =
|
|
666
|
+
| 'top'
|
|
667
|
+
| 'top-baseline'
|
|
668
|
+
| 'middle'
|
|
669
|
+
| 'bottom-baseline'
|
|
670
|
+
| 'bottom'
|
|
671
|
+
| number;
|
|
672
|
+
|
|
673
|
+
/** How a label's lines line up within its block. */
|
|
674
|
+
export type LabelAlign = 'left' | 'right' | 'center' | 'justify';
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Crisp text at any size, drawn from glyph distance fields: Drei's `Text` (troika's
|
|
678
|
+
* `Text`, `bf6f4ad` `src/core/Text.tsx`). `font` is the URL of a TTF, OTF or WOFF file,
|
|
679
|
+
* or `null` for troika's default. A label is drawn by the scene graph's label engine (in
|
|
680
|
+
* Foldkit, the environment's); without one it is empty. Fonts load and glyphs build in the
|
|
681
|
+
* background, and the scene redraws when they are ready.
|
|
682
|
+
*/
|
|
683
|
+
export type LabelNode = {
|
|
684
|
+
readonly _tag: 'Label';
|
|
685
|
+
readonly key: string;
|
|
686
|
+
readonly position: Vec3;
|
|
687
|
+
readonly rotation: Rotation;
|
|
688
|
+
readonly scale: Vec3;
|
|
689
|
+
readonly transition: Transition;
|
|
690
|
+
readonly behaviour: Behave | null;
|
|
691
|
+
/** Makes the label pickable, over its glyphs' bounds. */
|
|
692
|
+
readonly interactive: boolean;
|
|
693
|
+
readonly text: string;
|
|
694
|
+
readonly font: string | null;
|
|
695
|
+
/** The em height, in scene units. */
|
|
696
|
+
readonly fontSize: number;
|
|
697
|
+
readonly color: Rgb;
|
|
698
|
+
readonly fillOpacity: number;
|
|
699
|
+
readonly anchorX: LabelAnchorX;
|
|
700
|
+
readonly anchorY: LabelAnchorY;
|
|
701
|
+
/** Wraps lines longer than this, in scene units; `null` never wraps. */
|
|
702
|
+
readonly maxWidth: number | null;
|
|
703
|
+
/** Line spacing as a multiple of `fontSize`; `null` for the font's own ("normal"). */
|
|
704
|
+
readonly lineHeight: number | null;
|
|
705
|
+
/** Extra space between letters, in ems. */
|
|
706
|
+
readonly letterSpacing: number;
|
|
707
|
+
readonly textAlign: LabelAlign;
|
|
708
|
+
/** An outline around the glyphs, in scene units (0 for none), and its look. */
|
|
709
|
+
readonly outlineWidth: number;
|
|
710
|
+
readonly outlineColor: Rgb;
|
|
711
|
+
readonly outlineOpacity: number;
|
|
712
|
+
readonly outlineBlur: number;
|
|
713
|
+
/**
|
|
714
|
+
* Colours for runs of characters, overriding `color` from each `start` (a character
|
|
715
|
+
* index) to the next: troika's `colorRanges`, as a list.
|
|
716
|
+
*/
|
|
717
|
+
readonly colorRanges: ReadonlyArray<LabelColorRange>;
|
|
718
|
+
/**
|
|
719
|
+
* Curves the text round a vertical cylinder this far away, in scene units: positive in
|
|
720
|
+
* front (concave), negative behind (convex), 0 flat. troika's `curveRadius`.
|
|
721
|
+
*/
|
|
722
|
+
readonly curveRadius: number;
|
|
723
|
+
/**
|
|
724
|
+
* A material for the glyphs to be drawn with (lit by the scene, say), as troika takes a
|
|
725
|
+
* base material and derives its text material from it; `color` still colours them.
|
|
726
|
+
* `null` for troika's own unlit one.
|
|
727
|
+
*/
|
|
728
|
+
readonly material: MaterialRef | null;
|
|
729
|
+
};
|
|
730
|
+
|
|
731
|
+
/** A run of a label's characters in another colour, from character index `start`. */
|
|
732
|
+
export type LabelColorRange = { readonly start: number; readonly color: Rgb };
|
|
733
|
+
|
|
734
|
+
/**
|
|
735
|
+
* Plays the clip named `clip` from the borrowed object's `animations`. Playback is a
|
|
736
|
+
* function of scene time, like `spin`: it pauses with the scene and rewinds with it.
|
|
737
|
+
* `speed` scales time (negative plays backwards); `loop: false` holds the last frame.
|
|
738
|
+
* Changing the animation restarts it from the current scene time; removing it returns
|
|
739
|
+
* the object to its rest pose.
|
|
740
|
+
*/
|
|
741
|
+
export type Animation = {
|
|
742
|
+
readonly clip: string;
|
|
743
|
+
readonly speed: number;
|
|
744
|
+
readonly loop: boolean;
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
/** Uniform ambient light. */
|
|
748
|
+
export type AmbientLightNode = {
|
|
749
|
+
readonly _tag: 'AmbientLight';
|
|
750
|
+
readonly key: string;
|
|
751
|
+
readonly color: Rgb;
|
|
752
|
+
readonly intensity: number;
|
|
753
|
+
};
|
|
754
|
+
|
|
755
|
+
/** Directional light shining from `position` towards the origin. */
|
|
756
|
+
export type DirectionalLightNode = {
|
|
757
|
+
readonly _tag: 'DirectionalLight';
|
|
758
|
+
readonly key: string;
|
|
759
|
+
readonly color: Rgb;
|
|
760
|
+
readonly intensity: number;
|
|
761
|
+
readonly position: Vec3;
|
|
762
|
+
/** Renders a shadow map from this light, when the scene enables shadows. */
|
|
763
|
+
readonly castShadow: boolean;
|
|
764
|
+
/** Shadow map width and height in texels: a power of two. */
|
|
765
|
+
readonly shadowMapSize: number;
|
|
766
|
+
/** Depth offset that removes shadow acne; usually a small negative number. */
|
|
767
|
+
readonly shadowBias: number;
|
|
768
|
+
/** Half the width and height, in world units, of the area the shadow covers. */
|
|
769
|
+
readonly shadowArea: number;
|
|
770
|
+
};
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* A light shining in every direction from `position`. `distance` 0 means no cut-off;
|
|
774
|
+
* `decay` 2 is physically correct.
|
|
775
|
+
*/
|
|
776
|
+
export type PointLightNode = {
|
|
777
|
+
readonly _tag: 'PointLight';
|
|
778
|
+
readonly key: string;
|
|
779
|
+
readonly color: Rgb;
|
|
780
|
+
readonly intensity: number;
|
|
781
|
+
readonly position: Vec3;
|
|
782
|
+
readonly distance: number;
|
|
783
|
+
readonly decay: number /** Renders a shadow map from this light, when the scene enables shadows. */;
|
|
784
|
+
readonly castShadow: boolean;
|
|
785
|
+
/** Shadow map width and height in texels: a power of two. */
|
|
786
|
+
readonly shadowMapSize: number;
|
|
787
|
+
/** Depth offset that removes shadow acne; usually a small negative number. */
|
|
788
|
+
readonly shadowBias: number;
|
|
789
|
+
};
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* A cone of light from `position` towards `target`, both in world space. `angle` is the
|
|
793
|
+
* cone's half-angle in radians; `penumbra` (0 to 1) softens its edge.
|
|
794
|
+
*/
|
|
795
|
+
export type SpotLightNode = {
|
|
796
|
+
readonly _tag: 'SpotLight';
|
|
797
|
+
readonly key: string;
|
|
798
|
+
readonly color: Rgb;
|
|
799
|
+
readonly intensity: number;
|
|
800
|
+
readonly position: Vec3;
|
|
801
|
+
readonly target: Vec3;
|
|
802
|
+
readonly distance: number;
|
|
803
|
+
readonly angle: number;
|
|
804
|
+
readonly penumbra: number;
|
|
805
|
+
readonly decay: number /** Renders a shadow map from this light, when the scene enables shadows. */;
|
|
806
|
+
readonly castShadow: boolean;
|
|
807
|
+
/** Shadow map width and height in texels: a power of two. */
|
|
808
|
+
readonly shadowMapSize: number;
|
|
809
|
+
/** Depth offset that removes shadow acne; usually a small negative number. */
|
|
810
|
+
readonly shadowBias: number;
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
/** Sky-to-ground gradient light: `color` from above `position`, `groundColor` from below. */
|
|
814
|
+
export type HemisphereLightNode = {
|
|
815
|
+
readonly _tag: 'HemisphereLight';
|
|
816
|
+
readonly key: string;
|
|
817
|
+
readonly color: Rgb;
|
|
818
|
+
readonly groundColor: Rgb;
|
|
819
|
+
readonly intensity: number;
|
|
820
|
+
readonly position: Vec3;
|
|
821
|
+
};
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* A square grid of lines on the XZ plane, three.js's `GridHelper`: `size` across, cut
|
|
825
|
+
* into `divisions` cells, with the two middle lines in `centerColor`. (Drei's `Grid` is a
|
|
826
|
+
* fading shader grid; this is the plain helper.)
|
|
827
|
+
*/
|
|
828
|
+
export type GridNode = {
|
|
829
|
+
readonly _tag: 'Grid';
|
|
830
|
+
readonly key: string;
|
|
831
|
+
readonly position: Vec3;
|
|
832
|
+
readonly size: number;
|
|
833
|
+
readonly divisions: number;
|
|
834
|
+
readonly color: Rgb;
|
|
835
|
+
readonly centerColor: Rgb;
|
|
836
|
+
};
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Drei's `Grid`: a plane whose shader draws cell lines and section lines on the XZ plane,
|
|
840
|
+
* fading with distance from the camera's foot on it. `size` is the plane's
|
|
841
|
+
* `[width, height]`; `infinite` stretches it as far as the fade reaches, and
|
|
842
|
+
* `followCamera` slides it under the camera. `fadeFrom` 1 fades from the camera, 0 from
|
|
843
|
+
* the grid's origin. Its rotation is fixed Euler angles.
|
|
844
|
+
*/
|
|
845
|
+
export type ShaderGridNode = {
|
|
846
|
+
readonly _tag: 'ShaderGrid';
|
|
847
|
+
readonly key: string;
|
|
848
|
+
readonly position: Vec3;
|
|
849
|
+
readonly rotation: Vec3;
|
|
850
|
+
readonly size: readonly [width: number, height: number];
|
|
851
|
+
readonly cellSize: number;
|
|
852
|
+
readonly cellThickness: number;
|
|
853
|
+
readonly cellColor: Rgb;
|
|
854
|
+
readonly sectionSize: number;
|
|
855
|
+
readonly sectionThickness: number;
|
|
856
|
+
readonly sectionColor: Rgb;
|
|
857
|
+
readonly infinite: boolean;
|
|
858
|
+
readonly followCamera: boolean;
|
|
859
|
+
readonly fadeDistance: number;
|
|
860
|
+
readonly fadeStrength: number;
|
|
861
|
+
readonly fadeFrom: number;
|
|
862
|
+
readonly side: MaterialSide;
|
|
863
|
+
};
|
|
864
|
+
|
|
865
|
+
/** Any node in a scene. Keys are unique across the whole scene. */
|
|
866
|
+
export type SceneNode =
|
|
867
|
+
| GridNode
|
|
868
|
+
| ShaderGridNode
|
|
869
|
+
| GroupNode
|
|
870
|
+
| MeshNode
|
|
871
|
+
| InstancesNode
|
|
872
|
+
| BorrowedNode
|
|
873
|
+
| LabelNode
|
|
874
|
+
| AmbientLightNode
|
|
875
|
+
| DirectionalLightNode
|
|
876
|
+
| PointLightNode
|
|
877
|
+
| SpotLightNode
|
|
878
|
+
| HemisphereLightNode;
|
|
879
|
+
|
|
880
|
+
/** The node kinds the kernel knows how to host. */
|
|
881
|
+
export type NodeKind = SceneNode['_tag'];
|
|
882
|
+
|
|
883
|
+
/** A perspective camera: `fov` is the vertical field of view in degrees. */
|
|
884
|
+
export type PerspectiveCamera = {
|
|
885
|
+
readonly _tag: 'Perspective';
|
|
886
|
+
readonly fov: number;
|
|
887
|
+
readonly near: number;
|
|
888
|
+
readonly far: number;
|
|
889
|
+
readonly position: Vec3;
|
|
890
|
+
readonly lookAt: Vec3 /**
|
|
891
|
+
* How the rendered camera follows a new position, `lookAt` or zoom: 0 (the default)
|
|
892
|
+
* jumps; above 0 eases there round the target, closing that fraction of the remaining
|
|
893
|
+
* way every sixtieth of a second, as three.js's `OrbitControls.dampingFactor` (Drei's
|
|
894
|
+
* default is 0.05). Field of view, near and far always apply at once.
|
|
895
|
+
*/;
|
|
896
|
+
readonly damping: number;
|
|
897
|
+
/**
|
|
898
|
+
* Turns the rendered camera round its target, as three.js's `OrbitControls.autoRotate`
|
|
899
|
+
* at `autoRotateSpeed`: 0 (the default) is still; 2 orbits once every 30 seconds of
|
|
900
|
+
* scene time, positive clockwise seen from above. It holds still while a gesture is
|
|
901
|
+
* pressed; before a gesture an `AutoRotated` event says where it got to, for the Model
|
|
902
|
+
* (`autoRotated(camera, detail)`). A new position or `lookAt` turns on from there.
|
|
903
|
+
*/
|
|
904
|
+
readonly autoRotate: number;
|
|
905
|
+
};
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* An orthographic camera. As in React Three Fiber, the frustum follows the viewport in
|
|
909
|
+
* CSS pixels and `zoom` is CSS pixels per world unit, so objects keep their on-screen
|
|
910
|
+
* size when the viewport resizes.
|
|
911
|
+
*/
|
|
912
|
+
export type OrthographicCamera = {
|
|
913
|
+
readonly _tag: 'Orthographic';
|
|
914
|
+
readonly zoom: number;
|
|
915
|
+
readonly near: number;
|
|
916
|
+
readonly far: number;
|
|
917
|
+
readonly position: Vec3;
|
|
918
|
+
readonly lookAt: Vec3 /** As on `PerspectiveCamera`. */;
|
|
919
|
+
readonly damping: number;
|
|
920
|
+
/** As on `PerspectiveCamera`. */
|
|
921
|
+
readonly autoRotate: number;
|
|
922
|
+
};
|
|
923
|
+
|
|
924
|
+
/** The single active camera. */
|
|
925
|
+
export type Camera = PerspectiveCamera | OrthographicCamera;
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* Shadow map filtering, as React Three Fiber names it: `basic` (hard), `percentage` (PCF),
|
|
929
|
+
* `soft` (PCF soft) or `variance` (VSM). `off` disables shadows.
|
|
930
|
+
*/
|
|
931
|
+
export type ShadowMode = 'off' | 'basic' | 'percentage' | 'soft' | 'variance';
|
|
932
|
+
|
|
933
|
+
/** How the renderer maps scene light to screen colour. */
|
|
934
|
+
export type ToneMapping = 'none' | 'linear' | 'reinhard' | 'cineon' | 'aces' | 'agx' | 'neutral';
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* When frames render, as React Three Fiber's `frameloop`: `always` every display frame,
|
|
938
|
+
* `demand` only when something changed or is animating, `never` only on `advance`.
|
|
939
|
+
*/
|
|
940
|
+
export type FrameMode = 'always' | 'demand' | 'never';
|
|
941
|
+
|
|
942
|
+
/**
|
|
943
|
+
* A post-processing effect, applied in order after the scene renders (three.js's
|
|
944
|
+
* `EffectComposer` passes).
|
|
945
|
+
*
|
|
946
|
+
* - `Bloom`: bright areas glow (`UnrealBloomPass`): `strength`, `radius`, and the
|
|
947
|
+
* luminance `threshold` above which pixels bloom.
|
|
948
|
+
* - `Vignette`: darkens the edges (`VignetteShader`): `offset` and `darkness`.
|
|
949
|
+
* - `Film`: animated grain (`FilmPass`): `intensity`, optionally `grayscale`.
|
|
950
|
+
*/
|
|
951
|
+
export type PostEffect =
|
|
952
|
+
| {
|
|
953
|
+
readonly _tag: 'Bloom';
|
|
954
|
+
readonly strength: number;
|
|
955
|
+
readonly radius: number;
|
|
956
|
+
readonly threshold: number;
|
|
957
|
+
}
|
|
958
|
+
| { readonly _tag: 'Vignette'; readonly offset: number; readonly darkness: number }
|
|
959
|
+
| { readonly _tag: 'Film'; readonly intensity: number; readonly grayscale: boolean };
|
|
960
|
+
|
|
961
|
+
/** Scene-wide rendering settings, changeable at any time. */
|
|
962
|
+
export type RenderSettings = {
|
|
963
|
+
/** Post-processing, in order. Empty renders straight to the screen. */
|
|
964
|
+
readonly effects: ReadonlyArray<PostEffect>;
|
|
965
|
+
readonly frames: FrameMode;
|
|
966
|
+
/**
|
|
967
|
+
* Scales the drawing buffer's pixel ratio, from just above 0 to 1. Lower it when
|
|
968
|
+
* frames are slow (see `PerformanceChanged`), as Drei's `AdaptiveDpr` does.
|
|
969
|
+
*/
|
|
970
|
+
readonly resolution: number;
|
|
971
|
+
readonly shadows: ShadowMode;
|
|
972
|
+
readonly toneMapping: ToneMapping;
|
|
973
|
+
/** Exposure for tone mapping. Ignored when `toneMapping` is `none`. */
|
|
974
|
+
readonly exposure: number;
|
|
975
|
+
/** The output colour space: `srgb` for displays, `linear` to skip the conversion. */
|
|
976
|
+
readonly colorSpace: 'srgb' | 'linear';
|
|
977
|
+
};
|
|
978
|
+
|
|
979
|
+
/** Part of the canvas, as fractions (0 to 1) of its width and height from the top left. */
|
|
980
|
+
export type ViewRect = {
|
|
981
|
+
readonly x: number;
|
|
982
|
+
readonly y: number;
|
|
983
|
+
readonly width: number;
|
|
984
|
+
readonly height: number;
|
|
985
|
+
};
|
|
986
|
+
|
|
987
|
+
/**
|
|
988
|
+
* Another camera drawing the scene into part of the canvas: Drei's `View` and R3F's
|
|
989
|
+
* split-screen portals, as data. Views draw in order, later ones on top.
|
|
990
|
+
*/
|
|
991
|
+
export type View = { readonly key: string; readonly camera: Camera; readonly rect: ViewRect };
|
|
992
|
+
|
|
993
|
+
/**
|
|
994
|
+
* A small scene rendered into a texture that materials use as `map: id`: Drei's
|
|
995
|
+
* `RenderTexture`, as data. Its nodes have their own key namespace and may use the
|
|
996
|
+
* scene's shared resources. It redraws only when it changes or animates.
|
|
997
|
+
*/
|
|
998
|
+
export type RenderTexture = {
|
|
999
|
+
readonly id: string;
|
|
1000
|
+
/** Texture size in pixels. */
|
|
1001
|
+
readonly width: number;
|
|
1002
|
+
readonly height: number;
|
|
1003
|
+
readonly camera: Camera;
|
|
1004
|
+
/** A clear colour, or `null` for transparent. */
|
|
1005
|
+
readonly background: Rgb | null;
|
|
1006
|
+
readonly children: ReadonlyArray<SceneNode>;
|
|
1007
|
+
};
|
|
1008
|
+
|
|
1009
|
+
/** A complete scene: camera, render settings, shared resources and root nodes. */
|
|
1010
|
+
/**
|
|
1011
|
+
* Who owns the pointer's gestures on the canvas.
|
|
1012
|
+
*
|
|
1013
|
+
* - `'page'` (the default): the wheel scrolls the page, touch pans it, the right button
|
|
1014
|
+
* opens the browser's menu, and the scene reports only events on interactive meshes.
|
|
1015
|
+
* - `'scene'`: the scene claims them, as three.js's `OrbitControls` does when connected,
|
|
1016
|
+
* and reports every drag, wheel and pinch on the canvas as a `Gesture`, for controls
|
|
1017
|
+
* such as `orbit` to turn into a new camera.
|
|
1018
|
+
*/
|
|
1019
|
+
export type Gestures = 'page' | 'scene';
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* A point the application shows HTML at, as Drei's `Html` (`src/web/Html.tsx` at
|
|
1023
|
+
* `bf6f4ad`, without `transform`). The scene works out where the point is on the canvas
|
|
1024
|
+
* each frame it draws; the host moves the application's HTML there.
|
|
1025
|
+
*/
|
|
1026
|
+
export type Overlay = {
|
|
1027
|
+
readonly key: string;
|
|
1028
|
+
/** The node the position is relative to, moving with it; `null` for world space. */
|
|
1029
|
+
readonly node: string | null;
|
|
1030
|
+
readonly position: Vec3;
|
|
1031
|
+
/** Centre the HTML on the point (Drei's `center`); otherwise its top left is there. */
|
|
1032
|
+
readonly center: boolean;
|
|
1033
|
+
/**
|
|
1034
|
+
* Scale the HTML with distance, as Drei's `distanceFactor`: at a distance where the
|
|
1035
|
+
* view is `distanceFactor` units tall it shows at its own size. `null` keeps its size.
|
|
1036
|
+
*/
|
|
1037
|
+
readonly distanceFactor: number | null;
|
|
1038
|
+
/** Hide the HTML while a mesh is in front of the point (Drei's `occlude`). */
|
|
1039
|
+
readonly occlude: boolean;
|
|
1040
|
+
/** z-index for points at the camera's near and far planes (Drei's `zIndexRange`). */
|
|
1041
|
+
readonly zIndexRange: readonly [near: number, far: number];
|
|
1042
|
+
/** With views: the view it is shown in. `null`: the camera, or the first view. */
|
|
1043
|
+
readonly view: string | null;
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
/**
|
|
1047
|
+
* Image-based lighting and background, as Drei's `Environment` (`src/core/Environment.tsx`
|
|
1048
|
+
* at `bf6f4ad`, `setEnvProps`). `map` names an equirectangular texture lent to the store;
|
|
1049
|
+
* `null` uses three.js's `RoomEnvironment`, a neutral studio built in code (no files).
|
|
1050
|
+
*/
|
|
1051
|
+
export type Environment = {
|
|
1052
|
+
readonly map: string | null;
|
|
1053
|
+
/** Drei's `background`: `false` lights only, `true` also shows it, `'only'` only shows it. */
|
|
1054
|
+
readonly background: boolean | 'only';
|
|
1055
|
+
readonly backgroundBlurriness: number;
|
|
1056
|
+
readonly backgroundIntensity: number;
|
|
1057
|
+
readonly environmentIntensity: number;
|
|
1058
|
+
};
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* A physically based daylight sky, three.js's `Sky` (Preetham), as Drei's `Sky`
|
|
1062
|
+
* (`src/core/Sky.tsx` at `bf6f4ad`). Drawn at the camera's far plane, never picked.
|
|
1063
|
+
*/
|
|
1064
|
+
export type Sky = {
|
|
1065
|
+
readonly sunPosition: Vec3;
|
|
1066
|
+
readonly turbidity: number;
|
|
1067
|
+
readonly rayleigh: number;
|
|
1068
|
+
readonly mieCoefficient: number;
|
|
1069
|
+
readonly mieDirectionalG: number;
|
|
1070
|
+
/** three.js 0.186's cloud cover, 0 to 1. Clouds hold still: scene time does not move them. */
|
|
1071
|
+
readonly clouds: number;
|
|
1072
|
+
/** The size of the sky box (Drei's `distance`). */
|
|
1073
|
+
readonly distance: number;
|
|
1074
|
+
};
|
|
1075
|
+
|
|
1076
|
+
/**
|
|
1077
|
+
* Soft shadows on the ground under everything, as Drei's `ContactShadows`
|
|
1078
|
+
* (`src/core/ContactShadows.tsx` at `bf6f4ad`, after three.js's `webgl_shadow_contact`
|
|
1079
|
+
* example): the scene's depth seen from below, blurred, on a plane. Redrawn with every
|
|
1080
|
+
* frame the scene draws; needs no lights or shadow maps.
|
|
1081
|
+
*/
|
|
1082
|
+
export type ContactShadows = {
|
|
1083
|
+
/** The middle of the shadow plane; it lies flat, facing up. */
|
|
1084
|
+
readonly position: Vec3;
|
|
1085
|
+
/** Width and depth of the plane, in world units (Drei's `width × scale`, `height × scale`). */
|
|
1086
|
+
readonly size: readonly [width: number, depth: number];
|
|
1087
|
+
/**
|
|
1088
|
+
* Where the shadow camera starts seeing, above the plane (Drei's `near`). Negative takes
|
|
1089
|
+
* in faces just below it, such as the flat bottoms of objects resting on the plane.
|
|
1090
|
+
*/
|
|
1091
|
+
readonly near: number;
|
|
1092
|
+
/** How far above the plane objects still cast a shadow (Drei's `far`). */
|
|
1093
|
+
readonly far: number;
|
|
1094
|
+
readonly blur: number;
|
|
1095
|
+
/** A second, finer blur pass (Drei's `smooth`). */
|
|
1096
|
+
readonly smooth: boolean;
|
|
1097
|
+
readonly opacity: number;
|
|
1098
|
+
readonly color: Rgb;
|
|
1099
|
+
/** Texels across the shadow texture. */
|
|
1100
|
+
readonly resolution: number;
|
|
1101
|
+
};
|
|
1102
|
+
|
|
1103
|
+
/**
|
|
1104
|
+
* Immersive presentation (WebXR), as `@react-three/xr`'s store and `XROrigin`
|
|
1105
|
+
* (pmndrs/xr at `0e1acd8`). Data only: an application enters a session from a user
|
|
1106
|
+
* gesture through its host (the Foldkit environment's `xr.enter`), and the scene that
|
|
1107
|
+
* describes `xr` is the one presented.
|
|
1108
|
+
*/
|
|
1109
|
+
export type Xr = {
|
|
1110
|
+
/** Where the player stands: the reference space's origin in the scene, on the floor. */
|
|
1111
|
+
readonly origin: Vec3;
|
|
1112
|
+
/** Which way the player faces at the origin: radians about +y (0 looks down −z). */
|
|
1113
|
+
readonly heading: number;
|
|
1114
|
+
/** The reference space requested (pmndrs/xr's default is `local-floor`). */
|
|
1115
|
+
readonly referenceSpace: 'local-floor' | 'local' | 'bounded-floor';
|
|
1116
|
+
/** Framebuffer scale relative to the device's default (1); lower is faster. */
|
|
1117
|
+
readonly framebufferScale: number;
|
|
1118
|
+
/**
|
|
1119
|
+
* In AR, report where a select's ray meets a real surface (`XrSurface` events), from the
|
|
1120
|
+
* session's hit tests: tap to place, as pmndrs/xr's `useXRHitTest`.
|
|
1121
|
+
*/
|
|
1122
|
+
readonly hitTest: boolean;
|
|
1123
|
+
/** Draw each input source's pointing ray and each tracked hand's joints. */
|
|
1124
|
+
readonly showInputs: boolean;
|
|
1125
|
+
/**
|
|
1126
|
+
* Places fixed in the real world, by id, where the description puts them (in the
|
|
1127
|
+
* scene's space): WebXR anchors, which the session keeps in place as it learns the room.
|
|
1128
|
+
* Groups follow them with `follow: anchorSpace(id)`.
|
|
1129
|
+
*/
|
|
1130
|
+
readonly anchors: ReadonlyArray<XrAnchor>;
|
|
1131
|
+
/** Detect the room's planes (floors, walls, tables) and report them as `XrPlanes` events. */
|
|
1132
|
+
readonly planes: boolean;
|
|
1133
|
+
/**
|
|
1134
|
+
* Detect the room's meshes (furniture, walls, the room as a whole) and report them as
|
|
1135
|
+
* `XrMeshes` events; each one's geometry is lent for `xrMesh(id)`, followed with
|
|
1136
|
+
* `meshSpace(id)`.
|
|
1137
|
+
*/
|
|
1138
|
+
readonly meshes: boolean;
|
|
1139
|
+
/** Keep the scene's HTML overlays shown during an AR session (WebXR's DOM overlay). */
|
|
1140
|
+
readonly domOverlay: boolean;
|
|
1141
|
+
/**
|
|
1142
|
+
* Glide the player with the thumbsticks while presenting, as pmndrs/xr's controller
|
|
1143
|
+
* locomotion does: the left stick moves where the head faces, the right turns. The
|
|
1144
|
+
* player's place is the session's while gliding; when the sticks come back to the
|
|
1145
|
+
* middle an `XrMoved` event says where it ended, for the Model's `origin` and
|
|
1146
|
+
* `heading`. `null` to leave the sticks to the application (`XrStick`, `locomote`).
|
|
1147
|
+
*/
|
|
1148
|
+
readonly glide: XrGlide | null;
|
|
1149
|
+
};
|
|
1150
|
+
|
|
1151
|
+
/** An anchor the description places: its id, and where in the scene (Euler rotation). */
|
|
1152
|
+
export type XrAnchor = { readonly id: string; readonly position: Vec3; readonly rotation: Vec3 };
|
|
1153
|
+
|
|
1154
|
+
/** How the sticks glide the player (pmndrs/xr's defaults: 2 m/s, a 45° snap turn). */
|
|
1155
|
+
export type XrGlide = {
|
|
1156
|
+
/** Metres per second at full stick. */
|
|
1157
|
+
readonly speed: number;
|
|
1158
|
+
/** `smooth` turns while the stick is pushed; `snap` turns once per push. */
|
|
1159
|
+
readonly turn: 'smooth' | 'snap';
|
|
1160
|
+
/** Radians per second at full stick, for a smooth turn. */
|
|
1161
|
+
readonly turnSpeed: number;
|
|
1162
|
+
/** Degrees per push, for a snap turn. */
|
|
1163
|
+
readonly snapDegrees: number;
|
|
1164
|
+
};
|
|
1165
|
+
|
|
1166
|
+
export type SceneDescription = {
|
|
1167
|
+
readonly camera: Camera;
|
|
1168
|
+
/** Whether the scene claims the pointer's gestures from the page. */
|
|
1169
|
+
readonly gestures: Gestures;
|
|
1170
|
+
/**
|
|
1171
|
+
* Views to draw instead of `camera` filling the canvas. Empty (the default) draws one
|
|
1172
|
+
* full view with `camera`.
|
|
1173
|
+
*/
|
|
1174
|
+
readonly views: ReadonlyArray<View>;
|
|
1175
|
+
/** Scenes rendered into textures for materials to use. */
|
|
1176
|
+
readonly renderTextures: ReadonlyArray<RenderTexture>;
|
|
1177
|
+
/** Points to show HTML at, placed every frame the scene draws. */
|
|
1178
|
+
readonly overlays: ReadonlyArray<Overlay>;
|
|
1179
|
+
/** Image-based lighting and background, or `null` for none. */
|
|
1180
|
+
readonly environment: Environment | null;
|
|
1181
|
+
/** A daylight sky behind everything, or `null` for none. */
|
|
1182
|
+
readonly sky: Sky | null;
|
|
1183
|
+
/** Soft shadows on the ground, or `null` for none. */
|
|
1184
|
+
readonly contactShadows: ContactShadows | null;
|
|
1185
|
+
/** A physics world for meshes with a `body`, or `null` for none. */
|
|
1186
|
+
readonly physics: Physics | null;
|
|
1187
|
+
/** How the scene is presented in an immersive session, or `null` if it never is. */
|
|
1188
|
+
readonly xr: Xr | null;
|
|
1189
|
+
/**
|
|
1190
|
+
* Nodes whose world bounding box the scene reports (`Measured` events) whenever it
|
|
1191
|
+
* changes: what Drei's `Bounds` measures, for `fitCamera`. Loaded models included.
|
|
1192
|
+
*/
|
|
1193
|
+
readonly measure: ReadonlyArray<string>;
|
|
1194
|
+
readonly render: RenderSettings;
|
|
1195
|
+
readonly resources: ResourceDefinitions;
|
|
1196
|
+
readonly children: ReadonlyArray<SceneNode>;
|
|
1197
|
+
};
|