phoria2 1.0.0 → 1.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.
Files changed (76) hide show
  1. package/README.md +71 -13
  2. package/dist/bloom.js +1 -1
  3. package/dist/charts.js +397 -384
  4. package/dist/charts.js.map +1 -1
  5. package/dist/core.js +4451 -3568
  6. package/dist/core.js.map +1 -1
  7. package/dist/edit.js +67 -67
  8. package/dist/edit.js.map +1 -1
  9. package/dist/explain.js +6 -2
  10. package/dist/explain.js.map +1 -1
  11. package/dist/gltf.js +211 -166
  12. package/dist/gltf.js.map +1 -1
  13. package/dist/motion.js +26 -26
  14. package/dist/motion.js.map +1 -1
  15. package/dist/particles.js +49 -49
  16. package/dist/particles.js.map +1 -1
  17. package/dist/passes.js +188 -86
  18. package/dist/passes.js.map +1 -1
  19. package/dist/phoria2.js +1 -1
  20. package/dist/picking.js +8 -13
  21. package/dist/picking.js.map +1 -1
  22. package/dist/snapshot.js +1 -1
  23. package/dist/tooltip.js +3 -3
  24. package/dist/tooltip.js.map +1 -1
  25. package/dist/types/OrbitControl.d.ts +6 -2
  26. package/dist/types/Raycaster.d.ts +10 -0
  27. package/dist/types/View.d.ts +64 -1
  28. package/dist/types/charts/Chart.d.ts +7 -0
  29. package/dist/types/explain.d.ts +3 -0
  30. package/dist/types/frame.d.ts +7 -0
  31. package/dist/types/geometry/Geometry.d.ts +14 -2
  32. package/dist/types/keyboard.d.ts +48 -0
  33. package/dist/types/labels.d.ts +4 -0
  34. package/dist/types/material/Material.d.ts +125 -0
  35. package/dist/types/material/Texture.d.ts +37 -5
  36. package/dist/types/scene/Node.d.ts +19 -14
  37. package/dist/types/scene/drawables.d.ts +32 -14
  38. package/dist/types/scene/lights.d.ts +16 -2
  39. package/dist/types/shadow.d.ts +2 -1
  40. package/dist/types/types.d.ts +14 -0
  41. package/dist/types/value/Color.d.ts +0 -4
  42. package/dist/types/value/Quat.d.ts +4 -2
  43. package/dist/types/webgl/WebGLRenderer.d.ts +6 -0
  44. package/dist/types/webgl/passes.d.ts +37 -13
  45. package/dist/types/webgl/resources.d.ts +24 -2
  46. package/dist/types/webgl/shaders.d.ts +4 -2
  47. package/llms-full.txt +153 -15
  48. package/package.json +4 -1
  49. package/schema/scene.schema.json +146 -1
  50. package/src/OrbitControl.js +7 -3
  51. package/src/Raycaster.js +58 -0
  52. package/src/View.js +207 -42
  53. package/src/charts/Chart.js +20 -2
  54. package/src/explain.js +6 -2
  55. package/src/frame.js +29 -9
  56. package/src/geometry/Geometry.js +24 -4
  57. package/src/gltf/load.js +50 -6
  58. package/src/keyboard.js +298 -0
  59. package/src/labels.js +4 -1
  60. package/src/material/Material.js +104 -19
  61. package/src/material/Texture.js +116 -11
  62. package/src/scene/Node.js +20 -9
  63. package/src/scene/Scene.js +2 -0
  64. package/src/scene/cameras.js +4 -1
  65. package/src/scene/drawables.js +48 -12
  66. package/src/scene/lights.js +40 -6
  67. package/src/shadow.js +27 -4
  68. package/src/types.js +6 -0
  69. package/src/value/Color.js +21 -0
  70. package/src/value/Quat.js +15 -6
  71. package/src/watch.js +25 -1
  72. package/src/webgl/WebGLRenderer.js +51 -12
  73. package/src/webgl/passes.js +190 -32
  74. package/src/webgl/picking.js +0 -1
  75. package/src/webgl/resources.js +89 -8
  76. package/src/webgl/shaders.js +350 -48
@@ -6,6 +6,16 @@ export type Cut = {
6
6
  plane: Float32Array;
7
7
  cap: boolean;
8
8
  };
