@tileflow/core 0.1.0-alpha.32 → 0.1.0-alpha.34
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/README.md +36 -1
- package/THIRD_PARTY_NOTICES.md +25 -2
- package/dist/browser.d.ts +1217 -1
- package/dist/browser.js +10339 -2849
- package/dist/build.d.ts +15 -6
- package/dist/build.js +1234 -427
- package/dist/{capture-scene-BaAJjGq7.d.ts → capture-shot-ChPQvPyi.d.ts} +121 -1
- package/dist/capture.d.ts +1 -1
- package/dist/capture.js +218 -0
- package/dist/config-reference.json +2646 -766
- package/dist/{icon-composition-Befmn-zZ.d.ts → icon-composition-DqoZWQuz.d.ts} +318 -3
- package/dist/index.d.ts +122 -7
- package/dist/index.js +2533 -985
- package/dist/{manifest-types-E7m23eXL.d.ts → manifest-types-hmzy2bBX.d.ts} +20 -1
- package/dist/manifest.d.ts +2 -2
- package/dist/native.js +1893 -1884
- package/dist/runtime.d.ts +1 -1
- package/docs/application-tile-reading.md +83 -0
- package/docs/authoring-model.md +13 -3
- package/docs/buildings-3d.md +172 -0
- package/docs/camera-moves-and-tile-cache.md +112 -0
- package/docs/capture-scenes.md +4 -0
- package/docs/capture-shots.md +173 -0
- package/docs/depth-markers.md +65 -0
- package/docs/public-api-and-browser-subpath.md +3 -3
- package/docs/route-drawing.md +191 -0
- package/docs/street-lights.md +107 -0
- package/docs/sun-and-light.md +125 -0
- package/docs/themes-and-module-styles.md +7 -0
- package/docs/trees-3d.md +211 -0
- package/package.json +4 -1
|
@@ -168,4 +168,124 @@ type NormalizedTileflowCaptureScene = {
|
|
|
168
168
|
declare function normalizeTileflowCaptureScene(input: TileflowCaptureScene): NormalizedTileflowCaptureScene;
|
|
169
169
|
declare function normalizeTileflowCaptureId(value: string | undefined): string | undefined;
|
|
170
170
|
|
|
171
|
-
|
|
171
|
+
/** A camera between keyframes: always the center form, with bearing and pitch resolved. */
|
|
172
|
+
type TileflowShotCamera = {
|
|
173
|
+
type: 'center';
|
|
174
|
+
center: [number, number];
|
|
175
|
+
zoom: number;
|
|
176
|
+
bearing: number;
|
|
177
|
+
pitch: number;
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
declare const tileflowCaptureShotSchemaVersion: 1;
|
|
181
|
+
declare const tileflowCaptureShotLimits: Readonly<{
|
|
182
|
+
blendThemes: Readonly<{
|
|
183
|
+
maximum: 8;
|
|
184
|
+
minimum: 2;
|
|
185
|
+
}>;
|
|
186
|
+
defaultFps: 30;
|
|
187
|
+
durationMs: Readonly<{
|
|
188
|
+
maximum: 60000;
|
|
189
|
+
}>;
|
|
190
|
+
fps: readonly [24, 25, 30, 50, 60];
|
|
191
|
+
keyframes: Readonly<{
|
|
192
|
+
maximum: 64;
|
|
193
|
+
minimum: 2;
|
|
194
|
+
}>;
|
|
195
|
+
maximumFrames: 3600;
|
|
196
|
+
}>;
|
|
197
|
+
/** Shot names follow the same portable artifact-name rules as scene names. */
|
|
198
|
+
declare const tileflowCaptureShotNameSchema: z.ZodString;
|
|
199
|
+
declare const tileflowCaptureShotBlendSchema: z.ZodObject<{
|
|
200
|
+
themes: z.ZodArray<z.ZodString>;
|
|
201
|
+
position: z.ZodNumber;
|
|
202
|
+
}, z.core.$strict>;
|
|
203
|
+
declare const tileflowCaptureShotKeyframeSchema: z.ZodObject<{
|
|
204
|
+
at: z.ZodNumber;
|
|
205
|
+
camera: z.ZodObject<{
|
|
206
|
+
type: z.ZodLiteral<"center">;
|
|
207
|
+
center: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
208
|
+
zoom: z.ZodNumber;
|
|
209
|
+
bearing: z.ZodOptional<z.ZodNumber>;
|
|
210
|
+
pitch: z.ZodOptional<z.ZodNumber>;
|
|
211
|
+
}, z.core.$strict>;
|
|
212
|
+
blend: z.ZodOptional<z.ZodObject<{
|
|
213
|
+
themes: z.ZodArray<z.ZodString>;
|
|
214
|
+
position: z.ZodNumber;
|
|
215
|
+
}, z.core.$strict>>;
|
|
216
|
+
}, z.core.$strict>;
|
|
217
|
+
declare const tileflowCaptureShotSchema: z.ZodObject<{
|
|
218
|
+
theme: z.ZodString;
|
|
219
|
+
viewport: z.ZodObject<{
|
|
220
|
+
width: z.ZodNumber;
|
|
221
|
+
height: z.ZodNumber;
|
|
222
|
+
dpr: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<2>]>>;
|
|
223
|
+
}, z.core.$strict>;
|
|
224
|
+
fps: z.ZodOptional<z.ZodLiteral<24 | 25 | 30 | 50 | 60>>;
|
|
225
|
+
keyframes: z.ZodArray<z.ZodObject<{
|
|
226
|
+
at: z.ZodNumber;
|
|
227
|
+
camera: z.ZodObject<{
|
|
228
|
+
type: z.ZodLiteral<"center">;
|
|
229
|
+
center: z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>;
|
|
230
|
+
zoom: z.ZodNumber;
|
|
231
|
+
bearing: z.ZodOptional<z.ZodNumber>;
|
|
232
|
+
pitch: z.ZodOptional<z.ZodNumber>;
|
|
233
|
+
}, z.core.$strict>;
|
|
234
|
+
blend: z.ZodOptional<z.ZodObject<{
|
|
235
|
+
themes: z.ZodArray<z.ZodString>;
|
|
236
|
+
position: z.ZodNumber;
|
|
237
|
+
}, z.core.$strict>>;
|
|
238
|
+
}, z.core.$strict>>;
|
|
239
|
+
easing: z.ZodOptional<z.ZodEnum<{
|
|
240
|
+
linear: "linear";
|
|
241
|
+
smooth: "smooth";
|
|
242
|
+
}>>;
|
|
243
|
+
map: z.ZodString;
|
|
244
|
+
}, z.core.$strict>;
|
|
245
|
+
type TileflowCaptureShotBlend = z.infer<typeof tileflowCaptureShotBlendSchema>;
|
|
246
|
+
type TileflowCaptureShotKeyframe = z.infer<typeof tileflowCaptureShotKeyframeSchema>;
|
|
247
|
+
type TileflowCaptureShot = z.infer<typeof tileflowCaptureShotSchema>;
|
|
248
|
+
type TileflowCaptureShotEasing = 'linear' | 'smooth';
|
|
249
|
+
type NormalizedTileflowCaptureShotCamera = TileflowShotCamera;
|
|
250
|
+
type NormalizedTileflowCaptureShot = {
|
|
251
|
+
map: string;
|
|
252
|
+
theme: string;
|
|
253
|
+
viewport: {
|
|
254
|
+
width: number;
|
|
255
|
+
height: number;
|
|
256
|
+
dpr: 1 | 2;
|
|
257
|
+
};
|
|
258
|
+
fps: 24 | 25 | 30 | 50 | 60;
|
|
259
|
+
easing: TileflowCaptureShotEasing;
|
|
260
|
+
keyframes: Array<{
|
|
261
|
+
at: number;
|
|
262
|
+
camera: NormalizedTileflowCaptureShotCamera;
|
|
263
|
+
blend?: {
|
|
264
|
+
themes: string[];
|
|
265
|
+
position: number;
|
|
266
|
+
};
|
|
267
|
+
}>;
|
|
268
|
+
};
|
|
269
|
+
/** One rendered frame of a shot: the camera and blend position at `at` milliseconds. */
|
|
270
|
+
type TileflowCaptureShotFrame = {
|
|
271
|
+
index: number;
|
|
272
|
+
at: number;
|
|
273
|
+
camera: NormalizedTileflowCaptureShotCamera;
|
|
274
|
+
/** Present when the shot blends themes. */
|
|
275
|
+
blendPosition?: number;
|
|
276
|
+
};
|
|
277
|
+
declare function normalizeTileflowCaptureShot(input: TileflowCaptureShot): NormalizedTileflowCaptureShot;
|
|
278
|
+
/**
|
|
279
|
+
* The number of frames a shot renders: one at the start and one every `1 / fps` seconds up to its
|
|
280
|
+
* last keyframe. The last keyframe is a frame when its time is a whole number of frame intervals.
|
|
281
|
+
*/
|
|
282
|
+
declare function tileflowCaptureShotFrameCount(shot: Pick<TileflowCaptureShot, 'fps' | 'keyframes'>): number;
|
|
283
|
+
/**
|
|
284
|
+
* Interpolates every frame of a shot. Frame `i` shows the shot at `i * 1000 / fps` milliseconds.
|
|
285
|
+
* Within each keyframe segment the center moves in Web Mercator coordinates along the shorter way
|
|
286
|
+
* around the world, zoom and pitch change linearly, bearing turns along the shorter arc, and the
|
|
287
|
+
* blend position changes linearly; `easing: 'smooth'` eases each segment in and out.
|
|
288
|
+
*/
|
|
289
|
+
declare function tileflowCaptureShotFrames(shot: TileflowCaptureShot | Omit<TileflowCaptureShot, 'map'>): TileflowCaptureShotFrame[];
|
|
290
|
+
|
|
291
|
+
export { tileflowCaptureSceneSchemaVersion as A, tileflowCaptureShotBlendSchema as B, tileflowCaptureShotFrameCount as C, tileflowCaptureShotFrames as D, tileflowCaptureShotKeyframeSchema as E, tileflowCaptureShotLimits as F, tileflowCaptureShotNameSchema as G, tileflowCaptureShotSchema as H, tileflowCaptureShotSchemaVersion as I, tileflowCaptureTargetSchema as J, tileflowCaptureViewportSchema as K, tileflowCaptureSceneFitIssue as L, type NormalizedTileflowCaptureScene as N, type TileflowCaptureScene as T, type TileflowCaptureShot as a, type NormalizedTileflowCaptureShot as b, type NormalizedTileflowCaptureShotCamera as c, type TileflowCaptureApplicationTarget as d, type TileflowCaptureBoundsCamera as e, type TileflowCaptureCamera as f, type TileflowCaptureCenterCamera as g, type TileflowCaptureMapTarget as h, type TileflowCaptureShotBlend as i, type TileflowCaptureShotEasing as j, type TileflowCaptureShotFrame as k, type TileflowCaptureShotKeyframe as l, type TileflowCaptureTarget as m, type TileflowCaptureViewport as n, normalizeTileflowCaptureId as o, normalizeTileflowCaptureScene as p, normalizeTileflowCaptureShot as q, tileflowCaptureBoundsCameraSchema as r, tileflowCaptureCameraSchema as s, tileflowCaptureApplicationTargetSchema as t, tileflowCaptureCenterCameraSchema as u, tileflowCaptureIdSchema as v, tileflowCaptureMapTargetSchema as w, tileflowCaptureSceneLimits as x, tileflowCaptureSceneNameSchema as y, tileflowCaptureSceneSchema as z };
|
package/dist/capture.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { N as NormalizedTileflowCaptureScene,
|
|
1
|
+
export { N as NormalizedTileflowCaptureScene, b as NormalizedTileflowCaptureShot, c as NormalizedTileflowCaptureShotCamera, d as TileflowCaptureApplicationTarget, e as TileflowCaptureBoundsCamera, f as TileflowCaptureCamera, g as TileflowCaptureCenterCamera, h as TileflowCaptureMapTarget, T as TileflowCaptureScene, a as TileflowCaptureShot, i as TileflowCaptureShotBlend, j as TileflowCaptureShotEasing, k as TileflowCaptureShotFrame, l as TileflowCaptureShotKeyframe, m as TileflowCaptureTarget, n as TileflowCaptureViewport, o as normalizeTileflowCaptureId, p as normalizeTileflowCaptureScene, q as normalizeTileflowCaptureShot, t as tileflowCaptureApplicationTargetSchema, r as tileflowCaptureBoundsCameraSchema, s as tileflowCaptureCameraSchema, u as tileflowCaptureCenterCameraSchema, v as tileflowCaptureIdSchema, w as tileflowCaptureMapTargetSchema, L as tileflowCaptureSceneFitIssue, x as tileflowCaptureSceneLimits, y as tileflowCaptureSceneNameSchema, z as tileflowCaptureSceneSchema, A as tileflowCaptureSceneSchemaVersion, B as tileflowCaptureShotBlendSchema, C as tileflowCaptureShotFrameCount, D as tileflowCaptureShotFrames, E as tileflowCaptureShotKeyframeSchema, F as tileflowCaptureShotLimits, G as tileflowCaptureShotNameSchema, H as tileflowCaptureShotSchema, I as tileflowCaptureShotSchemaVersion, J as tileflowCaptureTargetSchema, K as tileflowCaptureViewportSchema } from './capture-shot-ChPQvPyi.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
/** Canonical, filesystem-safe identity shared by authored and emitted Tileflow resources. */
|
package/dist/capture.js
CHANGED
|
@@ -267,9 +267,219 @@ function hasControlCharacter(value) {
|
|
|
267
267
|
}
|
|
268
268
|
return false;
|
|
269
269
|
}
|
|
270
|
+
|
|
271
|
+
// src/capture-shot.ts
|
|
272
|
+
import { z as z4 } from "zod";
|
|
273
|
+
|
|
274
|
+
// src/capture-shot-motion.ts
|
|
275
|
+
function tileflowShotStateAt(shot, at) {
|
|
276
|
+
const { keyframes } = shot;
|
|
277
|
+
const first = keyframes[0];
|
|
278
|
+
const last = keyframes.at(-1);
|
|
279
|
+
if (!first || !last || keyframes.length < 2)
|
|
280
|
+
throw new TypeError("A shot needs at least two keyframes.");
|
|
281
|
+
const time = Math.min(last.at, Math.max(first.at, Number.isFinite(at) ? at : first.at));
|
|
282
|
+
let segment = 0;
|
|
283
|
+
while (segment < keyframes.length - 2 && time > keyframes[segment + 1].at) segment += 1;
|
|
284
|
+
const from = keyframes[segment];
|
|
285
|
+
const to = keyframes[segment + 1];
|
|
286
|
+
const linear = Math.min(1, Math.max(0, (time - from.at) / (to.at - from.at)));
|
|
287
|
+
const t = shot.easing === "linear" ? linear : smoothstep(linear);
|
|
288
|
+
return {
|
|
289
|
+
at: time,
|
|
290
|
+
camera: interpolateCamera(cameraOf(from), cameraOf(to), t),
|
|
291
|
+
...from.blend && to.blend ? { blendPosition: interpolateNumber(from.blend.position, to.blend.position, t) } : {}
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
function cameraOf({ camera }) {
|
|
295
|
+
return {
|
|
296
|
+
type: "center",
|
|
297
|
+
center: [camera.center[0], camera.center[1]],
|
|
298
|
+
zoom: camera.zoom,
|
|
299
|
+
bearing: camera.bearing ?? 0,
|
|
300
|
+
pitch: camera.pitch ?? 0
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
var maximumMercatorLatitude = 85.051129;
|
|
304
|
+
function interpolateCamera(from, to, t) {
|
|
305
|
+
return {
|
|
306
|
+
type: "center",
|
|
307
|
+
center: interpolateCenter(from.center, to.center, t),
|
|
308
|
+
zoom: interpolateNumber(from.zoom, to.zoom, t),
|
|
309
|
+
bearing: interpolateBearing(from.bearing, to.bearing, t),
|
|
310
|
+
pitch: interpolateNumber(from.pitch, to.pitch, t)
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function interpolateNumber(from, to, t) {
|
|
314
|
+
if (t <= 0 || from === to) return from;
|
|
315
|
+
if (t >= 1) return to;
|
|
316
|
+
return from + (to - from) * t;
|
|
317
|
+
}
|
|
318
|
+
function interpolateCenter(from, to, t) {
|
|
319
|
+
if (t <= 0 || from[0] === to[0] && from[1] === to[1]) return [from[0], from[1]];
|
|
320
|
+
if (t >= 1) return [to[0], to[1]];
|
|
321
|
+
const start = mercatorFromLngLat(from);
|
|
322
|
+
const end = mercatorFromLngLat(to);
|
|
323
|
+
let dx = end[0] - start[0];
|
|
324
|
+
if (dx > 0.5) dx -= 1;
|
|
325
|
+
else if (dx < -0.5) dx += 1;
|
|
326
|
+
return lngLatFromMercator([start[0] + dx * t, start[1] + (end[1] - start[1]) * t]);
|
|
327
|
+
}
|
|
328
|
+
function interpolateBearing(from, to, t) {
|
|
329
|
+
if (t <= 0 || from === to) return from;
|
|
330
|
+
if (t >= 1) return to;
|
|
331
|
+
const delta = ((to - from) % 360 + 540) % 360 - 180;
|
|
332
|
+
return wrapDegrees(from + delta * t);
|
|
333
|
+
}
|
|
334
|
+
function mercatorFromLngLat([longitude, latitude]) {
|
|
335
|
+
const clamped = Math.max(-maximumMercatorLatitude, Math.min(maximumMercatorLatitude, latitude));
|
|
336
|
+
return [
|
|
337
|
+
(180 + longitude) / 360,
|
|
338
|
+
(180 - 180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + clamped * Math.PI / 360))) / 360
|
|
339
|
+
];
|
|
340
|
+
}
|
|
341
|
+
function lngLatFromMercator([x, y]) {
|
|
342
|
+
const latitude = 360 / Math.PI * Math.atan(Math.exp((180 - y * 360) * Math.PI / 180)) - 90;
|
|
343
|
+
return [wrapDegrees(x * 360 - 180), latitude];
|
|
344
|
+
}
|
|
345
|
+
function wrapDegrees(value) {
|
|
346
|
+
if (value >= -180 && value <= 180) return value;
|
|
347
|
+
return ((value + 180) % 360 + 360) % 360 - 180;
|
|
348
|
+
}
|
|
349
|
+
function smoothstep(t) {
|
|
350
|
+
return t * t * (3 - 2 * t);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// src/capture-shot.ts
|
|
354
|
+
var tileflowCaptureShotSchemaVersion = 1;
|
|
355
|
+
var tileflowCaptureShotLimits = Object.freeze({
|
|
356
|
+
blendThemes: Object.freeze({ maximum: 8, minimum: 2 }),
|
|
357
|
+
defaultFps: 30,
|
|
358
|
+
durationMs: Object.freeze({ maximum: 6e4 }),
|
|
359
|
+
fps: Object.freeze([24, 25, 30, 50, 60]),
|
|
360
|
+
keyframes: Object.freeze({ maximum: 64, minimum: 2 }),
|
|
361
|
+
maximumFrames: 3600
|
|
362
|
+
});
|
|
363
|
+
var tileflowCaptureShotNameSchema = tileflowCaptureSceneNameSchema;
|
|
364
|
+
var tileflowCaptureShotBlendSchema = z4.object({
|
|
365
|
+
themes: z4.array(tileflowThemeNameSchema).min(tileflowCaptureShotLimits.blendThemes.minimum).max(tileflowCaptureShotLimits.blendThemes.maximum),
|
|
366
|
+
position: z4.number().finite().min(0)
|
|
367
|
+
}).strict().superRefine((blend, context) => {
|
|
368
|
+
if (new Set(blend.themes).size !== blend.themes.length) {
|
|
369
|
+
context.addIssue({ code: "custom", message: "Expected distinct themes", path: ["themes"] });
|
|
370
|
+
}
|
|
371
|
+
if (blend.position > blend.themes.length - 1) {
|
|
372
|
+
context.addIssue({
|
|
373
|
+
code: "custom",
|
|
374
|
+
message: `Expected a position from 0 to ${blend.themes.length - 1}`,
|
|
375
|
+
path: ["position"]
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
var tileflowCaptureShotKeyframeSchema = z4.object({
|
|
380
|
+
at: z4.number().int().min(0).max(tileflowCaptureShotLimits.durationMs.maximum),
|
|
381
|
+
camera: tileflowCaptureCenterCameraSchema,
|
|
382
|
+
blend: tileflowCaptureShotBlendSchema.optional()
|
|
383
|
+
}).strict();
|
|
384
|
+
var tileflowCaptureShotFields = {
|
|
385
|
+
theme: tileflowThemeNameSchema,
|
|
386
|
+
viewport: tileflowCaptureViewportSchema,
|
|
387
|
+
fps: z4.literal(tileflowCaptureShotLimits.fps).optional(),
|
|
388
|
+
keyframes: z4.array(tileflowCaptureShotKeyframeSchema).min(tileflowCaptureShotLimits.keyframes.minimum).max(tileflowCaptureShotLimits.keyframes.maximum),
|
|
389
|
+
easing: z4.enum(["smooth", "linear"]).optional()
|
|
390
|
+
};
|
|
391
|
+
var tileflowCaptureShotSchema = z4.object({ map: tileflowPortableIdSchema, ...tileflowCaptureShotFields }).strict().superRefine(checkShotTiming);
|
|
392
|
+
var tileflowMapShotSchema = z4.object(tileflowCaptureShotFields).strict().superRefine(checkShotTiming);
|
|
393
|
+
function normalizeTileflowCaptureShot(input) {
|
|
394
|
+
const shot = tileflowCaptureShotSchema.parse(input);
|
|
395
|
+
return { map: shot.map, ...normalizeShotFields(shot) };
|
|
396
|
+
}
|
|
397
|
+
function tileflowCaptureShotFrameCount(shot) {
|
|
398
|
+
const fps = shot.fps ?? tileflowCaptureShotLimits.defaultFps;
|
|
399
|
+
const duration = shot.keyframes.at(-1)?.at ?? 0;
|
|
400
|
+
return Math.floor(duration * fps / 1e3 + 1e-9) + 1;
|
|
401
|
+
}
|
|
402
|
+
function tileflowCaptureShotFrames(shot) {
|
|
403
|
+
const { map: _map, ...fields } = shot;
|
|
404
|
+
const normalized = normalizeShotFields(tileflowMapShotSchema.parse(fields));
|
|
405
|
+
const count = tileflowCaptureShotFrameCount(normalized);
|
|
406
|
+
const duration = normalized.keyframes.at(-1).at;
|
|
407
|
+
const frames = [];
|
|
408
|
+
for (let index = 0; index < count; index += 1) {
|
|
409
|
+
const at = Math.min(duration, index * 1e3 / normalized.fps);
|
|
410
|
+
frames.push({ index, ...tileflowShotStateAt(normalized, at) });
|
|
411
|
+
}
|
|
412
|
+
return frames;
|
|
413
|
+
}
|
|
414
|
+
function normalizeShotFields(shot) {
|
|
415
|
+
return {
|
|
416
|
+
theme: shot.theme,
|
|
417
|
+
viewport: { ...shot.viewport, dpr: shot.viewport.dpr ?? 1 },
|
|
418
|
+
fps: shot.fps ?? tileflowCaptureShotLimits.defaultFps,
|
|
419
|
+
easing: shot.easing ?? "smooth",
|
|
420
|
+
keyframes: shot.keyframes.map((keyframe) => ({
|
|
421
|
+
at: keyframe.at,
|
|
422
|
+
camera: {
|
|
423
|
+
type: "center",
|
|
424
|
+
center: keyframe.camera.center,
|
|
425
|
+
zoom: keyframe.camera.zoom,
|
|
426
|
+
bearing: keyframe.camera.bearing ?? 0,
|
|
427
|
+
pitch: keyframe.camera.pitch ?? 0
|
|
428
|
+
},
|
|
429
|
+
...keyframe.blend ? { blend: { themes: [...keyframe.blend.themes], position: keyframe.blend.position } } : {}
|
|
430
|
+
}))
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
function checkShotTiming(shot, context) {
|
|
434
|
+
const { keyframes } = shot;
|
|
435
|
+
if (keyframes[0] && keyframes[0].at !== 0) {
|
|
436
|
+
context.addIssue({
|
|
437
|
+
code: "custom",
|
|
438
|
+
message: "Expected the first keyframe at 0 milliseconds",
|
|
439
|
+
path: ["keyframes", 0, "at"]
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
for (let index = 1; index < keyframes.length; index += 1) {
|
|
443
|
+
if (keyframes[index].at <= keyframes[index - 1].at) {
|
|
444
|
+
context.addIssue({
|
|
445
|
+
code: "custom",
|
|
446
|
+
message: "Expected a time after the previous keyframe",
|
|
447
|
+
path: ["keyframes", index, "at"]
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
const blended = keyframes.filter((keyframe) => keyframe.blend !== void 0);
|
|
452
|
+
if (blended.length > 0) {
|
|
453
|
+
const themes = JSON.stringify(blended[0].blend.themes);
|
|
454
|
+
keyframes.forEach((keyframe, index) => {
|
|
455
|
+
if (!keyframe.blend) {
|
|
456
|
+
context.addIssue({
|
|
457
|
+
code: "custom",
|
|
458
|
+
message: "Expected a blend on every keyframe when one keyframe blends themes",
|
|
459
|
+
path: ["keyframes", index, "blend"]
|
|
460
|
+
});
|
|
461
|
+
} else if (JSON.stringify(keyframe.blend.themes) !== themes) {
|
|
462
|
+
context.addIssue({
|
|
463
|
+
code: "custom",
|
|
464
|
+
message: "Expected the same themes, in the same order, on every keyframe",
|
|
465
|
+
path: ["keyframes", index, "blend", "themes"]
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
const frames = tileflowCaptureShotFrameCount(shot);
|
|
471
|
+
if (frames > tileflowCaptureShotLimits.maximumFrames) {
|
|
472
|
+
context.addIssue({
|
|
473
|
+
code: "custom",
|
|
474
|
+
message: `Expected at most ${tileflowCaptureShotLimits.maximumFrames} frames; this shot renders ${frames}`,
|
|
475
|
+
path: ["keyframes", keyframes.length - 1, "at"]
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
270
479
|
export {
|
|
271
480
|
normalizeTileflowCaptureId,
|
|
272
481
|
normalizeTileflowCaptureScene,
|
|
482
|
+
normalizeTileflowCaptureShot,
|
|
273
483
|
tileflowCaptureApplicationTargetSchema,
|
|
274
484
|
tileflowCaptureBoundsCameraSchema,
|
|
275
485
|
tileflowCaptureCameraSchema,
|
|
@@ -281,6 +491,14 @@ export {
|
|
|
281
491
|
tileflowCaptureSceneNameSchema,
|
|
282
492
|
tileflowCaptureSceneSchema,
|
|
283
493
|
tileflowCaptureSceneSchemaVersion,
|
|
494
|
+
tileflowCaptureShotBlendSchema,
|
|
495
|
+
tileflowCaptureShotFrameCount,
|
|
496
|
+
tileflowCaptureShotFrames,
|
|
497
|
+
tileflowCaptureShotKeyframeSchema,
|
|
498
|
+
tileflowCaptureShotLimits,
|
|
499
|
+
tileflowCaptureShotNameSchema,
|
|
500
|
+
tileflowCaptureShotSchema,
|
|
501
|
+
tileflowCaptureShotSchemaVersion,
|
|
284
502
|
tileflowCaptureTargetSchema,
|
|
285
503
|
tileflowCaptureViewportSchema,
|
|
286
504
|
tileflowPortableIdSchema,
|