@snaptrude/plugin-core 0.9.15 → 0.9.16
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 +6 -0
- package/api-manifest.json +300 -0
- package/dist/api/core/camera/index.d.ts +418 -0
- package/dist/api/core/camera/index.d.ts.map +1 -1
- package/dist/api/presentation/index.d.ts +9 -0
- package/dist/api/presentation/index.d.ts.map +1 -1
- package/dist/api/presentation/walkthroughs.d.ts +1350 -0
- package/dist/api/presentation/walkthroughs.d.ts.map +1 -0
- package/dist/index.cjs +662 -262
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +610 -262
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/api/core/camera/index.ts +400 -1
- package/src/api/presentation/index.ts +9 -0
- package/src/api/presentation/walkthroughs.ts +1201 -0
- package/api-manifest.full.json +0 -8930
|
@@ -0,0 +1,1201 @@
|
|
|
1
|
+
import * as z from "zod"
|
|
2
|
+
import { PluginApiReturn } from "../../types"
|
|
3
|
+
import { ComponentHandle, Vec3Components } from "../../handles"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Walkthroughs: camera paths through the model, played in the viewport and
|
|
7
|
+
* exported as videos.
|
|
8
|
+
*
|
|
9
|
+
* A walkthrough is a list of keyframes (camera positions and where each looks)
|
|
10
|
+
* joined by a smooth path that the camera travels at a steady speed. Make one
|
|
11
|
+
* from full keyframes (`create`), from points on the floor (`createFromPoints`)
|
|
12
|
+
* or from a camera move around what is selected (`createFromPreset`); inspect
|
|
13
|
+
* it (`sample`, `listIssues`, `capture`); play it (`start`/`stop`/`getState`);
|
|
14
|
+
* and export it as a video onto the Present canvas (`export` plus the job
|
|
15
|
+
* methods). Edits are write-gated and each is one step of the walkthrough undo
|
|
16
|
+
* history, which is separate from the model's. Walkthroughs are not saved with
|
|
17
|
+
* the project yet: they last until the project is closed or reloaded, while an
|
|
18
|
+
* exported video stays on the Present canvas.
|
|
19
|
+
*
|
|
20
|
+
* Positions are world coordinates in internal `babylon` units (1 unit =
|
|
21
|
+
* 0.254 m, Y up); yaw is degrees clockwise from +z seen from above, pitch is
|
|
22
|
+
* degrees above level. Accessed via `snaptrude.presentation.walkthroughs`.
|
|
23
|
+
*/
|
|
24
|
+
export abstract class PluginPresentationWalkthroughsApi {
|
|
25
|
+
constructor() {}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* List the open project's walkthroughs, oldest first.
|
|
29
|
+
*
|
|
30
|
+
* @returns `{ walkthroughs }` — every {@linkcode PluginWalkthrough} (`[]` when there are none).
|
|
31
|
+
*
|
|
32
|
+
* @examplePrompt Which walkthroughs are there?
|
|
33
|
+
* @examplePrompt List the camera paths in this project
|
|
34
|
+
*
|
|
35
|
+
* # Example
|
|
36
|
+
* ```ts
|
|
37
|
+
* const { walkthroughs } = await snaptrude.presentation.walkthroughs.list()
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
public abstract list(): PluginApiReturn<PluginWalkthroughsListResult>
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get one walkthrough by id.
|
|
44
|
+
*
|
|
45
|
+
* @param walkthroughId - The walkthrough's id
|
|
46
|
+
* @returns The {@linkcode PluginWalkthrough}, or `null` when there is none with that id.
|
|
47
|
+
*
|
|
48
|
+
* @examplePrompt Show me the keyframes of the orbit walkthrough
|
|
49
|
+
* @examplePrompt How long does this walkthrough take?
|
|
50
|
+
*
|
|
51
|
+
* # Example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const walkthrough = await snaptrude.presentation.walkthroughs.get(walkthroughId)
|
|
54
|
+
* console.log(walkthrough?.durationInSeconds)
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
public abstract get(
|
|
58
|
+
walkthroughId: string,
|
|
59
|
+
): PluginApiReturn<PluginWalkthrough | null>
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Create a walkthrough from full keyframes: where the camera stands at each
|
|
63
|
+
* and how it looks there (ahead along the path, at a target, or in a fixed
|
|
64
|
+
* direction). A keyframe that follows the floor stands at the walkthrough's
|
|
65
|
+
* eye height above the floor, stair, terrain or ground at or below its `eye`,
|
|
66
|
+
* and the path between two such keyframes climbs stairs and ramps. The new walkthrough opens in the
|
|
67
|
+
* walkthrough dock. Write-gated; one undo step.
|
|
68
|
+
*
|
|
69
|
+
* @param keyframes - At least one {@linkcode PluginWalkthroughKeyframeInput}, in order
|
|
70
|
+
* @param options - Name, loop, repeat, and speed or duration ({@linkcode PluginWalkthroughCreateOptions})
|
|
71
|
+
* @returns The new {@linkcode PluginWalkthrough}.
|
|
72
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. VALIDATION when
|
|
73
|
+
* `isLoop` is set with fewer than three keyframes. PRECONDITION_FAILED when a
|
|
74
|
+
* floor-following keyframe lies below the ground with nothing under it.
|
|
75
|
+
*
|
|
76
|
+
* @examplePrompt Make a walkthrough through these three viewpoints
|
|
77
|
+
* @examplePrompt Create a camera path that looks at the atrium the whole way
|
|
78
|
+
*
|
|
79
|
+
* # Example
|
|
80
|
+
* ```ts
|
|
81
|
+
* const walkthrough = await snaptrude.presentation.walkthroughs.create(
|
|
82
|
+
* [
|
|
83
|
+
* { eye: { x: 0, y: 30, z: 80 }, look: { mode: "target", target: { x: 0, y: 10, z: 0 } } },
|
|
84
|
+
* { eye: { x: 60, y: 30, z: 0 }, look: { mode: "target", target: { x: 0, y: 10, z: 0 } } },
|
|
85
|
+
* ],
|
|
86
|
+
* { name: "Approach", durationInSeconds: 10 },
|
|
87
|
+
* )
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
public abstract create(
|
|
91
|
+
keyframes: PluginWalkthroughKeyframeInput[],
|
|
92
|
+
options?: PluginWalkthroughCreateOptions,
|
|
93
|
+
): PluginApiReturn<PluginWalkthrough>
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Create a walkthrough that walks through points on the floor, the way the
|
|
97
|
+
* Walkthrough tool draws a route: the camera stands at eye height above the
|
|
98
|
+
* floor, stair, terrain or ground at each point, climbs stairs and ramps between them, and looks ahead
|
|
99
|
+
* along the path, or at `options.lookAt` the whole way. Write-gated; one undo
|
|
100
|
+
* step.
|
|
101
|
+
*
|
|
102
|
+
* @param points - 2 to 200 points on or above the floor, in order
|
|
103
|
+
* @param options - Name, loop, repeat, speed or duration, and `lookAt` ({@linkcode PluginWalkthroughCreateFromPointsOptions})
|
|
104
|
+
* @returns The new {@linkcode PluginWalkthrough}.
|
|
105
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. VALIDATION when
|
|
106
|
+
* `isLoop` is set with fewer than three points. PRECONDITION_FAILED when a point
|
|
107
|
+
* lies below the ground with nothing under it.
|
|
108
|
+
*
|
|
109
|
+
* @examplePrompt Walk from the entrance through the lobby to the stairs
|
|
110
|
+
* @examplePrompt Make a walkthrough that visits every room on this floor
|
|
111
|
+
* @examplePrompt Create a loop around the courtyard
|
|
112
|
+
*
|
|
113
|
+
* # Example
|
|
114
|
+
* ```ts
|
|
115
|
+
* await snaptrude.presentation.walkthroughs.createFromPoints(
|
|
116
|
+
* [{ x: 0, y: 0, z: 0 }, { x: 40, y: 0, z: 0 }, { x: 40, y: 0, z: 30 }],
|
|
117
|
+
* { name: "Ground floor tour" },
|
|
118
|
+
* )
|
|
119
|
+
* ```
|
|
120
|
+
*/
|
|
121
|
+
public abstract createFromPoints(
|
|
122
|
+
points: Vec3Components[],
|
|
123
|
+
options?: PluginWalkthroughCreateFromPointsOptions,
|
|
124
|
+
): PluginApiReturn<PluginWalkthrough>
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Create a walkthrough from a camera move around a subject, as the
|
|
128
|
+
* Walkthrough button's menu does: `orbit` circles it facing its middle,
|
|
129
|
+
* `flyOver` passes above it looking ahead and down, `pushIn` and `pullBack`
|
|
130
|
+
* move toward and away from it, and `rise` cranes up from eye level. The
|
|
131
|
+
* subject is `options.subject`, else the selection, else the visible model
|
|
132
|
+
* without its terrain; the move is sized to fit it in view and starts on the
|
|
133
|
+
* side the camera is on. While the walkthrough is still a preset,
|
|
134
|
+
* {@linkcode PluginPresentationWalkthroughsApi.update} can change its
|
|
135
|
+
* distance, height and direction; editing a keyframe makes it ordinary.
|
|
136
|
+
* Write-gated; one undo step.
|
|
137
|
+
*
|
|
138
|
+
* @param kind - The camera move ({@linkcode PluginWalkthroughPresetKind})
|
|
139
|
+
* @param options - Subject, distance, height, direction, duration, name, repeat ({@linkcode PluginWalkthroughCreateFromPresetOptions})
|
|
140
|
+
* @returns The new {@linkcode PluginWalkthrough}.
|
|
141
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. HANDLE_INVALID when a
|
|
142
|
+
* subject handle does not resolve. PRECONDITION_FAILED when there is nothing to frame.
|
|
143
|
+
*
|
|
144
|
+
* @examplePrompt Orbit around the selected building
|
|
145
|
+
* @examplePrompt Make a drone fly-over of the site
|
|
146
|
+
* @examplePrompt Push in slowly toward the entrance
|
|
147
|
+
* @examplePrompt Crane up to reveal the whole campus
|
|
148
|
+
*
|
|
149
|
+
* # Example
|
|
150
|
+
* ```ts
|
|
151
|
+
* await snaptrude.presentation.walkthroughs.createFromPreset("orbit", {
|
|
152
|
+
* subject: [towerId],
|
|
153
|
+
* heightInDegrees: 35,
|
|
154
|
+
* durationInSeconds: 20,
|
|
155
|
+
* })
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
public abstract createFromPreset(
|
|
159
|
+
kind: PluginWalkthroughPresetKind,
|
|
160
|
+
options?: PluginWalkthroughCreateFromPresetOptions,
|
|
161
|
+
): PluginApiReturn<PluginWalkthrough>
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Change a walkthrough: only the fields given change. Speed and duration are
|
|
165
|
+
* two ways to set one thing, so give at most one of them. `preset` changes a
|
|
166
|
+
* preset walkthrough's camera move and makes its keyframes again, keeping its
|
|
167
|
+
* duration; changing `isLoop` of a preset walkthrough makes it ordinary.
|
|
168
|
+
* Write-gated; one undo step.
|
|
169
|
+
*
|
|
170
|
+
* @param walkthroughId - The walkthrough's id
|
|
171
|
+
* @param patch - The fields to change ({@linkcode PluginWalkthroughPatch})
|
|
172
|
+
* @returns The updated {@linkcode PluginWalkthrough}.
|
|
173
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. HANDLE_INVALID when
|
|
174
|
+
* there is no walkthrough with that id. VALIDATION when `isLoop` is set on a
|
|
175
|
+
* walkthrough of fewer than three keyframes. PRECONDITION_FAILED when `preset`
|
|
176
|
+
* is given for a walkthrough that is not a preset.
|
|
177
|
+
*
|
|
178
|
+
* @examplePrompt Slow the walkthrough down to 30 seconds
|
|
179
|
+
* @examplePrompt Rename it to "Evening approach"
|
|
180
|
+
* @examplePrompt Make the orbit go the other way round and higher up
|
|
181
|
+
*
|
|
182
|
+
* # Example
|
|
183
|
+
* ```ts
|
|
184
|
+
* await snaptrude.presentation.walkthroughs.update(walkthroughId, {
|
|
185
|
+
* durationInSeconds: 30,
|
|
186
|
+
* isRepeating: true,
|
|
187
|
+
* })
|
|
188
|
+
* ```
|
|
189
|
+
*/
|
|
190
|
+
public abstract update(
|
|
191
|
+
walkthroughId: string,
|
|
192
|
+
patch: PluginWalkthroughPatch,
|
|
193
|
+
): PluginApiReturn<PluginWalkthrough>
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Delete a walkthrough. Write-gated; one undo step.
|
|
197
|
+
*
|
|
198
|
+
* @param walkthroughId - The walkthrough's id
|
|
199
|
+
* @returns `true` once it has been deleted.
|
|
200
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. HANDLE_INVALID when
|
|
201
|
+
* there is no walkthrough with that id.
|
|
202
|
+
*
|
|
203
|
+
* @examplePrompt Delete the old walkthrough
|
|
204
|
+
*
|
|
205
|
+
* # Example
|
|
206
|
+
* ```ts
|
|
207
|
+
* await snaptrude.presentation.walkthroughs.delete(walkthroughId)
|
|
208
|
+
* ```
|
|
209
|
+
*/
|
|
210
|
+
public abstract delete(walkthroughId: string): PluginApiReturn<boolean>
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Add a keyframe to a walkthrough at `index` (0 to the keyframe count;
|
|
214
|
+
* default: the end). A preset walkthrough becomes ordinary. Write-gated; one
|
|
215
|
+
* undo step.
|
|
216
|
+
*
|
|
217
|
+
* @param walkthroughId - The walkthrough's id
|
|
218
|
+
* @param keyframe - The {@linkcode PluginWalkthroughKeyframeInput} to add
|
|
219
|
+
* @param index - Where to insert it (default: after the last keyframe)
|
|
220
|
+
* @returns The updated {@linkcode PluginWalkthrough}; the new keyframe is at `index`.
|
|
221
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. HANDLE_INVALID when
|
|
222
|
+
* there is no walkthrough with that id. VALIDATION when `index` is out of range.
|
|
223
|
+
*
|
|
224
|
+
* @examplePrompt Add a stop in the kitchen after the second point
|
|
225
|
+
*
|
|
226
|
+
* # Example
|
|
227
|
+
* ```ts
|
|
228
|
+
* await snaptrude.presentation.walkthroughs.createKeyframe(
|
|
229
|
+
* walkthroughId,
|
|
230
|
+
* { eye: { x: 12, y: 0, z: 30 }, followsFloor: true, holdInSeconds: 2 },
|
|
231
|
+
* 2,
|
|
232
|
+
* )
|
|
233
|
+
* ```
|
|
234
|
+
*/
|
|
235
|
+
public abstract createKeyframe(
|
|
236
|
+
walkthroughId: string,
|
|
237
|
+
keyframe: PluginWalkthroughKeyframeInput,
|
|
238
|
+
index?: number,
|
|
239
|
+
): PluginApiReturn<PluginWalkthrough>
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Change a keyframe: only the fields given change. A preset walkthrough
|
|
243
|
+
* becomes ordinary. Write-gated; one undo step.
|
|
244
|
+
*
|
|
245
|
+
* @param walkthroughId - The walkthrough's id
|
|
246
|
+
* @param keyframeId - The keyframe's id
|
|
247
|
+
* @param patch - The fields to change ({@linkcode PluginWalkthroughKeyframePatch})
|
|
248
|
+
* @returns The updated {@linkcode PluginWalkthrough}.
|
|
249
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. HANDLE_INVALID when
|
|
250
|
+
* the walkthrough or keyframe does not exist.
|
|
251
|
+
*
|
|
252
|
+
* @examplePrompt Pause for three seconds at the second point
|
|
253
|
+
* @examplePrompt Make the last point look at the fireplace
|
|
254
|
+
*
|
|
255
|
+
* # Example
|
|
256
|
+
* ```ts
|
|
257
|
+
* await snaptrude.presentation.walkthroughs.updateKeyframe(walkthroughId, keyframeId, {
|
|
258
|
+
* look: { mode: "target", target: { x: 5, y: 4, z: 10 } },
|
|
259
|
+
* })
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
public abstract updateKeyframe(
|
|
263
|
+
walkthroughId: string,
|
|
264
|
+
keyframeId: string,
|
|
265
|
+
patch: PluginWalkthroughKeyframePatch,
|
|
266
|
+
): PluginApiReturn<PluginWalkthrough>
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Remove a keyframe; the path then runs straight from the keyframe before it
|
|
270
|
+
* to the one after. Removing the last keyframe deletes the walkthrough. A
|
|
271
|
+
* preset walkthrough becomes ordinary. Write-gated; one undo step.
|
|
272
|
+
*
|
|
273
|
+
* @param walkthroughId - The walkthrough's id
|
|
274
|
+
* @param keyframeId - The keyframe's id
|
|
275
|
+
* @returns The updated {@linkcode PluginWalkthrough}, or `null` when removing the last keyframe deleted it.
|
|
276
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. HANDLE_INVALID when
|
|
277
|
+
* the walkthrough or keyframe does not exist.
|
|
278
|
+
*
|
|
279
|
+
* @examplePrompt Remove the third stop from the walkthrough
|
|
280
|
+
*
|
|
281
|
+
* # Example
|
|
282
|
+
* ```ts
|
|
283
|
+
* await snaptrude.presentation.walkthroughs.deleteKeyframe(walkthroughId, keyframeId)
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
public abstract deleteKeyframe(
|
|
287
|
+
walkthroughId: string,
|
|
288
|
+
keyframeId: string,
|
|
289
|
+
): PluginApiReturn<PluginWalkthrough | null>
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Move a keyframe to position `index` in the walkthrough's order (the
|
|
293
|
+
* `presentation.sheets.reorder` convention). A preset walkthrough becomes
|
|
294
|
+
* ordinary. Write-gated; one undo step.
|
|
295
|
+
*
|
|
296
|
+
* @param walkthroughId - The walkthrough's id
|
|
297
|
+
* @param keyframeId - The keyframe's id
|
|
298
|
+
* @param index - Its new 0-based position (0 to the keyframe count - 1)
|
|
299
|
+
* @returns The updated {@linkcode PluginWalkthrough}.
|
|
300
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. HANDLE_INVALID when
|
|
301
|
+
* the walkthrough or keyframe does not exist. VALIDATION when `index` is out of range.
|
|
302
|
+
*
|
|
303
|
+
* @examplePrompt Visit the terrace before the living room
|
|
304
|
+
*
|
|
305
|
+
* # Example
|
|
306
|
+
* ```ts
|
|
307
|
+
* await snaptrude.presentation.walkthroughs.reorderKeyframe(walkthroughId, keyframeId, 0)
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
public abstract reorderKeyframe(
|
|
311
|
+
walkthroughId: string,
|
|
312
|
+
keyframeId: string,
|
|
313
|
+
index: number,
|
|
314
|
+
): PluginApiReturn<PluginWalkthrough>
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Sample where the camera is and which way it looks at given moments of a
|
|
318
|
+
* walkthrough's playback, without moving the camera.
|
|
319
|
+
*
|
|
320
|
+
* @param walkthroughId - The walkthrough's id
|
|
321
|
+
* @param timesInSeconds - 1 to 500 moments, each clamped to the walkthrough's duration
|
|
322
|
+
* @returns `{ samples }` — one {@linkcode PluginWalkthroughSample} per time, in order.
|
|
323
|
+
* @throws HANDLE_INVALID when there is no walkthrough with that id.
|
|
324
|
+
*
|
|
325
|
+
* @examplePrompt Where is the camera halfway through the walkthrough?
|
|
326
|
+
* @examplePrompt Check how high the camera flies over the roof
|
|
327
|
+
*
|
|
328
|
+
* # Example
|
|
329
|
+
* ```ts
|
|
330
|
+
* const walkthrough = await snaptrude.presentation.walkthroughs.get(walkthroughId)
|
|
331
|
+
* const { samples } = await snaptrude.presentation.walkthroughs.sample(walkthroughId, [
|
|
332
|
+
* 0,
|
|
333
|
+
* walkthrough!.durationInSeconds / 2,
|
|
334
|
+
* ])
|
|
335
|
+
* ```
|
|
336
|
+
*/
|
|
337
|
+
public abstract sample(
|
|
338
|
+
walkthroughId: string,
|
|
339
|
+
timesInSeconds: number[],
|
|
340
|
+
): PluginApiReturn<PluginWalkthroughSampleResult>
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Find places where a walkthrough's camera passes through the model: through
|
|
344
|
+
* anything walking would stop at, such as a wall, glazing, a column, a slab or
|
|
345
|
+
* a roof, which would show the inside of the geometry on screen. Doors,
|
|
346
|
+
* furniture and room masses don't count, as walking passes through them. Each
|
|
347
|
+
* issue gives the first moment and point of one pass. The camera itself does
|
|
348
|
+
* not move.
|
|
349
|
+
*
|
|
350
|
+
* @param walkthroughId - The walkthrough's id
|
|
351
|
+
* @returns `{ issues }` — every {@linkcode PluginWalkthroughIssue} in playback order (`[]` when the path is clear).
|
|
352
|
+
* @throws HANDLE_INVALID when there is no walkthrough with that id.
|
|
353
|
+
*
|
|
354
|
+
* @examplePrompt Does the walkthrough go through any walls?
|
|
355
|
+
* @examplePrompt Check the camera path for clashes and fix them
|
|
356
|
+
*
|
|
357
|
+
* # Example
|
|
358
|
+
* ```ts
|
|
359
|
+
* const { issues } = await snaptrude.presentation.walkthroughs.listIssues(walkthroughId)
|
|
360
|
+
* for (const issue of issues) console.log(issue.timeInSeconds, issue.componentId)
|
|
361
|
+
* ```
|
|
362
|
+
*/
|
|
363
|
+
public abstract listIssues(
|
|
364
|
+
walkthroughId: string,
|
|
365
|
+
): PluginApiReturn<PluginWalkthroughListIssuesResult>
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Capture frames of a walkthrough as one contact-sheet image: a grid of
|
|
369
|
+
* views at evenly spaced moments (or at `options.timesInSeconds`), read left
|
|
370
|
+
* to right and top to bottom. The camera goes back to where it was
|
|
371
|
+
* afterwards. Switches from 2D plan view to 3D first.
|
|
372
|
+
*
|
|
373
|
+
* @param walkthroughId - The walkthrough's id
|
|
374
|
+
* @param options - How many frames or which moments, image width and format ({@linkcode PluginWalkthroughCaptureOptions})
|
|
375
|
+
* @returns `{ image, frames }` — the contact sheet as a base64 data URL and the moment of each frame.
|
|
376
|
+
* @throws HANDLE_INVALID when there is no walkthrough with that id. PRECONDITION_FAILED
|
|
377
|
+
* when a walkthrough is playing or being exported.
|
|
378
|
+
*
|
|
379
|
+
* @examplePrompt Show me what the walkthrough looks like
|
|
380
|
+
* @examplePrompt Capture six frames of the fly-over
|
|
381
|
+
*
|
|
382
|
+
* # Example
|
|
383
|
+
* ```ts
|
|
384
|
+
* const { image } = await snaptrude.presentation.walkthroughs.capture(walkthroughId, {
|
|
385
|
+
* count: 6,
|
|
386
|
+
* })
|
|
387
|
+
* ```
|
|
388
|
+
*/
|
|
389
|
+
public abstract capture(
|
|
390
|
+
walkthroughId: string,
|
|
391
|
+
options?: PluginWalkthroughCaptureOptions,
|
|
392
|
+
): PluginApiReturn<PluginWalkthroughCaptureResult>
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Play a walkthrough in the viewport, from the start or `options.fromTimeInSeconds`.
|
|
396
|
+
* Arrow-key navigation pauses while it plays; {@linkcode PluginPresentationWalkthroughsApi.stop}
|
|
397
|
+
* puts the camera back where it was. Switches from 2D plan view to 3D first.
|
|
398
|
+
* Resolves once playback has started; a walkthrough that is already playing
|
|
399
|
+
* keeps playing.
|
|
400
|
+
*
|
|
401
|
+
* @param walkthroughId - The walkthrough's id
|
|
402
|
+
* @param options - `fromTimeInSeconds` (default 0)
|
|
403
|
+
* @returns The {@linkcode PluginWalkthroughPlaybackState} after starting.
|
|
404
|
+
* @throws HANDLE_INVALID when there is no walkthrough with that id. PRECONDITION_FAILED
|
|
405
|
+
* when a walkthrough is being exported.
|
|
406
|
+
*
|
|
407
|
+
* @examplePrompt Play the walkthrough
|
|
408
|
+
* @examplePrompt Show me the orbit
|
|
409
|
+
*
|
|
410
|
+
* # Example
|
|
411
|
+
* ```ts
|
|
412
|
+
* await snaptrude.presentation.walkthroughs.start(walkthroughId)
|
|
413
|
+
* ```
|
|
414
|
+
*/
|
|
415
|
+
public abstract start(
|
|
416
|
+
walkthroughId: string,
|
|
417
|
+
options?: PluginWalkthroughStartOptions,
|
|
418
|
+
): PluginApiReturn<PluginWalkthroughPlaybackState>
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Stop playback and put the camera back where it was before it started. A
|
|
422
|
+
* no-op when nothing is playing.
|
|
423
|
+
*
|
|
424
|
+
* @returns The {@linkcode PluginWalkthroughPlaybackState} after stopping.
|
|
425
|
+
*
|
|
426
|
+
* @examplePrompt Stop the walkthrough
|
|
427
|
+
*
|
|
428
|
+
* # Example
|
|
429
|
+
* ```ts
|
|
430
|
+
* await snaptrude.presentation.walkthroughs.stop()
|
|
431
|
+
* ```
|
|
432
|
+
*/
|
|
433
|
+
public abstract stop(): PluginApiReturn<PluginWalkthroughPlaybackState>
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Read the playback state: which walkthrough is playing or paused, and how
|
|
437
|
+
* far through it.
|
|
438
|
+
*
|
|
439
|
+
* @returns The current {@linkcode PluginWalkthroughPlaybackState}.
|
|
440
|
+
*
|
|
441
|
+
* @examplePrompt Is the walkthrough still playing?
|
|
442
|
+
*
|
|
443
|
+
* # Example
|
|
444
|
+
* ```ts
|
|
445
|
+
* const { status, timeInSeconds } = await snaptrude.presentation.walkthroughs.getState()
|
|
446
|
+
* ```
|
|
447
|
+
*/
|
|
448
|
+
public abstract getState(): PluginApiReturn<PluginWalkthroughPlaybackState>
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Record a walkthrough as a video and place it on the Present canvas, as an
|
|
452
|
+
* asynchronous job: this resolves at once with the queued job, and
|
|
453
|
+
* {@linkcode PluginPresentationWalkthroughsApi.getJob} reports it until it
|
|
454
|
+
* completes, fails or is cancelled. Recording plays the walkthrough in real
|
|
455
|
+
* time at the chosen size, so it takes about as long as the walkthrough plus
|
|
456
|
+
* the upload; the editor switches to Present mode to place the video, which
|
|
457
|
+
* keeps playing muted in a loop there. Only one export runs at a time.
|
|
458
|
+
* Write-gated.
|
|
459
|
+
*
|
|
460
|
+
* @param walkthroughId - The walkthrough's id
|
|
461
|
+
* @param options - Video quality and frame rate ({@linkcode PluginWalkthroughExportOptions})
|
|
462
|
+
* @returns The queued {@linkcode PluginWalkthroughExportJob}.
|
|
463
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. HANDLE_INVALID when
|
|
464
|
+
* there is no walkthrough with that id. PRECONDITION_FAILED when another export
|
|
465
|
+
* is running or this browser cannot record video.
|
|
466
|
+
*
|
|
467
|
+
* @examplePrompt Export the walkthrough as a video
|
|
468
|
+
* @examplePrompt Put a 1080p video of the orbit on a sheet
|
|
469
|
+
*
|
|
470
|
+
* # Example
|
|
471
|
+
* ```ts
|
|
472
|
+
* const walkthroughs = snaptrude.presentation.walkthroughs
|
|
473
|
+
* let job = await walkthroughs.export(walkthroughId, { quality: "1080p" })
|
|
474
|
+
* while (job.status === "queued" || job.status === "running") {
|
|
475
|
+
* await new Promise((resolve) => setTimeout(resolve, 2000))
|
|
476
|
+
* job = (await walkthroughs.getJob(job.jobId))!
|
|
477
|
+
* }
|
|
478
|
+
* console.log(job.result?.shapeId)
|
|
479
|
+
* ```
|
|
480
|
+
*/
|
|
481
|
+
public abstract export(
|
|
482
|
+
walkthroughId: string,
|
|
483
|
+
options?: PluginWalkthroughExportOptions,
|
|
484
|
+
): PluginApiReturn<PluginWalkthroughExportJob>
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Get an export job by id.
|
|
488
|
+
*
|
|
489
|
+
* @param jobId - The job's id, from {@linkcode PluginPresentationWalkthroughsApi.export}
|
|
490
|
+
* @returns The {@linkcode PluginWalkthroughExportJob}, or `null` when there is none
|
|
491
|
+
* with that id (finished jobs are forgotten after 30 minutes).
|
|
492
|
+
*
|
|
493
|
+
* @examplePrompt Is the video export done yet?
|
|
494
|
+
*
|
|
495
|
+
* # Example
|
|
496
|
+
* ```ts
|
|
497
|
+
* const job = await snaptrude.presentation.walkthroughs.getJob(jobId)
|
|
498
|
+
* ```
|
|
499
|
+
*/
|
|
500
|
+
public abstract getJob(
|
|
501
|
+
jobId: string,
|
|
502
|
+
): PluginApiReturn<PluginWalkthroughExportJob | null>
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Cancel an export job. The recording stops and nothing is placed; a job that
|
|
506
|
+
* has already finished is returned unchanged. Write-gated.
|
|
507
|
+
*
|
|
508
|
+
* @param jobId - The job's id
|
|
509
|
+
* @returns The {@linkcode PluginWalkthroughExportJob} after cancelling.
|
|
510
|
+
* @throws METHOD_NOT_PERMITTED when plugin writes are disabled. HANDLE_INVALID when
|
|
511
|
+
* there is no job with that id.
|
|
512
|
+
*
|
|
513
|
+
* @examplePrompt Cancel the video export
|
|
514
|
+
*
|
|
515
|
+
* # Example
|
|
516
|
+
* ```ts
|
|
517
|
+
* await snaptrude.presentation.walkthroughs.cancelJob(jobId)
|
|
518
|
+
* ```
|
|
519
|
+
*/
|
|
520
|
+
public abstract cancelJob(
|
|
521
|
+
jobId: string,
|
|
522
|
+
): PluginApiReturn<PluginWalkthroughExportJob>
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* List export jobs, newest first: running ones and those that finished in the
|
|
526
|
+
* last 30 minutes.
|
|
527
|
+
*
|
|
528
|
+
* @returns `{ jobs }` — each {@linkcode PluginWalkthroughExportJob} (`[]` when there are none).
|
|
529
|
+
*
|
|
530
|
+
* @examplePrompt Which video exports are running?
|
|
531
|
+
*
|
|
532
|
+
* # Example
|
|
533
|
+
* ```ts
|
|
534
|
+
* const { jobs } = await snaptrude.presentation.walkthroughs.listJobs()
|
|
535
|
+
* ```
|
|
536
|
+
*/
|
|
537
|
+
public abstract listJobs(): PluginApiReturn<PluginWalkthroughListJobsResult>
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// Plain {x, y, z} record with finite components (the brepFromRevolution `axisOrigin` pattern).
|
|
541
|
+
const FiniteVec3Components = z.object({
|
|
542
|
+
x: z.number().finite(),
|
|
543
|
+
y: z.number().finite(),
|
|
544
|
+
z: z.number().finite(),
|
|
545
|
+
})
|
|
546
|
+
|
|
547
|
+
const PositiveFinite = z.number().finite().positive()
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* How a keyframe's camera looks — exactly one of:
|
|
551
|
+
*
|
|
552
|
+
* | Shape | Meaning |
|
|
553
|
+
* |---|---|
|
|
554
|
+
* | `{ mode: "path" }` | Ahead along the path, level |
|
|
555
|
+
* | `{ mode: "target", target }` | At a point in the model |
|
|
556
|
+
* | `{ mode: "fixed", yawInDegrees, pitchInDegrees }` | In a fixed direction (pitch within ±89°) |
|
|
557
|
+
*/
|
|
558
|
+
export const PluginWalkthroughLook = z.discriminatedUnion("mode", [
|
|
559
|
+
z.object({ mode: z.literal("path") }).strict(),
|
|
560
|
+
z
|
|
561
|
+
.object({ mode: z.literal("target"), target: FiniteVec3Components })
|
|
562
|
+
.strict(),
|
|
563
|
+
z
|
|
564
|
+
.object({
|
|
565
|
+
mode: z.literal("fixed"),
|
|
566
|
+
yawInDegrees: z.number().finite(),
|
|
567
|
+
pitchInDegrees: z.number().finite().min(-89).max(89),
|
|
568
|
+
})
|
|
569
|
+
.strict(),
|
|
570
|
+
])
|
|
571
|
+
export type PluginWalkthroughLook = z.infer<typeof PluginWalkthroughLook>
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* A keyframe of a {@linkcode PluginWalkthrough}.
|
|
575
|
+
*
|
|
576
|
+
* | Property | Type | Description |
|
|
577
|
+
* |---|---|---|
|
|
578
|
+
* | `keyframeId` | `string` | The keyframe's id |
|
|
579
|
+
* | `eye` | `{ x, y, z }` | Camera position (world, `babylon` units) |
|
|
580
|
+
* | `look` | {@linkcode PluginWalkthroughLook} | How the camera looks here |
|
|
581
|
+
* | `followsFloor` | `boolean` | Stands at eye height above the floor; paths between two such keyframes follow the floor |
|
|
582
|
+
* | `holdInSeconds` | `number` | Pause here before moving on |
|
|
583
|
+
*/
|
|
584
|
+
export const PluginWalkthroughKeyframe = z.object({
|
|
585
|
+
keyframeId: z.string(),
|
|
586
|
+
eye: Vec3Components,
|
|
587
|
+
look: PluginWalkthroughLook,
|
|
588
|
+
followsFloor: z.boolean(),
|
|
589
|
+
holdInSeconds: z.number(),
|
|
590
|
+
})
|
|
591
|
+
export type PluginWalkthroughKeyframe = z.infer<
|
|
592
|
+
typeof PluginWalkthroughKeyframe
|
|
593
|
+
>
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* A keyframe to add, for {@linkcode PluginPresentationWalkthroughsApi.create} and
|
|
597
|
+
* {@linkcode PluginPresentationWalkthroughsApi.createKeyframe}.
|
|
598
|
+
*
|
|
599
|
+
* | Property | Type | Description |
|
|
600
|
+
* |---|---|---|
|
|
601
|
+
* | `eye` | `{ x, y, z }` | Camera position; with `followsFloor`, a point on or above the floor |
|
|
602
|
+
* | `look` | {@linkcode PluginWalkthroughLook} `\| undefined` | How the camera looks here (default `{ mode: "path" }`) |
|
|
603
|
+
* | `followsFloor` | `boolean \| undefined` | Stand at eye height above the floor at or below `eye` (default `false`: `eye` as given) |
|
|
604
|
+
* | `holdInSeconds` | `number \| undefined` | Pause here, 0 to 60 (default 0) |
|
|
605
|
+
*/
|
|
606
|
+
export const PluginWalkthroughKeyframeInput = z
|
|
607
|
+
.object({
|
|
608
|
+
eye: FiniteVec3Components,
|
|
609
|
+
look: PluginWalkthroughLook.optional(),
|
|
610
|
+
followsFloor: z.boolean().optional(),
|
|
611
|
+
holdInSeconds: z.number().finite().min(0).max(60).optional(),
|
|
612
|
+
})
|
|
613
|
+
.strict()
|
|
614
|
+
export type PluginWalkthroughKeyframeInput = z.infer<
|
|
615
|
+
typeof PluginWalkthroughKeyframeInput
|
|
616
|
+
>
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* The fields to change in {@linkcode PluginPresentationWalkthroughsApi.updateKeyframe};
|
|
620
|
+
* omitted fields keep their value.
|
|
621
|
+
*/
|
|
622
|
+
export const PluginWalkthroughKeyframePatch = z
|
|
623
|
+
.object({
|
|
624
|
+
eye: FiniteVec3Components.optional(),
|
|
625
|
+
look: PluginWalkthroughLook.optional(),
|
|
626
|
+
followsFloor: z.boolean().optional(),
|
|
627
|
+
holdInSeconds: z.number().finite().min(0).max(60).optional(),
|
|
628
|
+
})
|
|
629
|
+
.strict()
|
|
630
|
+
export type PluginWalkthroughKeyframePatch = z.infer<
|
|
631
|
+
typeof PluginWalkthroughKeyframePatch
|
|
632
|
+
>
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* A camera move for {@linkcode PluginPresentationWalkthroughsApi.createFromPreset}:
|
|
636
|
+
* `orbit` (circle the subject facing its middle), `flyOver` (pass above it
|
|
637
|
+
* looking ahead and down), `pushIn` / `pullBack` (move toward / away from it),
|
|
638
|
+
* `rise` (crane up from eye level).
|
|
639
|
+
*/
|
|
640
|
+
export const PluginWalkthroughPresetKind = z.enum([
|
|
641
|
+
"orbit",
|
|
642
|
+
"flyOver",
|
|
643
|
+
"pushIn",
|
|
644
|
+
"pullBack",
|
|
645
|
+
"rise",
|
|
646
|
+
])
|
|
647
|
+
export type PluginWalkthroughPresetKind = z.infer<
|
|
648
|
+
typeof PluginWalkthroughPresetKind
|
|
649
|
+
>
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* The camera move a preset walkthrough was made from.
|
|
653
|
+
*
|
|
654
|
+
* | Property | Type | Description |
|
|
655
|
+
* |---|---|---|
|
|
656
|
+
* | `kind` | {@linkcode PluginWalkthroughPresetKind} | The move |
|
|
657
|
+
* | `distance` | `number` | Camera distance, as a multiple of the distance at which the subject just fits in view |
|
|
658
|
+
* | `heightInDegrees` | `number` | Camera height, in degrees above level seen from the subject's middle |
|
|
659
|
+
* | `isClockwise` | `boolean` | Orbits only: goes round clockwise seen from above |
|
|
660
|
+
*/
|
|
661
|
+
export const PluginWalkthroughPreset = z.object({
|
|
662
|
+
kind: PluginWalkthroughPresetKind,
|
|
663
|
+
distance: z.number(),
|
|
664
|
+
heightInDegrees: z.number(),
|
|
665
|
+
isClockwise: z.boolean(),
|
|
666
|
+
})
|
|
667
|
+
export type PluginWalkthroughPreset = z.infer<typeof PluginWalkthroughPreset>
|
|
668
|
+
|
|
669
|
+
/** The Distance setting: 0.8 to 3 times the distance at which the subject just fits. */
|
|
670
|
+
const PresetDistance = z.number().finite().min(0.8).max(3)
|
|
671
|
+
/** The Height setting, in degrees above level. */
|
|
672
|
+
const PresetHeightInDegrees = z.number().finite().min(0).max(75)
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* A walkthrough.
|
|
676
|
+
*
|
|
677
|
+
* | Property | Type | Description |
|
|
678
|
+
* |---|---|---|
|
|
679
|
+
* | `walkthroughId` | `string` | The walkthrough's id |
|
|
680
|
+
* | `name` | `string` | Its name |
|
|
681
|
+
* | `keyframes` | {@linkcode PluginWalkthroughKeyframe}`[]` | Its keyframes, in order |
|
|
682
|
+
* | `isLoop` | `boolean` | The path returns from the last keyframe to the first |
|
|
683
|
+
* | `isRepeating` | `boolean` | Playback starts again when it reaches the end |
|
|
684
|
+
* | `speed` | `number` | Travel speed, `babylon` units per second |
|
|
685
|
+
* | `durationInSeconds` | `number` | How long playback takes, including easing and holds |
|
|
686
|
+
* | `pathLength` | `number` | Length of the path, `babylon` units |
|
|
687
|
+
* | `eyeHeight` | `number` | Eye height above the floor for floor-following keyframes, `babylon` units |
|
|
688
|
+
* | `preset` | {@linkcode PluginWalkthroughPreset} `\| null` | The camera move it was made from, while it is still a preset |
|
|
689
|
+
*/
|
|
690
|
+
export const PluginWalkthrough = z.object({
|
|
691
|
+
walkthroughId: z.string(),
|
|
692
|
+
name: z.string(),
|
|
693
|
+
keyframes: z.array(PluginWalkthroughKeyframe),
|
|
694
|
+
isLoop: z.boolean(),
|
|
695
|
+
isRepeating: z.boolean(),
|
|
696
|
+
speed: z.number(),
|
|
697
|
+
durationInSeconds: z.number(),
|
|
698
|
+
pathLength: z.number(),
|
|
699
|
+
eyeHeight: z.number(),
|
|
700
|
+
preset: PluginWalkthroughPreset.nullable(),
|
|
701
|
+
})
|
|
702
|
+
export type PluginWalkthrough = z.infer<typeof PluginWalkthrough>
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Result of {@linkcode PluginPresentationWalkthroughsApi.list}.
|
|
706
|
+
*/
|
|
707
|
+
export const PluginWalkthroughsListResult = z.object({
|
|
708
|
+
walkthroughs: z.array(PluginWalkthrough),
|
|
709
|
+
})
|
|
710
|
+
export type PluginWalkthroughsListResult = z.infer<
|
|
711
|
+
typeof PluginWalkthroughsListResult
|
|
712
|
+
>
|
|
713
|
+
|
|
714
|
+
const CreateOptionFields = {
|
|
715
|
+
name: z.string().trim().min(1).max(120).optional(),
|
|
716
|
+
isLoop: z.boolean().optional(),
|
|
717
|
+
isRepeating: z.boolean().optional(),
|
|
718
|
+
speed: PositiveFinite.optional(),
|
|
719
|
+
durationInSeconds: PositiveFinite.optional(),
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
const atMostOneOfSpeedAndDuration = (value: {
|
|
723
|
+
speed?: number
|
|
724
|
+
durationInSeconds?: number
|
|
725
|
+
}) => value.speed === undefined || value.durationInSeconds === undefined
|
|
726
|
+
const SPEED_AND_DURATION_MESSAGE = "Give speed or durationInSeconds, not both"
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Options for {@linkcode PluginPresentationWalkthroughsApi.create}.
|
|
730
|
+
*
|
|
731
|
+
* | Property | Type | Description |
|
|
732
|
+
* |---|---|---|
|
|
733
|
+
* | `name` | `string \| undefined` | Its name (default "Walkthrough N") |
|
|
734
|
+
* | `isLoop` | `boolean \| undefined` | Return from the last keyframe to the first (default `false`; needs 3 keyframes) |
|
|
735
|
+
* | `isRepeating` | `boolean \| undefined` | Play again from the start at the end (default `false`) |
|
|
736
|
+
* | `speed` | `number \| undefined` | Travel speed, `babylon` units per second (default 1 m/s) |
|
|
737
|
+
* | `durationInSeconds` | `number \| undefined` | Take this long instead; sets the speed. Give `speed` or this, not both |
|
|
738
|
+
*/
|
|
739
|
+
export const PluginWalkthroughCreateOptions = z
|
|
740
|
+
.object(CreateOptionFields)
|
|
741
|
+
.strict()
|
|
742
|
+
.refine(atMostOneOfSpeedAndDuration, SPEED_AND_DURATION_MESSAGE)
|
|
743
|
+
export type PluginWalkthroughCreateOptions = z.infer<
|
|
744
|
+
typeof PluginWalkthroughCreateOptions
|
|
745
|
+
>
|
|
746
|
+
|
|
747
|
+
/**
|
|
748
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.create}.
|
|
749
|
+
*/
|
|
750
|
+
export const PluginWalkthroughCreateArgs = z.object({
|
|
751
|
+
keyframes: z.array(PluginWalkthroughKeyframeInput).min(1).max(200),
|
|
752
|
+
options: PluginWalkthroughCreateOptions.optional(),
|
|
753
|
+
})
|
|
754
|
+
export type PluginWalkthroughCreateArgs = z.infer<
|
|
755
|
+
typeof PluginWalkthroughCreateArgs
|
|
756
|
+
>
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Options for {@linkcode PluginPresentationWalkthroughsApi.createFromPoints}: those of
|
|
760
|
+
* {@linkcode PluginWalkthroughCreateOptions}, plus:
|
|
761
|
+
*
|
|
762
|
+
* | Property | Type | Description |
|
|
763
|
+
* |---|---|---|
|
|
764
|
+
* | `lookAt` | `{ x, y, z } \| undefined` | Look at this point the whole way (default: ahead along the path) |
|
|
765
|
+
*/
|
|
766
|
+
export const PluginWalkthroughCreateFromPointsOptions = z
|
|
767
|
+
.object({ ...CreateOptionFields, lookAt: FiniteVec3Components.optional() })
|
|
768
|
+
.strict()
|
|
769
|
+
.refine(atMostOneOfSpeedAndDuration, SPEED_AND_DURATION_MESSAGE)
|
|
770
|
+
export type PluginWalkthroughCreateFromPointsOptions = z.infer<
|
|
771
|
+
typeof PluginWalkthroughCreateFromPointsOptions
|
|
772
|
+
>
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.createFromPoints}.
|
|
776
|
+
*/
|
|
777
|
+
export const PluginWalkthroughCreateFromPointsArgs = z.object({
|
|
778
|
+
points: z.array(FiniteVec3Components).min(2).max(200),
|
|
779
|
+
options: PluginWalkthroughCreateFromPointsOptions.optional(),
|
|
780
|
+
})
|
|
781
|
+
export type PluginWalkthroughCreateFromPointsArgs = z.infer<
|
|
782
|
+
typeof PluginWalkthroughCreateFromPointsArgs
|
|
783
|
+
>
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* Options for {@linkcode PluginPresentationWalkthroughsApi.createFromPreset}.
|
|
787
|
+
*
|
|
788
|
+
* | Property | Type | Description |
|
|
789
|
+
* |---|---|---|
|
|
790
|
+
* | `subject` | {@linkcode ComponentHandle}`[] \| undefined` | What to frame (default: the selection, else the visible model without terrain) |
|
|
791
|
+
* | `distance` | `number \| undefined` | 0.8 to 3 times the distance at which the subject just fits (default per move) |
|
|
792
|
+
* | `heightInDegrees` | `number \| undefined` | 0 to 75 degrees above level (default per move) |
|
|
793
|
+
* | `isClockwise` | `boolean \| undefined` | Orbits only: go round clockwise seen from above (default `false`) |
|
|
794
|
+
* | `durationInSeconds` | `number \| undefined` | How long the move takes (default per move: orbit 24, fly over 12, others 8) |
|
|
795
|
+
* | `name` | `string \| undefined` | Its name (default the move's name and a number) |
|
|
796
|
+
* | `isRepeating` | `boolean \| undefined` | Play again from the start at the end (default `false`) |
|
|
797
|
+
*/
|
|
798
|
+
export const PluginWalkthroughCreateFromPresetOptions = z
|
|
799
|
+
.object({
|
|
800
|
+
subject: z.array(ComponentHandle).min(1).max(1000).optional(),
|
|
801
|
+
distance: PresetDistance.optional(),
|
|
802
|
+
heightInDegrees: PresetHeightInDegrees.optional(),
|
|
803
|
+
isClockwise: z.boolean().optional(),
|
|
804
|
+
durationInSeconds: PositiveFinite.optional(),
|
|
805
|
+
name: z.string().trim().min(1).max(120).optional(),
|
|
806
|
+
isRepeating: z.boolean().optional(),
|
|
807
|
+
})
|
|
808
|
+
.strict()
|
|
809
|
+
export type PluginWalkthroughCreateFromPresetOptions = z.infer<
|
|
810
|
+
typeof PluginWalkthroughCreateFromPresetOptions
|
|
811
|
+
>
|
|
812
|
+
|
|
813
|
+
/**
|
|
814
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.createFromPreset}.
|
|
815
|
+
*/
|
|
816
|
+
export const PluginWalkthroughCreateFromPresetArgs = z.object({
|
|
817
|
+
kind: PluginWalkthroughPresetKind,
|
|
818
|
+
options: PluginWalkthroughCreateFromPresetOptions.optional(),
|
|
819
|
+
})
|
|
820
|
+
export type PluginWalkthroughCreateFromPresetArgs = z.infer<
|
|
821
|
+
typeof PluginWalkthroughCreateFromPresetArgs
|
|
822
|
+
>
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
* The fields to change in {@linkcode PluginPresentationWalkthroughsApi.update};
|
|
826
|
+
* omitted fields keep their value.
|
|
827
|
+
*
|
|
828
|
+
* | Property | Type | Description |
|
|
829
|
+
* |---|---|---|
|
|
830
|
+
* | `name` | `string \| undefined` | New name |
|
|
831
|
+
* | `isLoop` | `boolean \| undefined` | Return from the last keyframe to the first (needs 3 keyframes); makes a preset ordinary |
|
|
832
|
+
* | `isRepeating` | `boolean \| undefined` | Play again from the start at the end |
|
|
833
|
+
* | `speed` | `number \| undefined` | Travel speed, `babylon` units per second |
|
|
834
|
+
* | `durationInSeconds` | `number \| undefined` | Take this long; sets the speed. Give `speed` or this, not both |
|
|
835
|
+
* | `preset` | `{ distance?, heightInDegrees?, isClockwise? } \| undefined` | A preset walkthrough's move settings; its keyframes are made again |
|
|
836
|
+
*/
|
|
837
|
+
export const PluginWalkthroughPatch = z
|
|
838
|
+
.object({
|
|
839
|
+
name: z.string().trim().min(1).max(120).optional(),
|
|
840
|
+
isLoop: z.boolean().optional(),
|
|
841
|
+
isRepeating: z.boolean().optional(),
|
|
842
|
+
speed: PositiveFinite.optional(),
|
|
843
|
+
durationInSeconds: PositiveFinite.optional(),
|
|
844
|
+
preset: z
|
|
845
|
+
.object({
|
|
846
|
+
distance: PresetDistance.optional(),
|
|
847
|
+
heightInDegrees: PresetHeightInDegrees.optional(),
|
|
848
|
+
isClockwise: z.boolean().optional(),
|
|
849
|
+
})
|
|
850
|
+
.strict()
|
|
851
|
+
.optional(),
|
|
852
|
+
})
|
|
853
|
+
.strict()
|
|
854
|
+
.refine(atMostOneOfSpeedAndDuration, SPEED_AND_DURATION_MESSAGE)
|
|
855
|
+
export type PluginWalkthroughPatch = z.infer<typeof PluginWalkthroughPatch>
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.update}.
|
|
859
|
+
*/
|
|
860
|
+
export const PluginWalkthroughUpdateArgs = z.object({
|
|
861
|
+
walkthroughId: z.string().min(1),
|
|
862
|
+
patch: PluginWalkthroughPatch,
|
|
863
|
+
})
|
|
864
|
+
export type PluginWalkthroughUpdateArgs = z.infer<
|
|
865
|
+
typeof PluginWalkthroughUpdateArgs
|
|
866
|
+
>
|
|
867
|
+
|
|
868
|
+
/**
|
|
869
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.createKeyframe}.
|
|
870
|
+
*/
|
|
871
|
+
export const PluginWalkthroughCreateKeyframeArgs = z.object({
|
|
872
|
+
walkthroughId: z.string().min(1),
|
|
873
|
+
keyframe: PluginWalkthroughKeyframeInput,
|
|
874
|
+
index: z.number().int().min(0).optional(),
|
|
875
|
+
})
|
|
876
|
+
export type PluginWalkthroughCreateKeyframeArgs = z.infer<
|
|
877
|
+
typeof PluginWalkthroughCreateKeyframeArgs
|
|
878
|
+
>
|
|
879
|
+
|
|
880
|
+
/**
|
|
881
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.updateKeyframe}.
|
|
882
|
+
*/
|
|
883
|
+
export const PluginWalkthroughUpdateKeyframeArgs = z.object({
|
|
884
|
+
walkthroughId: z.string().min(1),
|
|
885
|
+
keyframeId: z.string().min(1),
|
|
886
|
+
patch: PluginWalkthroughKeyframePatch,
|
|
887
|
+
})
|
|
888
|
+
export type PluginWalkthroughUpdateKeyframeArgs = z.infer<
|
|
889
|
+
typeof PluginWalkthroughUpdateKeyframeArgs
|
|
890
|
+
>
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.deleteKeyframe}.
|
|
894
|
+
*/
|
|
895
|
+
export const PluginWalkthroughDeleteKeyframeArgs = z.object({
|
|
896
|
+
walkthroughId: z.string().min(1),
|
|
897
|
+
keyframeId: z.string().min(1),
|
|
898
|
+
})
|
|
899
|
+
export type PluginWalkthroughDeleteKeyframeArgs = z.infer<
|
|
900
|
+
typeof PluginWalkthroughDeleteKeyframeArgs
|
|
901
|
+
>
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.reorderKeyframe}.
|
|
905
|
+
*/
|
|
906
|
+
export const PluginWalkthroughReorderKeyframeArgs = z.object({
|
|
907
|
+
walkthroughId: z.string().min(1),
|
|
908
|
+
keyframeId: z.string().min(1),
|
|
909
|
+
index: z.number().int().min(0),
|
|
910
|
+
})
|
|
911
|
+
export type PluginWalkthroughReorderKeyframeArgs = z.infer<
|
|
912
|
+
typeof PluginWalkthroughReorderKeyframeArgs
|
|
913
|
+
>
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Where the camera is at one moment — an item of
|
|
917
|
+
* {@linkcode PluginWalkthroughSampleResult}.
|
|
918
|
+
*
|
|
919
|
+
* | Property | Type | Description |
|
|
920
|
+
* |---|---|---|
|
|
921
|
+
* | `timeInSeconds` | `number` | The moment (clamped to the walkthrough's duration) |
|
|
922
|
+
* | `eye` | `{ x, y, z }` | Camera position |
|
|
923
|
+
* | `direction` | `{ x, y, z }` | Unit view direction |
|
|
924
|
+
* | `yawInDegrees` | `number` | View direction, degrees clockwise from +z seen from above |
|
|
925
|
+
* | `pitchInDegrees` | `number` | View direction, degrees above level |
|
|
926
|
+
*/
|
|
927
|
+
export const PluginWalkthroughSample = z.object({
|
|
928
|
+
timeInSeconds: z.number(),
|
|
929
|
+
eye: Vec3Components,
|
|
930
|
+
direction: Vec3Components,
|
|
931
|
+
yawInDegrees: z.number(),
|
|
932
|
+
pitchInDegrees: z.number(),
|
|
933
|
+
})
|
|
934
|
+
export type PluginWalkthroughSample = z.infer<typeof PluginWalkthroughSample>
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.sample}.
|
|
938
|
+
*/
|
|
939
|
+
export const PluginWalkthroughSampleArgs = z.object({
|
|
940
|
+
walkthroughId: z.string().min(1),
|
|
941
|
+
timesInSeconds: z.array(z.number().finite()).min(1).max(500),
|
|
942
|
+
})
|
|
943
|
+
export type PluginWalkthroughSampleArgs = z.infer<
|
|
944
|
+
typeof PluginWalkthroughSampleArgs
|
|
945
|
+
>
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Result of {@linkcode PluginPresentationWalkthroughsApi.sample}.
|
|
949
|
+
*/
|
|
950
|
+
export const PluginWalkthroughSampleResult = z.object({
|
|
951
|
+
samples: z.array(PluginWalkthroughSample),
|
|
952
|
+
})
|
|
953
|
+
export type PluginWalkthroughSampleResult = z.infer<
|
|
954
|
+
typeof PluginWalkthroughSampleResult
|
|
955
|
+
>
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* What is wrong at a walkthrough issue: `throughGeometry` — the camera passes
|
|
959
|
+
* through the model (a wall, glazing, a column, a slab, a roof or other solid
|
|
960
|
+
* that walking would stop at).
|
|
961
|
+
*/
|
|
962
|
+
export const PluginWalkthroughIssueKind = z.enum(["throughGeometry"])
|
|
963
|
+
export type PluginWalkthroughIssueKind = z.infer<
|
|
964
|
+
typeof PluginWalkthroughIssueKind
|
|
965
|
+
>
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* A place where a walkthrough's camera passes through the model — an item of
|
|
969
|
+
* {@linkcode PluginWalkthroughListIssuesResult}.
|
|
970
|
+
*
|
|
971
|
+
* | Property | Type | Description |
|
|
972
|
+
* |---|---|---|
|
|
973
|
+
* | `kind` | {@linkcode PluginWalkthroughIssueKind} | What is wrong |
|
|
974
|
+
* | `timeInSeconds` | `number` | When the camera reaches it during playback |
|
|
975
|
+
* | `point` | `{ x, y, z }` | Where the path enters the geometry |
|
|
976
|
+
* | `componentId` | `string \| null` | The component passed through, when it is one |
|
|
977
|
+
*/
|
|
978
|
+
export const PluginWalkthroughIssue = z.object({
|
|
979
|
+
kind: PluginWalkthroughIssueKind,
|
|
980
|
+
timeInSeconds: z.number(),
|
|
981
|
+
point: Vec3Components,
|
|
982
|
+
componentId: z.string().nullable(),
|
|
983
|
+
})
|
|
984
|
+
export type PluginWalkthroughIssue = z.infer<typeof PluginWalkthroughIssue>
|
|
985
|
+
|
|
986
|
+
/**
|
|
987
|
+
* Result of {@linkcode PluginPresentationWalkthroughsApi.listIssues}.
|
|
988
|
+
*/
|
|
989
|
+
export const PluginWalkthroughListIssuesResult = z.object({
|
|
990
|
+
issues: z.array(PluginWalkthroughIssue),
|
|
991
|
+
})
|
|
992
|
+
export type PluginWalkthroughListIssuesResult = z.infer<
|
|
993
|
+
typeof PluginWalkthroughListIssuesResult
|
|
994
|
+
>
|
|
995
|
+
|
|
996
|
+
/**
|
|
997
|
+
* Options for {@linkcode PluginPresentationWalkthroughsApi.capture}.
|
|
998
|
+
*
|
|
999
|
+
* | Property | Type | Description |
|
|
1000
|
+
* |---|---|---|
|
|
1001
|
+
* | `count` | `number \| undefined` | Frames at evenly spaced moments, first to last, 1 to 12 (default 6) |
|
|
1002
|
+
* | `timesInSeconds` | `number[] \| undefined` | Capture these 1 to 12 moments instead. Give `count` or this, not both |
|
|
1003
|
+
* | `width` | `number \| undefined` | Width of the whole image in pixels, 256 to 2048 (default 1536) |
|
|
1004
|
+
* | `format` | `"png" \| "jpeg" \| undefined` | Image format (default `"jpeg"`) |
|
|
1005
|
+
*/
|
|
1006
|
+
export const PluginWalkthroughCaptureOptions = z
|
|
1007
|
+
.object({
|
|
1008
|
+
count: z.number().int().min(1).max(12).optional(),
|
|
1009
|
+
timesInSeconds: z.array(z.number().finite()).min(1).max(12).optional(),
|
|
1010
|
+
width: z.number().int().min(256).max(2048).optional(),
|
|
1011
|
+
format: z.enum(["png", "jpeg"]).optional(),
|
|
1012
|
+
})
|
|
1013
|
+
.strict()
|
|
1014
|
+
.refine(
|
|
1015
|
+
(value) => value.count === undefined || value.timesInSeconds === undefined,
|
|
1016
|
+
"Give count or timesInSeconds, not both",
|
|
1017
|
+
)
|
|
1018
|
+
export type PluginWalkthroughCaptureOptions = z.infer<
|
|
1019
|
+
typeof PluginWalkthroughCaptureOptions
|
|
1020
|
+
>
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.capture}.
|
|
1024
|
+
*/
|
|
1025
|
+
export const PluginWalkthroughCaptureArgs = z.object({
|
|
1026
|
+
walkthroughId: z.string().min(1),
|
|
1027
|
+
options: PluginWalkthroughCaptureOptions.optional(),
|
|
1028
|
+
})
|
|
1029
|
+
export type PluginWalkthroughCaptureArgs = z.infer<
|
|
1030
|
+
typeof PluginWalkthroughCaptureArgs
|
|
1031
|
+
>
|
|
1032
|
+
|
|
1033
|
+
/**
|
|
1034
|
+
* Result of {@linkcode PluginPresentationWalkthroughsApi.capture}.
|
|
1035
|
+
*
|
|
1036
|
+
* | Property | Type | Description |
|
|
1037
|
+
* |---|---|---|
|
|
1038
|
+
* | `image` | `string` | The contact sheet as a base64 data URL |
|
|
1039
|
+
* | `frames` | `{ timeInSeconds }[]` | The moment of each frame, left to right and top to bottom |
|
|
1040
|
+
*/
|
|
1041
|
+
export const PluginWalkthroughCaptureResult = z.object({
|
|
1042
|
+
image: z.string(),
|
|
1043
|
+
frames: z.array(z.object({ timeInSeconds: z.number() })),
|
|
1044
|
+
})
|
|
1045
|
+
export type PluginWalkthroughCaptureResult = z.infer<
|
|
1046
|
+
typeof PluginWalkthroughCaptureResult
|
|
1047
|
+
>
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* Options for {@linkcode PluginPresentationWalkthroughsApi.start}.
|
|
1051
|
+
*
|
|
1052
|
+
* | Property | Type | Description |
|
|
1053
|
+
* |---|---|---|
|
|
1054
|
+
* | `fromTimeInSeconds` | `number \| undefined` | Start this far in (default 0) |
|
|
1055
|
+
*/
|
|
1056
|
+
export const PluginWalkthroughStartOptions = z
|
|
1057
|
+
.object({ fromTimeInSeconds: z.number().finite().min(0).optional() })
|
|
1058
|
+
.strict()
|
|
1059
|
+
export type PluginWalkthroughStartOptions = z.infer<
|
|
1060
|
+
typeof PluginWalkthroughStartOptions
|
|
1061
|
+
>
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.start}.
|
|
1065
|
+
*/
|
|
1066
|
+
export const PluginWalkthroughStartArgs = z.object({
|
|
1067
|
+
walkthroughId: z.string().min(1),
|
|
1068
|
+
options: PluginWalkthroughStartOptions.optional(),
|
|
1069
|
+
})
|
|
1070
|
+
export type PluginWalkthroughStartArgs = z.infer<
|
|
1071
|
+
typeof PluginWalkthroughStartArgs
|
|
1072
|
+
>
|
|
1073
|
+
|
|
1074
|
+
/**
|
|
1075
|
+
* The playback state — result of {@linkcode PluginPresentationWalkthroughsApi.start},
|
|
1076
|
+
* {@linkcode PluginPresentationWalkthroughsApi.stop} and
|
|
1077
|
+
* {@linkcode PluginPresentationWalkthroughsApi.getState}.
|
|
1078
|
+
*
|
|
1079
|
+
* | Property | Type | Description |
|
|
1080
|
+
* |---|---|---|
|
|
1081
|
+
* | `status` | `"stopped" \| "playing" \| "paused"` | Playback status |
|
|
1082
|
+
* | `walkthroughId` | `string \| null` | The walkthrough playing or paused (`null` when stopped) |
|
|
1083
|
+
* | `timeInSeconds` | `number` | How far through it |
|
|
1084
|
+
* | `durationInSeconds` | `number` | Its duration (0 when stopped) |
|
|
1085
|
+
* | `isRecording` | `boolean` | Whether playback is being recorded by an export |
|
|
1086
|
+
*/
|
|
1087
|
+
export const PluginWalkthroughPlaybackState = z.object({
|
|
1088
|
+
status: z.enum(["stopped", "playing", "paused"]),
|
|
1089
|
+
walkthroughId: z.string().nullable(),
|
|
1090
|
+
timeInSeconds: z.number(),
|
|
1091
|
+
durationInSeconds: z.number(),
|
|
1092
|
+
isRecording: z.boolean(),
|
|
1093
|
+
})
|
|
1094
|
+
export type PluginWalkthroughPlaybackState = z.infer<
|
|
1095
|
+
typeof PluginWalkthroughPlaybackState
|
|
1096
|
+
>
|
|
1097
|
+
|
|
1098
|
+
/**
|
|
1099
|
+
* Options for {@linkcode PluginPresentationWalkthroughsApi.export}.
|
|
1100
|
+
*
|
|
1101
|
+
* | Property | Type | Description |
|
|
1102
|
+
* |---|---|---|
|
|
1103
|
+
* | `quality` | `"720p" \| "1080p" \| "4k" \| undefined` | Video size (default `"1080p"`) |
|
|
1104
|
+
* | `framesPerSecond` | `30 \| 60 \| undefined` | Frame rate (default 30) |
|
|
1105
|
+
*/
|
|
1106
|
+
export const PluginWalkthroughExportOptions = z
|
|
1107
|
+
.object({
|
|
1108
|
+
quality: z.enum(["720p", "1080p", "4k"]).optional(),
|
|
1109
|
+
framesPerSecond: z.union([z.literal(30), z.literal(60)]).optional(),
|
|
1110
|
+
})
|
|
1111
|
+
.strict()
|
|
1112
|
+
export type PluginWalkthroughExportOptions = z.infer<
|
|
1113
|
+
typeof PluginWalkthroughExportOptions
|
|
1114
|
+
>
|
|
1115
|
+
|
|
1116
|
+
/**
|
|
1117
|
+
* Arguments for {@linkcode PluginPresentationWalkthroughsApi.export}.
|
|
1118
|
+
*/
|
|
1119
|
+
export const PluginWalkthroughExportArgs = z.object({
|
|
1120
|
+
walkthroughId: z.string().min(1),
|
|
1121
|
+
options: PluginWalkthroughExportOptions.optional(),
|
|
1122
|
+
})
|
|
1123
|
+
export type PluginWalkthroughExportArgs = z.infer<
|
|
1124
|
+
typeof PluginWalkthroughExportArgs
|
|
1125
|
+
>
|
|
1126
|
+
|
|
1127
|
+
/**
|
|
1128
|
+
* The status of a {@linkcode PluginWalkthroughExportJob}.
|
|
1129
|
+
*/
|
|
1130
|
+
export const PluginWalkthroughExportJobStatus = z.enum([
|
|
1131
|
+
"queued",
|
|
1132
|
+
"running",
|
|
1133
|
+
"completed",
|
|
1134
|
+
"failed",
|
|
1135
|
+
"cancelled",
|
|
1136
|
+
])
|
|
1137
|
+
export type PluginWalkthroughExportJobStatus = z.infer<
|
|
1138
|
+
typeof PluginWalkthroughExportJobStatus
|
|
1139
|
+
>
|
|
1140
|
+
|
|
1141
|
+
/**
|
|
1142
|
+
* What a completed export made.
|
|
1143
|
+
*
|
|
1144
|
+
* | Property | Type | Description |
|
|
1145
|
+
* |---|---|---|
|
|
1146
|
+
* | `shapeId` | `string` | The video shape on the Present canvas |
|
|
1147
|
+
* | `videoUrl` | `string \| null` | Where the uploaded video is stored |
|
|
1148
|
+
* | `width` / `height` | `number` | Video size in pixels |
|
|
1149
|
+
* | `mimeType` | `string` | Video type, e.g. `video/mp4` |
|
|
1150
|
+
* | `durationInSeconds` | `number` | Video length |
|
|
1151
|
+
*/
|
|
1152
|
+
export const PluginWalkthroughExportResult = z.object({
|
|
1153
|
+
shapeId: z.string(),
|
|
1154
|
+
videoUrl: z.string().nullable(),
|
|
1155
|
+
width: z.number(),
|
|
1156
|
+
height: z.number(),
|
|
1157
|
+
mimeType: z.string(),
|
|
1158
|
+
durationInSeconds: z.number(),
|
|
1159
|
+
})
|
|
1160
|
+
export type PluginWalkthroughExportResult = z.infer<
|
|
1161
|
+
typeof PluginWalkthroughExportResult
|
|
1162
|
+
>
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* A walkthrough video export job.
|
|
1166
|
+
*
|
|
1167
|
+
* | Property | Type | Description |
|
|
1168
|
+
* |---|---|---|
|
|
1169
|
+
* | `jobId` | `string` | The job's id |
|
|
1170
|
+
* | `walkthroughId` | `string` | The walkthrough being exported |
|
|
1171
|
+
* | `status` | {@linkcode PluginWalkthroughExportJobStatus} | Where the job is |
|
|
1172
|
+
* | `createdAt` / `updatedAt` | `number` | Epoch milliseconds |
|
|
1173
|
+
* | `completedAt` | `number \| undefined` | When it completed, failed or was cancelled |
|
|
1174
|
+
* | `progress` | `number \| undefined` | 0 to 1 while running |
|
|
1175
|
+
* | `result` | {@linkcode PluginWalkthroughExportResult} `\| undefined` | What it made, once completed |
|
|
1176
|
+
* | `error` | `string \| undefined` | Why it failed |
|
|
1177
|
+
*/
|
|
1178
|
+
export const PluginWalkthroughExportJob = z.object({
|
|
1179
|
+
jobId: z.string(),
|
|
1180
|
+
walkthroughId: z.string(),
|
|
1181
|
+
status: PluginWalkthroughExportJobStatus,
|
|
1182
|
+
createdAt: z.number(),
|
|
1183
|
+
updatedAt: z.number(),
|
|
1184
|
+
completedAt: z.number().optional(),
|
|
1185
|
+
progress: z.number().min(0).max(1).optional(),
|
|
1186
|
+
result: PluginWalkthroughExportResult.optional(),
|
|
1187
|
+
error: z.string().optional(),
|
|
1188
|
+
})
|
|
1189
|
+
export type PluginWalkthroughExportJob = z.infer<
|
|
1190
|
+
typeof PluginWalkthroughExportJob
|
|
1191
|
+
>
|
|
1192
|
+
|
|
1193
|
+
/**
|
|
1194
|
+
* Result of {@linkcode PluginPresentationWalkthroughsApi.listJobs}.
|
|
1195
|
+
*/
|
|
1196
|
+
export const PluginWalkthroughListJobsResult = z.object({
|
|
1197
|
+
jobs: z.array(PluginWalkthroughExportJob),
|
|
1198
|
+
})
|
|
1199
|
+
export type PluginWalkthroughListJobsResult = z.infer<
|
|
1200
|
+
typeof PluginWalkthroughListJobsResult
|
|
1201
|
+
>
|