9
+ export type Solid = {
10
+ node: any;
11
+ world: Float32Array;
12
+ instance: number | null;
13
+ cut: Cut | null;
14
+ x: number;
15
+ y: number;
16
+ z: number;
17
+ radius: number;
18
+ };
9
19
  export type Hit = {
10
20
  /**
11
21
  * what was hit
@@ -16,6 +16,7 @@ import type { ToneMapping, BloomOptions } from './webgl/WebGLRenderer.js';
16
16
  import type { CameraOptions } from './scene/cameras.js';
17
17
  import type { ColorInput, Vec3Input } from './types.js';
18
18
  import type { Node } from './scene/Node.js';
19
+ import type { KeyboardOptions } from './keyboard.js';
19
20
  export type RenderMode = 'auto' | 'always' | 'manual';
20
21
  export type ViewOptions = {
21
22
  /**
@@ -73,6 +74,11 @@ export type ViewOptions = {
73
74
  * (default true)
74
75
  */
75
76
  antialias?: boolean;
77
+ /**
78
+ * soft-edged outlines with round corners (default: as antialias); change it
79
+ * any time with view.renderer.outlineAntialias
80
+ */
81
+ outlineAntialias?: boolean;
76
82
  /**
77
83
  * which WebGL context draws it: 'own' gives the canvas one of
78
84
  * its own; 'shared' draws with the page's one shared context and copies the picture over, so a page can hold
@@ -101,6 +107,24 @@ export type ViewOptions = {
101
107
  * longest frame step in seconds, so a background tab doesn't jump (default 0.1)
102
108
  */
103
109
  maxDelta?: number;
110
+ /**
111
+ * cut motion short, for people it makes unwell: frame() jumps rather
112
+ * than glides, auto-rotation holds, and charts change at once with their flows still. Default 'auto': as the
113
+ * system's setting (prefers-reduced-motion), followed as it changes
114
+ */
115
+ reducedMotion?: 'auto' | boolean;
116
+ /**
117
+ * use without a pointer: the canvas joins the page's tab order, and
118
+ * the arrow keys step through what can be hovered or clicked - each with the hover tint, the tooltip and hover
119
+ * handlers - with Enter or Space to click and Escape to leave. A screen reader hears each one. { label: (hit) =>
120
+ * text } says what it hears (default: the tooltip's text, the data, or the name). Default false
121
+ */
122
+ keyboard?: boolean | KeyboardOptions;
123
+ /**
124
+ * what the view shows, for screen readers: the canvas's label. With keyboard
125
+ * on and no description, one is made from the scene (charts describe themselves)
126
+ */
127
+ description?: string | null;
104
128
  };
105
129
  export type ViewEvent = 'click' | 'hover';
106
130
  export type ViewHandler = (hit: Hit | null, event: PointerEvent | MouseEvent | null) => void;
