@displayxr/inline3d 1.24.0 → 1.25.1
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 +128 -0
- package/README.md +15 -0
- package/index.d.ts +57 -0
- package/js/inline3d-player.js +2219 -0
- package/js/inline3d-splat-layer-rig.js +341 -125
- package/js/inline3d-splat-playcanvas.js +52 -18
- package/js/inline3d-splat.js +8 -1
- package/js/inline3d.js +208 -12
- package/package.json +7 -1
- package/player.d.ts +273 -0
- package/splat.d.ts +46 -7
package/player.d.ts
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
// Type definitions for @displayxr/inline3d/player.
|
|
2
|
+
// PREVIEW tier — not covered by the 1.x semver promise. See docs/sdk-stability.md.
|
|
3
|
+
//
|
|
4
|
+
// v1 slice of docs/rfcs/0001-media-player.md. Narrower than the RFC's full plan — no `'tb'`/
|
|
5
|
+
// `'auto'` format, no sidecar/filename format detection, no `opts.group` playback policy, no
|
|
6
|
+
// `opts.fit`/letterboxing — see the report that shipped this file for the reasoning. Widening
|
|
7
|
+
// any of those later is additive (new optional fields), so this stays forward-compatible.
|
|
8
|
+
|
|
9
|
+
/** `'sbs'` side-by-side, `'tb'` top/bottom (left eye on top) — ./splat setVideo's names — or `'mono'`. */
|
|
10
|
+
export type PlayerFormat = 'sbs' | 'tb' | 'mono';
|
|
11
|
+
|
|
12
|
+
/** A source: a URL or Blob, or candidates best-first for {@link pickSource}. */
|
|
13
|
+
export type PlayerSource = string | Blob | Array<string | Blob | { src: string | Blob; type?: string }>;
|
|
14
|
+
export type PlayerControls = 'sdk' | 'none';
|
|
15
|
+
|
|
16
|
+
export interface PlayerOptions {
|
|
17
|
+
/**
|
|
18
|
+
* `'sbs'` (default) is a real stereo pair, woven via `wall.addVideo()` — every fallback
|
|
19
|
+
* `addVideo` already has (including the browser-unsupported / off-screen-lazy one) applies for
|
|
20
|
+
* free. `'mono'` is genuinely flat content: painted full-frame, never split into eyes, on a
|
|
21
|
+
* small paint loop this module owns (NOT the same code path as an unsupported wall — see
|
|
22
|
+
* js/inline3d-player.js's module doc comment).
|
|
23
|
+
*/
|
|
24
|
+
format?: PlayerFormat;
|
|
25
|
+
/** Painted before the first frame, and again on the video's `error` event. */
|
|
26
|
+
poster?: string;
|
|
27
|
+
autoplay?: boolean;
|
|
28
|
+
/** Default true — required for autoplay in every browser that has one. */
|
|
29
|
+
muted?: boolean;
|
|
30
|
+
loop?: boolean;
|
|
31
|
+
/** Default `'sdk'`. `'none'` leaves chrome to the page (handle + events + its own overlays). */
|
|
32
|
+
controls?: PlayerControls;
|
|
33
|
+
/**
|
|
34
|
+
* Space/K play-pause, ←/→ seek ±5 s, J/L seek ±10 s, M mute. Bound to the canvas and its
|
|
35
|
+
* transport, never `document`, so a page with several players drives only the focused one.
|
|
36
|
+
* Default true.
|
|
37
|
+
*/
|
|
38
|
+
keyboard?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* What `setSource()` does by default — the `./splat` vocabulary, the part a video can mean.
|
|
41
|
+
* `'crossfade'` is opt-in HERE: it creates the mixer canvas that runs it (one extra full-frame
|
|
42
|
+
* draw per painted frame), so a player that never asks keeps the byte-identical
|
|
43
|
+
* `addVideo(canvas, video)` paint path and pays nothing. Default `'cut'`.
|
|
44
|
+
*
|
|
45
|
+
* The crossfade runs from the outgoing title's LAST FRAME to the incoming one (`./splat`'s
|
|
46
|
+
* `outgoing: 'frozen'`) — not a blend of two decoding streams. On an SBS video that is not
|
|
47
|
+
* the "tracking paused" look it is on a splat: the frame's disparity is baked in either way.
|
|
48
|
+
* `./splat`'s other transitions (`flip`, `wavefront`, particles, sequences) move a photo's
|
|
49
|
+
* gaussians and are refused by name.
|
|
50
|
+
*/
|
|
51
|
+
transition?: PlayerTransition;
|
|
52
|
+
/** The crossfade's length, ms. Default 600. */
|
|
53
|
+
durationMs?: number;
|
|
54
|
+
/** A `./splat` easing name, or `(x) => y` on [0, 1]. Default `'easeInOutSine'`. */
|
|
55
|
+
easing?: PlayerEasing;
|
|
56
|
+
/** LEGACY (the 1.10 spelling, kept as `./splat` keeps it): `> 0` = `transition: 'crossfade'` of this length. */
|
|
57
|
+
fadeMs?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Accent colour for the transport — a named preset (`'azure'` default, `'violet'`, `'magenta'`,
|
|
60
|
+
* `'sunset'`, `'amber'`, `'lime'`, `'mint'`, `'ice'`) or any CSS colour. Written to the
|
|
61
|
+
* `--dxr-accent` custom property on the host, so it re-skins the scrub fill, the knob, the play
|
|
62
|
+
* orb, the focus rings and the spinner in one value.
|
|
63
|
+
*/
|
|
64
|
+
accent?: PlayerAccent | (string & {});
|
|
65
|
+
/**
|
|
66
|
+
* Show a small pill in the control row (`true` → "3D", or your own short string). Opt-in and
|
|
67
|
+
* page-driven on purpose: the module will NOT infer it from `wall.supported`, because a
|
|
68
|
+
* supported wall whose tile is scrolled out of view — or whose panel is in a 2D mode — is not
|
|
69
|
+
* showing 3D at that moment, and a badge that says otherwise is worse than no badge.
|
|
70
|
+
*/
|
|
71
|
+
badge3d?: boolean | string;
|
|
72
|
+
/**
|
|
73
|
+
* The transport's look: `'classic'` (default) — a full-width bottom band; `'dock'` — a floating
|
|
74
|
+
* rounded dock with lit round buttons and an accent orb for play.
|
|
75
|
+
* `'bars'` — one row inside the bottom black bar: back / play / elapsed / scrub / remaining.
|
|
76
|
+
* `'call'` — the name and a timer bar on top, the controls at the bottom, and a 2.39:1 `band`
|
|
77
|
+
* by default. With a `band`, every skin puts its controls INSIDE the black bars when the bottom
|
|
78
|
+
* bar is tall enough, and nothing sits over the picture. Same controls, CSS only. Both
|
|
79
|
+
* keep every glow inside the overlay's own box (a shadow outside it would be woven).
|
|
80
|
+
*/
|
|
81
|
+
skin?: 'classic' | 'dock' | 'bars' | 'call';
|
|
82
|
+
/**
|
|
83
|
+
* How an eye image meets a tile of a different aspect — the same names and meaning as `./splat`
|
|
84
|
+
* `setVideo`'s `fit`. `'contain'`: the whole eye image, transparent bars where the aspects
|
|
85
|
+
* differ (the page shows through). `'cover'`: the tile is full and the overflow is cut. Unset:
|
|
86
|
+
* stretched to the tile (the 1.x behaviour). On the woven path it costs one extra draw per frame.
|
|
87
|
+
*/
|
|
88
|
+
fit?: 'contain' | 'cover';
|
|
89
|
+
/**
|
|
90
|
+
* A letterbox "band" slot: the picture is fitted into a centred band of this aspect inside the
|
|
91
|
+
* tile (e.g. `2.39` or `'2.39:1'` for a scope band in a 16:9 tile); the rest stays clear.
|
|
92
|
+
* Implies `fit: 'contain'` unless `fit` says otherwise.
|
|
93
|
+
*/
|
|
94
|
+
band?: number | string;
|
|
95
|
+
/**
|
|
96
|
+
* What the poster image is: `'mono'` (one image for both eyes, the default), or a stereo still
|
|
97
|
+
* laid out like the video (`'sbs'` / `'tb'`), painted eye by eye so it is 3D before the first frame.
|
|
98
|
+
*/
|
|
99
|
+
posterFormat?: 'mono' | 'sbs' | 'tb';
|
|
100
|
+
/**
|
|
101
|
+
* A playlist. With `titles` and no `src`, the first title loads. Entries may be bare sources.
|
|
102
|
+
* Drive it with `play(id)`, `next()`, `back()`; `'titlechange'` fires on each switch.
|
|
103
|
+
*/
|
|
104
|
+
titles?: ReadonlyArray<PlayerSource | { id?: string; src: PlayerSource; title?: string; poster?: string }>;
|
|
105
|
+
/** `next()` past the last title wraps to the first (and `back()` from the first to the last). Default false. */
|
|
106
|
+
loopList?: boolean;
|
|
107
|
+
/** A title that ends moves on to the next one and plays it. Default false. */
|
|
108
|
+
autoAdvance?: boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Players sharing a group decode one at a time: starting one pauses every other player in the
|
|
111
|
+
* group. For a shelf of previews that each play muted and looped. Any string; unset = no group.
|
|
112
|
+
*/
|
|
113
|
+
group?: string;
|
|
114
|
+
/** Transport scale — `'s'` (0.84×), `'m'` (default), `'l'` (1.28×). Icons, fonts and hit targets scale together. */
|
|
115
|
+
size?: 's' | 'm' | 'l';
|
|
116
|
+
/** A now-playing line over the top of the tile, fading with the transport. `setSource(src, { title })` changes it. */
|
|
117
|
+
title?: string;
|
|
118
|
+
/** −10 s / +10 s buttons beside play. Default true (hidden on tiles narrower than 420 px). J / L work either way. */
|
|
119
|
+
skipButtons?: boolean;
|
|
120
|
+
/**
|
|
121
|
+
* A fullscreen button (and the F key). The canvas's CONTAINER goes fullscreen, so the transport
|
|
122
|
+
* comes with it and the tile letterboxes on black. Default true; absent where the browser has no
|
|
123
|
+
* Fullscreen API.
|
|
124
|
+
*/
|
|
125
|
+
fullscreen?: boolean;
|
|
126
|
+
/** Default: `'anonymous'` iff `src` is a cross-origin URL; unset (browser default) otherwise. */
|
|
127
|
+
crossOrigin?: 'anonymous' | 'use-credentials';
|
|
128
|
+
/** Per-eye buffer resolution in px. `'sbs'` + supported wall only — see {@link TileOptions}. */
|
|
129
|
+
width?: number;
|
|
130
|
+
height?: number;
|
|
131
|
+
/** `'sbs'` + supported wall only. */
|
|
132
|
+
cornerRadius?: number;
|
|
133
|
+
feather?: number;
|
|
134
|
+
/** Element whose visibility gates the lazy create/close lifecycle (`'sbs'` path only). */
|
|
135
|
+
observe?: Element;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export type PlayerEvent = 'play' | 'pause' | 'ended' | 'timeupdate' | 'ready' | 'error' | 'titlechange';
|
|
139
|
+
|
|
140
|
+
/** One playlist entry (RFC 0001 Addendum A4). */
|
|
141
|
+
export interface PlayerTitle {
|
|
142
|
+
/** Stable id for `play(id)`; defaults to the entry's index as a string. */
|
|
143
|
+
readonly id: string;
|
|
144
|
+
readonly src: PlayerSource;
|
|
145
|
+
/** Shown in the title line while this title plays. */
|
|
146
|
+
readonly title?: string;
|
|
147
|
+
readonly poster?: string;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** What {@link addPlayer} returns. Deliberately the `<video>` element's own vocabulary. */
|
|
151
|
+
export interface PlayerHandle {
|
|
152
|
+
/** The hidden `<video>` this handle owns — escape hatch for anything not covered above. */
|
|
153
|
+
readonly video: HTMLVideoElement;
|
|
154
|
+
|
|
155
|
+
/** Resume; or, with an id (or an index into `titles`), switch to that title and play it. */
|
|
156
|
+
play(id?: string | number): Promise<void>;
|
|
157
|
+
pause(): void;
|
|
158
|
+
/** Play if paused or ended, else pause. */
|
|
159
|
+
toggle(): Promise<void>;
|
|
160
|
+
/** The playlist, read-only. */
|
|
161
|
+
readonly titles: ReadonlyArray<PlayerTitle>;
|
|
162
|
+
/** The title playing now, or null (no playlist, or a source that is not one of its titles). */
|
|
163
|
+
readonly current: PlayerTitle | null;
|
|
164
|
+
/** Replace the playlist; the current title stays current if the new list has its id. */
|
|
165
|
+
setTitles(list: PlayerOptions['titles']): void;
|
|
166
|
+
/** The next title, playing. At the end: nothing, unless `loopList`. */
|
|
167
|
+
next(): Promise<void>;
|
|
168
|
+
/** A remote's "previous": restart if more than 3 s in, else the previous title. */
|
|
169
|
+
back(): Promise<void>;
|
|
170
|
+
/** Clamped to `[0, duration]` (or `[0, t]` before `duration` is known). */
|
|
171
|
+
seek(t: number): void;
|
|
172
|
+
currentTime: number;
|
|
173
|
+
readonly duration: number;
|
|
174
|
+
readonly paused: boolean;
|
|
175
|
+
readonly ended: boolean;
|
|
176
|
+
volume: number;
|
|
177
|
+
muted: boolean;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Swap the source in place (and its poster, if given). Each field of `opts` overrides the
|
|
181
|
+
* player's own for this one swap — `{ durationMs: 1200 }` lengthens its crossfade,
|
|
182
|
+
* `{ transition: 'cut' }` skips it. A crossfade cannot be switched ON here for a player built
|
|
183
|
+
* with `transition: 'cut'`: the mixer would have to become the woven window's paint source
|
|
184
|
+
* mid-flight, which rebuilds the weave layer (the blink a crossfade removes). That swap is a
|
|
185
|
+
* cut, and a console warning says so once.
|
|
186
|
+
*
|
|
187
|
+
* With a cut the old frame holds until the new source reaches `readyState >= 2`. Throws, and
|
|
188
|
+
* changes nothing, on an unknown transition or easing.
|
|
189
|
+
*/
|
|
190
|
+
setSource(src: PlayerSource, opts?: PlayerSourceOptions): void;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Re-skin the SDK transport live — any of `accent` (a CSS colour; `''` = the default), `size`,
|
|
194
|
+
* `skin`. Invalid values warn and are ignored; a no-op with `controls: 'none'`.
|
|
195
|
+
*/
|
|
196
|
+
setAppearance(a: { accent?: PlayerAccent | (string & {}); size?: 's' | 'm' | 'l'; skin?: 'classic' | 'dock' | 'bars' | 'call' }): void;
|
|
197
|
+
|
|
198
|
+
/** Mark a 2D element painted over this window so the weave leaves it crisp — `'sbs'` + a
|
|
199
|
+
* supported wall only; a no-op everywhere else (there is no weave to protect it from). */
|
|
200
|
+
exclude(el: Element): void;
|
|
201
|
+
unexclude(el: Element): void;
|
|
202
|
+
|
|
203
|
+
/** Stop the paint loop / weave window, tear down the transport, release the `<video>`. */
|
|
204
|
+
remove(): void;
|
|
205
|
+
|
|
206
|
+
/** Returns an unsubscribe function, like {@link Inline3D.on}. */
|
|
207
|
+
on(event: PlayerEvent, fn: (payload?: unknown) => void): () => void;
|
|
208
|
+
off(event: PlayerEvent, fn: (payload?: unknown) => void): void;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Load a media title into an inline-3D window with real transport, in one call. Safe with a
|
|
213
|
+
* `null`/unsupported `wall` — it renders flat 2D instead, so pages need no branch.
|
|
214
|
+
* @param wall the manager from `createInline3D()`, or null/unsupported.
|
|
215
|
+
* @param canvas a 2D canvas ALREADY inside a container element — `controls:'sdk'` attaches the
|
|
216
|
+
* transport as a sibling of the canvas, inside `canvas.parentElement`.
|
|
217
|
+
* @param src the video URL, or a Blob/File (an object URL is created for you).
|
|
218
|
+
*/
|
|
219
|
+
export function addPlayer(
|
|
220
|
+
wall: object | null | undefined,
|
|
221
|
+
canvas: HTMLCanvasElement,
|
|
222
|
+
/** `null` with `opts.titles` loads the first title. */
|
|
223
|
+
src: PlayerSource | null,
|
|
224
|
+
opts?: PlayerOptions,
|
|
225
|
+
): PlayerHandle;
|
|
226
|
+
|
|
227
|
+
/** The `setSource()` transitions a video can mean. */
|
|
228
|
+
export type PlayerTransition = 'cut' | 'crossfade';
|
|
229
|
+
|
|
230
|
+
/** `./splat`'s easing names (the same curves), or a function on [0, 1]. */
|
|
231
|
+
export type PlayerEasing =
|
|
232
|
+
| 'linear'
|
|
233
|
+
| 'easeInQuad'
|
|
234
|
+
| 'easeOutQuad'
|
|
235
|
+
| 'easeInOutQuad'
|
|
236
|
+
| 'easeInCubic'
|
|
237
|
+
| 'easeOutCubic'
|
|
238
|
+
| 'easeInOutCubic'
|
|
239
|
+
| 'easeInOutSine'
|
|
240
|
+
| ((x: number) => number);
|
|
241
|
+
|
|
242
|
+
/** Per-call {@link PlayerHandle.setSource} options; each overrides the player's own. */
|
|
243
|
+
export interface PlayerSourceOptions {
|
|
244
|
+
poster?: string;
|
|
245
|
+
/** Replace the now-playing line ('' clears it). */
|
|
246
|
+
title?: string;
|
|
247
|
+
transition?: PlayerTransition;
|
|
248
|
+
durationMs?: number;
|
|
249
|
+
easing?: PlayerEasing;
|
|
250
|
+
/** Only `'frozen'` — the player dissolves from the outgoing title's last frame. */
|
|
251
|
+
outgoing?: 'frozen';
|
|
252
|
+
/** LEGACY: `> 0` = a crossfade of this length, `0` = a cut. `durationMs` wins when both are given. */
|
|
253
|
+
fadeMs?: number;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** The resolved form `resolveTransition()` returns. */
|
|
257
|
+
export interface ResolvedPlayerTransition {
|
|
258
|
+
type: PlayerTransition;
|
|
259
|
+
/** 0 for a cut. */
|
|
260
|
+
durationMs: number;
|
|
261
|
+
easing: PlayerEasing;
|
|
262
|
+
ease: (x: number) => number;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/** The named accent presets `accent` accepts (any CSS colour works too). */
|
|
266
|
+
export type PlayerAccent = 'azure' | 'violet' | 'magenta' | 'sunset' | 'amber' | 'lime' | 'mint' | 'ice';
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Pick the first source this browser can play from candidates listed best first; each is a URL, or
|
|
270
|
+
* `{ src, type }` with a FULL `canPlayType` string (`'video/webm; codecs="vp9, opus"'`). The
|
|
271
|
+
* DisplayXR Browser has no H.264/AAC, and a codec-less `'video/mp4'` still answers 'maybe'.
|
|
272
|
+
*/
|
|
273
|
+
export function pickSource(candidates: PlayerSource, canPlayType?: (type: string) => string): string | Blob | undefined;
|
package/splat.d.ts
CHANGED
|
@@ -179,15 +179,27 @@ export interface ResolvedRig {
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
/**
|
|
182
|
-
* `handle.setLayerRig` options —
|
|
183
|
-
*
|
|
184
|
-
*
|
|
182
|
+
* `handle.setLayerRig` / `handle.setLayerRigOptions` options — tile-wide; they MERGE across calls
|
|
183
|
+
* (a key given replaces, `null` clears it back to its default). The rounding gain is
|
|
184
|
+
* k = D / (metersToVirtual · viewerDistance): the photo rig's convergence distance over the
|
|
185
|
+
* viewer's. docs/proposals/layer-display-rig.md.
|
|
185
186
|
*/
|
|
186
187
|
export interface SplatLayerRigOptions {
|
|
187
188
|
/** Nominal viewer distance in metres (default 0.6, the browser's own nominal). */
|
|
188
|
-
viewerDistance?: number;
|
|
189
|
+
viewerDistance?: number | null;
|
|
189
190
|
/** An explicit gain k instead (1 = exactly the photo rig; larger = rounder). */
|
|
190
|
-
gain?: number;
|
|
191
|
+
gain?: number | null;
|
|
192
|
+
/**
|
|
193
|
+
* Metres ON THE PANEL (display space), + = toward the viewer: moves the display-rig stage
|
|
194
|
+
* forward by this much. The plane that lands on the glass moves back from the photo's
|
|
195
|
+
* convergence plane by planeOffset·D/viewerDistance (world units). Default 0.
|
|
196
|
+
*/
|
|
197
|
+
planeOffset?: number | null;
|
|
198
|
+
/**
|
|
199
|
+
* The plane that lands on the glass, as a distance from the photo's camera in world units
|
|
200
|
+
* (wins over planeOffset). Default: the photo's convergence distance D.
|
|
201
|
+
*/
|
|
202
|
+
planeDistance?: number | null;
|
|
191
203
|
}
|
|
192
204
|
|
|
193
205
|
/** `handle.layerRigState()`. */
|
|
@@ -196,10 +208,24 @@ export interface SplatLayerRigState {
|
|
|
196
208
|
display: Array<string | number>;
|
|
197
209
|
/** The `nolayerrig` kill switch is on (requests recorded, never applied). */
|
|
198
210
|
disabled: boolean;
|
|
199
|
-
/** The last drawn frame
|
|
211
|
+
/** The view path of the last drawn frame: RenderViews, the N-camera fallback, or one view. */
|
|
212
|
+
path: 'renderviews' | 'ncamera' | 'mono' | null;
|
|
213
|
+
/** The display-rig views were actually applied on the last drawn frame. */
|
|
214
|
+
engaged: boolean;
|
|
215
|
+
/** Same as `engaged` (the 1.23 name). */
|
|
200
216
|
rounded: boolean;
|
|
217
|
+
/** Why not engaged (or what is wrong with some layers while engaged); null when all is well. */
|
|
218
|
+
reason: string | null;
|
|
219
|
+
viewerDistance: number;
|
|
201
220
|
/** The gain the last frame used (null off a camera rig). */
|
|
202
221
|
gain: number | null;
|
|
222
|
+
/** The plane that lands on the glass, as a distance from the photo's camera (world units). */
|
|
223
|
+
planeM: number | null;
|
|
224
|
+
/** The photo rig's convergence distance D (world units). */
|
|
225
|
+
photoConvergenceM: number | null;
|
|
226
|
+
planeOffset: number;
|
|
227
|
+
/** The views were verified (read off the views) as located for the rig used; null if unknown. */
|
|
228
|
+
located: boolean | null;
|
|
203
229
|
}
|
|
204
230
|
|
|
205
231
|
/** `handle.makeSbsMaterial` options. */
|
|
@@ -968,7 +994,20 @@ export interface SplatHandle {
|
|
|
968
994
|
* `?dxrdiag=nolayerrig`. Callable before `ready`. docs/proposals/layer-display-rig.md.
|
|
969
995
|
*/
|
|
970
996
|
setLayerRig(layer: string | number | { id: number }, rig: 'display' | 'camera', opts?: SplatLayerRigOptions): SplatHandle;
|
|
971
|
-
/**
|
|
997
|
+
/**
|
|
998
|
+
* `engine: 'playcanvas'` only. Change the per-eye buffer scale live (the `renderScale` option),
|
|
999
|
+
* in (0, 4]; the backing store is resized on the next animation frame. Throws a RangeError
|
|
1000
|
+
* otherwise.
|
|
1001
|
+
*/
|
|
1002
|
+
setRenderScale(scale: number): SplatHandle;
|
|
1003
|
+
/** `engine: 'playcanvas'` only. The current per-eye buffer scale. */
|
|
1004
|
+
readonly renderScale: number;
|
|
1005
|
+
/** `engine: 'playcanvas'` only. Change the layer rig's tile-wide options live (merge; `null` clears). */
|
|
1006
|
+
setLayerRigOptions(opts: SplatLayerRigOptions): SplatHandle;
|
|
1007
|
+
/**
|
|
1008
|
+
* `engine: 'playcanvas'` only. What `setLayerRig` is doing — engaged or not, on which view path,
|
|
1009
|
+
* and why not. The same line is WARNed on the first 3D frame and on every change.
|
|
1010
|
+
*/
|
|
972
1011
|
layerRigState(): SplatLayerRigState;
|
|
973
1012
|
/**
|
|
974
1013
|
* `engine: 'playcanvas'` only, after `ready`. An unlit `pc.ShaderMaterial` that shows the left
|