@@ -163,6 +187,22 @@ export declare class View {
163
187
  get highlight(): Color | null;
164
188
  /** @param {ColorInput | null} v */
165
189
  set highlight(v: ColorInput | null);
190
+ /**
191
+ * Is motion cut short - glides, auto-rotation, chart transitions? Set true or false, or 'auto' (the
192
+ * default) to follow the system's setting. Read it for motion of your own, such as a timeline.
193
+ * @returns {boolean}
194
+ */
195
+ get reducedMotion(): boolean;
196
+ /** @param {'auto' | boolean} v */
197
+ set reducedMotion(v: 'auto' | boolean);
198
+ /**
199
+ * What the view shows, for screen readers - the canvas's label - or null. With keyboard on and no
200
+ * description, one is made from the scene.
201
+ * @returns {string | null}
202
+ */
203
+ get description(): string | null;
204
+ /** @param {string | null} v */
205
+ set description(v: string | null);
166
206
  /** Canvas width in CSS pixels. */
167
207
  get width(): number;
168
208
  /** Canvas height in CSS pixels. */
@@ -215,7 +255,8 @@ export declare class View {
215
255
  * @param {Node | Box3} [target] (default the scene)
216
256
  * @param {{ padding?: number, direction?: CameraPreset | Vec3Input, duration?: number }} [options] padding is
217
257
  * the margin around it, as a fraction of its size: 0 is a tight fit, 0.2 (the default) leaves a fifth.
218
- * duration is in seconds (default 0: straight there); a press or the wheel stops the glide
258
+ * duration is in seconds (default 0: straight there); a press or the wheel stops the glide, and with
259
+ * reducedMotion it goes straight there
219
260
  * @returns {this}
220
261
  */
221
262
  frame(target?: Node | Box3, { padding, direction: towards, duration }?: {
@@ -223,6 +264,28 @@ export declare class View {
223
264
  direction?: CameraPreset | Vec3Input;
224
265
  duration?: number;
225
266
  }): this;
267
+ /**
268
+ * Where frame() would put the camera, without moving it: its position, target and - for an
269
+ * orthographic camera - height, or null when there is nothing to frame. For a camera of your own
270
+ * that eases after something moving rather than jumping each frame:
271
+ *
272
+ * const aim = view.framing(debris)
273
+ * if (aim) {
274
+ * view.camera.position.lerp(aim.position, 0.1)
275
+ * view.camera.target.lerp(aim.target, 0.1)
276
+ * }
277
+ * @param {Node | Box3} [target] (default the scene)
278
+ * @param {{ padding?: number, direction?: CameraPreset | Vec3Input }} [options] as frame()
279
+ * @returns {{ position: Vec3, target: Vec3, height?: number } | null}
280
+ */
281
+ framing(target?: Node | Box3, { padding, direction }?: {
282
+ padding?: number;
283
+ direction?: CameraPreset | Vec3Input;
284
+ }): {
285
+ position: Vec3;
286
+ target: Vec3;
287
+ height?: number;
288
+ } | null;
226
289
  /**
227
290
  * The nearest hit under a canvas position - CSS pixels from the canvas's top left, or a pointer
228
291
  * event. Found on the GPU from the last frame drawn (one pass, however many instances), then made
@@ -45,6 +45,13 @@ export declare class Chart extends Group {
45
45
  filter(fn: ((row: any) => boolean) | null): this;
46
46
  /** One line about this chart, for view.explain(). */
47
47
  explain(): string;
48
+ /**
49
+ * One sentence about this chart for screen readers - the spec's description, or its title and what
50
+ * it shows: "Sales by month: bar chart of 12 rows by Month, Sales". A View with keyboard: true labels
51
+ * its canvas with this.
52
+ * @returns {string}
53
+ */
54
+ summary(): string;
48
55
  toJSON(): Record<string, unknown>;
49
56
  /** A new chart from the same spec and transform. @returns {any} */
50
57
  clone(): any;
@@ -36,6 +36,9 @@ export type ExplainInfo = {
36
36
  click: number;
37
37
  tooltip: boolean;
38
38
  highlight: boolean;
39
+ keyboard?: boolean;
40
+ reducedMotion?: boolean;
41
+ description?: string | null;
39
42
  };
40
43
  /**
41
44
  * lines from nodes that describe themselves, such as charts
@@ -146,6 +146,11 @@ export type FrameLabel = {
146
146
  * in front of the camera and inside the view
147
147
  */
148
148
  visible: boolean;
149
+ /**
150
+ * how far zoomed in at the point: half the view's height, in world units, is 1 / scale -
151
+ * the layer turns it into pixels to one world unit, for minScale
152
+ */
153
+ scale: number;
149
154
  };
150
155
  export type ShadowFrame = {
151
156
  light: FrameLight;
@@ -353,6 +358,8 @@ export type FrameDescription = {
353
358
  * @property {[number, number]} ndc [x, y] in -1..1
354
359
  * @property {number} depth
355
360
  * @property {boolean} visible in front of the camera and inside the view
361
+ * @property {number} scale how far zoomed in at the point: half the view's height, in world units, is 1 / scale -
362
+ * the layer turns it into pixels to one world unit, for minScale
356
363
  */
357
364
  /**
358
365
  * The shadow-casting directional light's view of the scene: what to draw into its depth map.
@@ -12,6 +12,11 @@ export type GeometryOptions = {
12
12
  * uv per vertex - glTF convention, (0, 0) is the image's top left
13
13
  */
14
14
  uvs?: ArrayLike<number>;
15
+ /**
16
+ * a second uv per vertex, for maps that need every surface on its own
17
+ * patch of texture - baked occlusion and light maps (a texture's uvSet: 1 reads it)
18
+ */
19
+ uvs2?: ArrayLike<number>;
15
20
  /**
16
21
  * rgb per vertex, sRGB 0-1 like every colour input
17
22
  */
@@ -31,6 +36,7 @@ export declare class Geometry {
31
36
  static OPTIONS: string[];
32
37
  /** @type {Float32Array} */ positions: Float32Array;
33
38
  /** @type {Float32Array | null} */ uvs: Float32Array | null;
39
+ /** A second UV set, for baked occlusion and light maps. @type {Float32Array | null} */ uvs2: Float32Array | null;
34
40
  /** @type {Float32Array | null} */ colors: Float32Array | null;
35
41
  /** @type {Uint16Array | Uint32Array | null} */ indices: Uint16Array | Uint32Array | null;
36
42
  /**
@@ -50,7 +56,9 @@ export declare class Geometry {
50
56
  constructor(options: GeometryOptions);
51
57
  /**
52
58
  * xyz per vertex. Computed (smooth) from the triangles on first read when not supplied, so
53
- * points and lines - whose geometry has no triangles - never pay for them.
59
+ * points and lines - whose geometry has no triangles - never pay for them - and computed again after
60
+ * needsUpdate(), so they follow positions edited in place. Normals that were supplied, assigned or
61
+ * made by calling computeNormals() are kept as they are.
54
62
  * @type {Float32Array}
55
63
  */
56
64
  get normals(): Float32Array;
@@ -71,7 +79,11 @@ export declare class Geometry {
71
79
  get drawnVertices(): number;
72
80
  /** Local space bounds, cached until needsUpdate(). @returns {Box3} */
73
81
  get bounds(): Box3;
74
- /** Call after editing the arrays in place. It is no longer what its generator made, so toJSON() saves the arrays. @returns {this} */
82
+ /**
83
+ * Call after editing the arrays in place. It is no longer what its generator made, so toJSON() saves
84
+ * the arrays; normals that were worked out on first read are worked out again on the next.
85
+ * @returns {this}
86
+ */
75
87
  needsUpdate(): this;
76
88
  /**
77
89
  * Compute vertex normals from the triangles. Smooth normals average the faces sharing each vertex;
@@ -0,0 +1,48 @@
1
+ import type { Hit } from './Raycaster.js';
2
+ import type { TooltipContent } from './tooltip.js';
3
+ import type { Node } from './scene/Node.js';
4
+ import type { View } from './View.js';
5
+ export type KeyboardOptions = {
6
+ /**
7
+ * what a screen reader says for each thing stepped to (default: the
8
+ * tooltip's text, then its data, then the node's name)
9
+ */
10
+ label?: (hit: Hit) => string;
11
+ };
12
+ export type KeyboardHooks = {
13
+ /**
14
+ * show this as hovered, or nothing
15
+ */
16
+ focus: (hit: Hit | null) => void;
17
+ /**
18
+ * click it
19
+ */
20
+ press: (hit: Hit) => void;
21
+ /**
22
+ * the tooltip's content for it, if there is a tooltip
23
+ */
24
+ tooltip: (hit: Hit) => TooltipContent;
25
+ /**
26
+ * does the View itself answer hovers or clicks (a tooltip, handlers)?
27
+ */
28
+ viewWide: () => boolean;
29
+ };
30
+ export type Item = {
31
+ node: Node;
32
+ index: number | null;
33
+ whole: Node | null;
34
+ };
35
+ export declare class Keyboard {
36
+ #private;
37
+ /** @param {View} view @param {KeyboardHooks} hooks @param {KeyboardOptions} options */
38
+ constructor(view: View, hooks: KeyboardHooks, options: KeyboardOptions);
39
+ /**
40
+ * The canvas's label for screen readers: the View's description, or - when it has none - one made
41
+ * from the scene: what its charts show, and how many things there are to step through.
42
+ * @param {string | null} text
43
+ */
44
+ setDescription(text: string | null): void;
45
+ /** Step off whatever was stepped to: the pointer has taken over, or focus has gone. */
46
+ clear(): void;
47
+ dispose(): void;
48
+ }
@@ -18,6 +18,10 @@ export type LabelStats = {
18
18
  * behind the camera or outside the view
19
19
  */
20
20
  offscreen: number;
21
+ /**
22
+ * hidden because the view isn't zoomed in to their minScale
23
+ */
24
+ zoomedOut: number;
21
25
  };
22
26
  export type Entry = {
23
27
  el: HTMLDivElement;
@@ -76,6 +76,20 @@ export type MaterialOptions = {
76
76
  * multiplies the emissive colour
77
77
  */
78
78
  emissiveMap?: MapInput | null;
79
+ /**
80
+ * light baked into a texture, added as light from all round - usually on
81
+ * the second UV set (uvSet: 1)
82
+ */
83
+ lightMap?: MapInput | null;
84
+ /**
85
+ * (default 1)
86
+ */
87
+ lightMapIntensity?: number;
88
+ /**
89
+ * this material's share of the environment's light and reflections:
90
+ * lower for a matte floor in a shiny showroom, higher to make one thing catch the light (default 1)
91
+ */
92
+ environmentIntensity?: number;
79
93
  /**
80
94
  * glow colour (default black)
81
95
  */
@@ -84,6 +98,74 @@ export type MaterialOptions = {
84
98
  * (default 1)
85
99
  */
86
100
  emissiveIntensity?: number;
101
+ /**
102
+ * 0-1: how much light passes through, as through glass (default 0). Unlike
103
+ * opacity, which fades the whole surface, glass keeps its reflections, and shows less of what is behind it
104
+ * towards its edges. Its colour shows in proportion to 1 - transmission
105
+ */
106
+ transmission?: number;
107
+ /**
108
+ * 0-1: a clear glossy layer over the surface - car paint, lacquer, varnish (default 0)
109
+ */
110
+ clearcoat?: number;
111
+ /**
112
+ * 0-1: how glossy the coat is, 0 a mirror (default 0)
113
+ */
114
+ clearcoatRoughness?: number;
115
+ /**
116
+ * 0-1: the soft bright rim of cloth at grazing angles - velvet, felt, upholstery (default 0)
117
+ */
118
+ sheen?: number;
119
+ /**
120
+ * the sheen's colour (default white)
121
+ */
122
+ sheenColor?: ColorInput;
123
+ /**
124
+ * 0-1: a thin bright rim at 0, a broad soft glow at 1 (default 0.5)
125
+ */
126
+ sheenRoughness?: number;
127
+ /**
128
+ * index of refraction, 1 or more: how strongly a non-metal reflects - water 1.33, glass and
129
+ * plastic 1.5 (the default), diamond 2.4
130
+ */
131
+ ior?: number;
132
+ /**
133
+ * 0-1: scales a non-metal's reflections, 0 for none - chalk, clay (default 1)
134
+ */
135
+ specularIntensity?: number;
136
+ /**
137
+ * tints a non-metal's reflections face on (default white)
138
+ */
139
+ specularColor?: ColorInput;
140
+ /**
141
+ * 0-1: brushed metal - highlights drawn out along the brushing, which runs along
142
+ * the UVs' u (around the mesh where it has no UVs) (default 0)
143
+ */
144
+ anisotropy?: number;
145
+ /**
146
+ * turns the brushing from the UVs' u, in radians (default 0)
147
+ */
148
+ anisotropyRotation?: number;
149
+ /**
150
+ * 0-1: light through thin surfaces, lighting them from behind - leaves, paper,
151
+ * lampshades, curtains (default 0)
152
+ */
153
+ translucency?: number;
154
+ /**
155
+ * tints the light that comes through (default white)
156
+ */
157
+ translucencyColor?: ColorInput;
158
+ /**
159
+ * a picture of a lit sphere that gives the whole look - clay, wax, chrome,
160
+ * a painted ball - picked by which way the surface faces the camera. Lights, shadows and the environment are
161
+ * ignored; the colour and colour map multiply it
162
+ */
163
+ matcap?: MapInput | null;
164
+ /**
165
+ * cartoon shading in this many flat tones (2 or more) with a hard-edged highlight;
166
+ * 0 (the default) is smooth
167
+ */
168
+ toon?: number;
87
169
  /**
88
170
  * flat colour that ignores lights (default false)
89
171
  */
@@ -144,7 +226,17 @@ export declare class Material {
144
226
  side: string;
145
227
  wireframe: string;
146
228
  shininess: string;
229
+ envMapIntensity: string;
230
+ reflectivityScale: string;
231
+ matcapMap: string;
232
+ gradientMap: string;
233
+ cel: string;
234
+ celShading: string;
147
235
  specular: string;
236
+ reflectivity: string;
237
+ anisotropyStrength: string;
238
+ diffuseTransmission: string;
239
+ subsurface: string;
148
240
  colour: string;
149
241
  emissiveColor: string;
150
242
  alpha: string;
@@ -159,6 +251,19 @@ export declare class Material {
159
251
  /** @type {number} */ roughness: number;
160
252
  /** @type {number} */ metalness: number;
161
253
  /** @type {number} */ emissiveIntensity: number;
254
+ /** How much light passes through, as through glass: 0-1. @type {number} */ transmission: number;
255
+ /** A clear glossy layer over the surface: 0-1. @type {number} */ clearcoat: number;
256
+ /** How glossy the coat is, 0 a mirror. @type {number} */ clearcoatRoughness: number;
257
+ /** The soft bright rim of cloth: 0-1. @type {number} */ sheen: number;
258
+ /** A thin bright rim at 0, a broad soft glow at 1. @type {number} */ sheenRoughness: number;
259
+ /** Index of refraction: how strongly a non-metal reflects (1.5). @type {number} */ ior: number;
260
+ /** Scales a non-metal's reflections, 0-1. @type {number} */ specularIntensity: number;
261
+ /** Brushed metal: 0-1. @type {number} */ anisotropy: number;
262
+ /** Turns the brushing from the UVs' u, in radians. @type {number} */ anisotropyRotation: number;
263
+ /** Light through thin surfaces: 0-1. @type {number} */ translucency: number;
264
+ /** Cartoon shading in this many flat tones; 0 is smooth. @type {number} */ toon: number;
265
+ /** @type {number} */ lightMapIntensity: number;
266
+ /** This material's share of the environment's light and reflections. @type {number} */ environmentIntensity: number;
162
267
  /** @type {boolean} */ unlit: boolean;
163
268
  /** @type {boolean} */ flatShading: boolean;
164
269
  /** @type {boolean} */ doubleSided: boolean;
@@ -180,6 +285,18 @@ export declare class Material {
180
285
  get emissive(): Color;
181
286
  /** @param {ColorInput} v */
182
287
  set emissive(v: ColorInput);
288
+ /** The sheen's colour; assign any colour input. @returns {Color} */
289
+ get sheenColor(): Color;
290
+ /** @param {ColorInput} v */
291
+ set sheenColor(v: ColorInput);
292
+ /** Tints a non-metal's reflections face on; assign any colour input. @returns {Color} */
293
+ get specularColor(): Color;
294
+ /** @param {ColorInput} v */
295
+ set specularColor(v: ColorInput);
296
+ /** Tints the light that comes through a translucent surface; assign any colour input. @returns {Color} */
297
+ get translucencyColor(): Color;
298
+ /** @param {ColorInput} v */
299
+ set translucencyColor(v: ColorInput);
183
300
  /** @returns {Texture | null} */
184
301
  get map(): Texture | null;
185
302
  /** @param {MapInput | null} v */
@@ -208,6 +325,14 @@ export declare class Material {
208
325
  get emissiveMap(): Texture | null;
209
326
  /** @param {MapInput | null} v */
210
327
  set emissiveMap(v: MapInput | null);
328
+ /** Light baked into a texture. @returns {Texture | null} */
329
+ get lightMap(): Texture | null;
330
+ /** @param {MapInput | null} v */
331
+ set lightMap(v: MapInput | null);
332
+ /** A picture of a lit sphere that gives the whole look. @returns {Texture | null} */
333
+ get matcap(): Texture | null;
334
+ /** @param {MapInput | null} v */
335
+ set matcap(v: MapInput | null);
211
336
  /** The maps that are set, by slot. @returns {[string, Texture][]} */
212
337
  get textures(): [string, Texture][];
213
338
  /** Rendered in the transparent pass: an opacity below 1, additive or multiply blending, or set for maps with soft alpha. @returns {boolean} */
@@ -11,7 +11,8 @@ export type TextureOptions = {
11
11
  image?: TextureImage;
12
12
  /**
13
13
  * image to load (starts loading immediately in a browser); a .hdr file loads as
14
- * linear HDR radiance, for scene.environment
14
+ * linear HDR radiance, for scene.environment; a video (.mp4, .webm, .ogv, .mov, .m4v) plays muted and on a
15
+ * loop, and texture.image is its <video> to pause, seek or unmute
15
16
  */
16
17
  url?: string;
17
18
  /**
@@ -31,12 +32,26 @@ export type TextureOptions = {
31
32
  * [u, v] (default [0, 0])
32
33
  */
33
34
  offset?: number[];
35
+ /**
36
+ * turns the image on the surface, in radians, about `center` (default 0)
37
+ */
38
+ rotation?: number;
39
+ /**
40
+ * [u, v] the point rotation turns about, in repeated UVs (default [0, 0], the
41
+ * corner, as glTF has it; [0.5, 0.5] for the middle of an unrepeated image)
42
+ */
43
+ center?: number[];
44
+ /**
45
+ * which UV set to read: 0 the first, 1 the second (Geometry uvs2) - baked occlusion
46
+ * and light maps usually come on the second (default 0)
47
+ */
48
+ uvSet?: 0 | 1;
34
49
  /**
35
50
  * (default 'linear')
36
51
  */
37
52
  filter?: 'linear' | 'nearest';
38
53
  /**
39
- * (default true)
54
+ * (default true; false for a video, which would make them every frame)
40
55
  */
41
56
  mipmaps?: boolean;
42
57
  /**
@@ -49,7 +64,10 @@ export type TextureOptions = {
49
64
  */
50
65
  flipY?: boolean;
51
66
  };
52
- /** An image for a material map. Canvas and video textures: set `needsUpdate()` after drawing. */
67
+ /**
68
+ * An image for a material map. A video's frames upload by themselves as it plays; after drawing on
69
+ * a canvas, call `needsUpdate()`.
70
+ */
53
71
  export declare class Texture {
54
72
  #private;
55
73
  /** The options it takes, and hints for names people reach for instead. */
@@ -59,15 +77,22 @@ export declare class Texture {
59
77
  encoding: string;
60
78
  wrapS: string;
61
79
  maxAnisotropy: string;
80
+ channel: string;
81
+ texCoord: string;
82
+ scale: string;
62
83
  };
63
- /** @type {TextureImage | null} null until loaded */
64
- image: TextureImage | null;
65
84
  /** @type {string | null} */
66
85
  url: string | null;
67
86
  /** @type {'repeat' | 'clamp' | 'mirror'} */
68
87
  wrap: 'repeat' | 'clamp' | 'mirror';
69
88
  repeat: number[];
70
89
  offset: number[];
90
+ /** Turns the image on the surface, in radians, about `center`. */
91
+ rotation: number;
92
+ /** [u, v] the point rotation turns about, in repeated UVs. */
93
+ center: number[];
94
+ /** Which UV set it reads: 0 the first, 1 the second (Geometry uvs2). @type {0 | 1} */
95
+ uvSet: 0 | 1;
71
96
  /** @type {'linear' | 'nearest'} */
72
97
  filter: 'linear' | 'nearest';
73
98
  mipmaps: boolean;
@@ -79,6 +104,13 @@ export declare class Texture {
79
104
  /** @param {TextureOptions | string} [options] options, or just a url */
80
105
  constructor(options?: TextureOptions | string);
81
106
  /** Call after redrawing a canvas or advancing a video. @returns {this} */
107
+ /**
108
+ * The pixels: null until loaded. A <video>'s frames upload by themselves while it plays.
109
+ * @returns {TextureImage | null}
110
+ */
111
+ get image(): TextureImage | null;
112
+ /** @param {TextureImage | null} v */
113
+ set image(v: TextureImage | null);
82
114
  /** 'srgb' for colour (decoded to linear by the GPU), 'linear' for data such as normals and roughness. Call needsUpdate() after changing it. @returns {'srgb' | 'linear'} */
83
115
  get colorSpace(): 'srgb' | 'linear';
84
116
  set colorSpace(v: 'srgb' | 'linear');
@@ -5,7 +5,7 @@ import { Mat4 } from '../value/Mat4.js';
5
5
  import { Quat } from '../value/Quat.js';
6
6
  import { Vec3 } from '../value/Vec3.js';
7
7
  import { Clip } from '../clip.js';
8
- import type { ColorInput, Vec3Input } from '../types.js';
8
+ import type { ColorInput, QuatInput, Vec3Input } from '../types.js';
9
9
  import type { Hit } from '../Raycaster.js';
10
10
  import type { Camera } from './cameras.js';
11
11
  import type { ClipOptions } from '../clip.js';
@@ -59,9 +59,9 @@ export type NodeOptions = {
59
59
  */
60
60
  rotation?: Vec3Input | Euler;
61
61
  /**
62
- * [x, y, z, w] - instead of rotation
62
+ * [x, y, z, w] or { x, y, z, w } - instead of rotation
63
63
  */
64
- quaternion?: ArrayLike<number>;
64
+ quaternion?: QuatInput;
65
65
  /**
66
66
  * a number scales uniformly
67
67
  */
@@ -87,9 +87,10 @@ export type NodeOptions = {
87
87
  */
88
88
  tooltip?: ((hit: Hit) => any) | null;
89
89
  /**
90
- * hover tint for this subtree, over the View's
90
+ * hover tint for this subtree, over the View's; false for none - a
91
+ * floor or wall left plain under a View that tints everything else (null: the View's)
91
92
  */
92
- highlight?: ColorInput | null;
93
+ highlight?: ColorInput | null | false;
93
94
  /**
94
95
  * hovering any part of this subtree tints all of it, as one thing - a
95
96
  * piece of furniture, a machine - rather than just the part under the pointer (default false)
@@ -127,7 +128,7 @@ export type NodeOptions = {
127
128
  */
128
129
  clip?: ClipOptions | Clip | null;
129
130
  };
130
- /** @import { ColorInput, Vec3Input } from '../types.js' */
131
+ /** @import { ColorInput, QuatInput, Vec3Input } from '../types.js' */
131
132
  /** @import { Hit } from '../Raycaster.js' */
132
133
  /** @import { Camera } from './cameras.js' */
133
134
  /** @import { ClipOptions } from '../clip.js' */
@@ -157,7 +158,7 @@ export type NodeOptions = {
157
158
  * @property {string} [name]
158
159
  * @property {Vec3Input} [position]
159
160
  * @property {Vec3Input | Euler} [rotation] Euler angles in radians, XYZ order
160
- * @property {ArrayLike<number>} [quaternion] [x, y, z, w] - instead of rotation
161
+ * @property {QuatInput} [quaternion] [x, y, z, w] or { x, y, z, w } - instead of rotation
161
162
  * @property {Vec3Input | number} [scale] a number scales uniformly
162
163
  * @property {boolean} [visible]
163
164
  * @property {boolean} [pickable] include in view.pick() (default true)
@@ -167,7 +168,8 @@ export type NodeOptions = {
167
168
  * @property {UpdateHandler | UpdateHandler[]} [onUpdate]
168
169
  * @property {((hit: Hit) => any) | null} [tooltip] tooltip for anything picked in this subtree; nearer nodes win, and
169
170
  * all win over the View's
170
- * @property {ColorInput | null} [highlight] hover tint for this subtree, over the View's
171
+ * @property {ColorInput | null | false} [highlight] hover tint for this subtree, over the View's; false for none - a
172
+ * floor or wall left plain under a View that tints everything else (null: the View's)
171
173
  * @property {boolean} [highlightWhole] hovering any part of this subtree tints all of it, as one thing - a
172
174
  * piece of furniture, a machine - rather than just the part under the pointer (default false)
173
175
  * @property {((hit: Hit | null) => void) | null} [onHover] called as the thing under the pointer in this subtree changes
@@ -244,14 +246,17 @@ export declare class Node {
244
246
  set rotation(v: Vec3Input);
245
247
  /** Kept in sync with rotation. Assigning copies, normalised. @returns {Quat} */
246
248
  get quaternion(): Quat;
247
- /** @param {ArrayLike<number>} v */
248
- set quaternion(v: ArrayLike<number>);
249
+ /** @param {QuatInput} v */
250
+ set quaternion(v: QuatInput);
249
251
  /** @param {NodeOptions} [options] */
250
252
  constructor(options?: NodeOptions);
251
- /** Hover tint for this subtree, over the View's; set any colour, or null. @returns {Color | null} */
252
- get highlight(): Color | null;
253
- /** @param {ColorInput | null} value */
254
- set highlight(value: ColorInput | null);
253
+ /**
254
+ * Hover tint for this subtree, over the View's: a colour, false for none, or null to use the View's.
255
+ * @returns {Color | null | false}
256
+ */
257
+ get highlight(): Color | null | false;
258
+ /** @param {ColorInput | null | false} value */
259
+ set highlight(value: ColorInput | null | false);
255
260
  /**
256
261
  * The section plane cutting this subtree, or null. Set { normal, offset, cap }, a Clip or null;
257
262
  * move the cut by changing its offset or normal in place.