@expofp/renderer 3.37.1 → 3.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +34 -0
  2. package/dist/controls/camera-api.d.ts +28 -0
  3. package/dist/controls/camera-api.js +33 -10
  4. package/dist/controls/hooks.js +2 -0
  5. package/dist/core/InstanceUniforms.d.ts +15 -0
  6. package/dist/core/InstanceUniforms.js +32 -0
  7. package/dist/core/batch/BatchedMesh.js +6 -0
  8. package/dist/core/instanced/instanced-material.js +5 -1
  9. package/dist/core/lines/BatchedLines.d.ts +9 -7
  10. package/dist/core/lines/BatchedLines.js +9 -7
  11. package/dist/core/lines/{FrustumCulling.d.ts → FrustumCullingLines.d.ts} +7 -6
  12. package/dist/core/lines/{FrustumCulling.js → FrustumCullingLines.js} +2 -2
  13. package/dist/core/lines/{Raycasting.d.ts → RaycastingLines.d.ts} +7 -6
  14. package/dist/core/lines/{Raycasting.js → RaycastingLines.js} +2 -2
  15. package/dist/core/lines/lines-material.js +10 -1
  16. package/dist/core/sprites/BatchedSprites.d.ts +115 -0
  17. package/dist/core/sprites/BatchedSprites.js +205 -0
  18. package/dist/core/sprites/RaycastingSprites.d.ts +41 -0
  19. package/dist/core/sprites/RaycastingSprites.js +71 -0
  20. package/dist/core/sprites/sprite-material.d.ts +59 -0
  21. package/dist/core/sprites/sprite-material.js +192 -0
  22. package/dist/core/text/BatchedText.d.ts +6 -0
  23. package/dist/core/text/BatchedText.js +6 -0
  24. package/dist/core/text/MemberTexture.js +55 -1
  25. package/dist/core/text/Text.d.ts +16 -1
  26. package/dist/core/text/Text.js +15 -0
  27. package/dist/core/text/batched-text-material.js +4 -2
  28. package/dist/objects/containers/hooks.d.ts +7 -2
  29. package/dist/objects/containers/hooks.js +20 -5
  30. package/dist/objects/containers/mesh-writes.js +3 -3
  31. package/dist/objects/images/ImageInstance.js +111 -43
  32. package/dist/objects/images/Images.d.ts +19 -7
  33. package/dist/objects/images/Images.js +266 -83
  34. package/dist/objects/images/atlas-packer.d.ts +92 -91
  35. package/dist/objects/images/atlas-packer.js +230 -258
  36. package/dist/objects/images/image-container.d.ts +14 -3
  37. package/dist/objects/images/image-container.js +19 -5
  38. package/dist/objects/images/pack-sources.d.ts +190 -0
  39. package/dist/objects/images/pack-sources.js +272 -0
  40. package/dist/objects/images/texture-budget.js +2 -2
  41. package/dist/objects/images/worker/atlas-worker.d.ts +56 -0
  42. package/dist/objects/images/worker/atlas-worker.js +123 -0
  43. package/dist/objects/images/worker/client.d.ts +62 -0
  44. package/dist/objects/images/worker/client.js +249 -0
  45. package/dist/objects/images/worker/index.d.ts +10 -0
  46. package/dist/objects/images/worker/index.js +1 -0
  47. package/dist/objects/layer/Layer.d.ts +7 -6
  48. package/dist/objects/layer/Layer.js +40 -30
  49. package/dist/objects/layer/layer-context.d.ts +41 -0
  50. package/dist/objects/layer/layer-context.js +45 -0
  51. package/dist/objects/materials/ColorMaterial.js +16 -3
  52. package/dist/objects/materials/LineMaterial.js +4 -2
  53. package/dist/objects/materials/TextureMaterial.js +14 -2
  54. package/dist/objects/materials/effects/color-dim.d.ts +1 -10
  55. package/dist/objects/materials/effects/color-dim.js +21 -18
  56. package/dist/objects/materials/effects/effects-context.d.ts +6 -5
  57. package/dist/objects/materials/shared.d.ts +18 -0
  58. package/dist/objects/materials/shared.js +21 -0
  59. package/dist/objects/models/Models.js +1 -8
  60. package/dist/objects/shapes/Shapes.js +2 -9
  61. package/dist/objects/text/TextInstance.js +1 -1
  62. package/dist/objects/text/text-layout.d.ts +13 -4
  63. package/dist/objects/text/text-layout.js +30 -4
  64. package/dist/space/Space.d.ts +15 -0
  65. package/dist/space/Space.js +16 -10
  66. package/dist/types/defs.d.ts +53 -2
  67. package/dist/utils/logging.d.ts +6 -3
  68. package/dist/utils/logging.js +15 -7
  69. package/dist/utils/math.d.ts +11 -0
  70. package/dist/utils/math.js +14 -0
  71. package/package.json +2 -2
@@ -1,128 +1,129 @@
1
1
  import { type ImageDef, type ImageSource } from '../../types/defs';
2
- /** A canvas an atlas is drawn onto. `OffscreenCanvas` included so packing can move to a worker. */
3
- export type AtlasCanvas = HTMLCanvasElement | OffscreenCanvas;
2
+ import { type AtlasCanvas, type CreateAtlasCanvas, type SourceRect, type UvRect } from './pack-sources';
3
+ export { type AtlasCanvas, type CreateAtlasCanvas, isResizableSource, type SourceRect, type UvRect, } from './pack-sources';
4
4
  /**
5
- * Creates the backing canvas for one atlas, sized to that atlas exactly.
6
- * @param width - The atlas width in pixels.
7
- * @param height - The atlas height in pixels.
8
- * @returns The canvas to draw on.
9
- */
10
- export type CreateAtlasCanvas = (width: number, height: number) => AtlasCanvas;
11
- /**
12
- * A region of a source image, in **source pixels with a top-left origin** — the same axes as
13
- * `ImageDef.bounds`, and literally the `sx, sy, sw, sh` the packer hands to `drawImage`. Kept in
14
- * pixels rather than normalized so it cannot be mistaken for a {@link UvRect}, whose origin is the
15
- * other corner.
16
- */
17
- export interface SourceRect {
18
- /** Distance from the source's left edge, in pixels. */
19
- x: number;
20
- /** Distance from the source's top edge, in pixels. */
21
- y: number;
22
- /** Region width in pixels. */
23
- width: number;
24
- /** Region height in pixels. */
25
- height: number;
26
- }
27
- /**
28
- * A region of an atlas, **normalized in the canvas's own axes: a top-left origin, v running down**.
5
+ * The pixels an atlas can hold: a canvas, or a bitmap transferred out of one.
29
6
  *
30
- * Consumed by a texture uploaded with `flipY = false`, which maps canvas row 0 to `v = 0`, so these
31
- * numbers feed a uv transform directly with no vertical inversion. That is deliberate: the scene's
32
- * y axis already points down (SVG coordinates, and the camera is placed to match), so a uv space
33
- * that also runs down keeps every axis in the pipeline pointing the same way — invert at one end
34
- * only and images come out upside down.
7
+ * `AtlasCanvas` stays narrow on purpose. `CreateAtlasCanvas` and `contextOf` both need a type they
8
+ * can open a 2D context on, and an `ImageBitmap` has no context to open.
35
9
  */
36
- export interface UvRect {
37
- /** Left edge, `0` at the atlas's left. */
38
- u0: number;
39
- /** Top edge, `0` at the atlas's top. */
40
- v0: number;
41
- /** Right edge. */
42
- u1: number;
43
- /** Bottom edge. */
44
- v1: number;
45
- }
46
- /** One image — or one tile of a split image — placed in an atlas. */
10
+ export type AtlasImage = AtlasCanvas | ImageBitmap;
11
+ /** One image, or one tile of a split image, placed in an atlas. */
47
12
  export interface PackedImage {
48
13
  /**
49
- * The def these pixels belong to. Defs whose sources dedupe appear as separate entries sharing
50
- * one region, so the list maps one-to-one onto the instances an atlas has to draw.
14
+ * The def that these pixels belong to. Defs whose sources dedupe appear as separate entries
15
+ * that share one region, so the list maps one-to-one onto the instances that an atlas must
16
+ * draw.
51
17
  */
52
18
  def: ImageDef;
53
19
  /** Where the pixels sit in the atlas. */
54
20
  uv: UvRect;
55
21
  /**
56
- * Which part of `def.source` this entry holds. Undefined when the source was small enough to
57
- * pack whole, which is the common case; set only on the tiles of a split source, where a
58
- * consumer needs it to work out the fraction of `def.bounds` this tile covers.
22
+ * Which part of `def.source` this entry holds. This is undefined when the source packs whole,
23
+ * which is the common case. It is set only on the tiles of a split source, where a consumer
24
+ * needs it to work out the fraction of `def.bounds` that this tile covers.
59
25
  */
60
26
  source?: SourceRect;
27
+ /**
28
+ * The intrinsic pixel size of `def.source`. The packer measures this once and carries it on the
29
+ * placement, because a `Blob` source cannot be measured again later. A tile's consumer reads
30
+ * this field to find the fraction of the image the tile covers. The field spares that consumer
31
+ * from decoding the source a second time.
32
+ */
33
+ size: {
34
+ width: number;
35
+ height: number;
36
+ };
61
37
  }
62
- /** One packed atlas: a canvas of pixels, and what landed where on it. */
38
+ /** One packed atlas: its pixels, and a record of what landed where on it. */
63
39
  export interface Atlas {
64
- /** The canvas holding the packed pixels. Its `width`/`height` are the atlas's size. */
65
- canvas: AtlasCanvas;
40
+ /**
41
+ * The atlas's packed pixels: a canvas, or a bitmap a worker transferred out of one. Its
42
+ * `width`/`height` are the atlas's size.
43
+ */
44
+ image: AtlasImage;
66
45
  /** Every def placement on this atlas. */
67
46
  images: PackedImage[];
68
47
  /**
69
- * Whether this atlas's pixels may be downscaled to fit a memory budget. Image and bitmap sources
70
- * pack into resizable atlases; canvas sources into fixed ones. An atlas never mixes the two (they
71
- * are packed as separate groups), so this one flag speaks for every placement on it — which is
72
- * what lets a memory budget scale the whole canvas at once without dragging a canvas source down
73
- * with the images. See {@link isResizableSource}.
48
+ * Whether this atlas's pixels can shrink to fit a memory budget. Image and bitmap sources pack
49
+ * into resizable atlases. Canvas sources pack into fixed ones. An atlas never mixes the two
50
+ * kinds, because the code packs them as separate groups. So this one flag applies to every
51
+ * placement on the atlas. It lets a memory budget scale a whole resizable canvas at once,
52
+ * without changing a canvas source's pixels. See {@link isResizableSource}.
74
53
  */
75
54
  resizable: boolean;
76
55
  }
77
56
  /** Options for {@link packAtlases}. */
78
57
  export interface AtlasPackerOptions {
79
- /** Creates each atlas canvas. Defaults to a DOM canvas. */
58
+ /** Creates each atlas canvas. Defaults to {@link createAtlasCanvas}. */
80
59
  createCanvas?: CreateAtlasCanvas;
60
+ /**
61
+ * Abandons the pack. A repack that supersedes a pack still in flight aborts that pack. The
62
+ * worker is told to drop it and goes on running, and a result that still arrives is thrown away
63
+ * instead of mounted.
64
+ */
65
+ signal?: AbortSignal;
81
66
  }
82
67
  /**
83
- * Whether a source's pixels may be downscaled to fit a memory budget. `true` for decoded images and
84
- * bitmaps, `false` for canvases — a canvas's pixels are the caller's, counted at full size but never
85
- * compressed (see the scene's `memoryLimit`).
68
+ * Where a pack draws its atlases.
86
69
  *
87
- * Detected by the absence of `getContext`: `HTMLCanvasElement` and `OffscreenCanvas` both have it,
88
- * `HTMLImageElement` and `ImageBitmap` do not. A property test rather than `instanceof`, because the
89
- * SDK runs in WebViews where `OffscreenCanvas`/`ImageBitmap` may be missing as globals and an
90
- * `instanceof` against an absent one throws.
91
- * @param source - The source to classify.
92
- * @returns Whether the source can be downscaled.
70
+ * There are two tiers and not three. Both tiers decode with `createImageBitmap`, because every
71
+ * build target has it (the plan's Global Constraints hold the compat data). What changes between
72
+ * the tiers is whether the drawing can leave the main thread. That turns on `OffscreenCanvas`,
73
+ * which Chrome 66 and Safari 15 do not have. The inline tier is a normal path for those targets
74
+ * and not an edge case. It is already around five times cheaper than the code it replaces, because
75
+ * it no longer decodes an `<img>`.
93
76
  */
94
- export declare function isResizableSource(source: ImageSource): boolean;
77
+ export type PackTier =
78
+ /** `Worker` and `OffscreenCanvas` are present, and every source is a `Blob`: pack off-thread. */
79
+ 'worker'
80
+ /** Anything else: decode and pack on the main thread. */
81
+ | 'inline';
95
82
  /**
96
- * Packs image defs into atlas canvases and reports where every def's pixels landed.
83
+ * Packs image defs into atlas canvases and reports where each def's pixels landed.
97
84
  *
98
- * Sources are split by kind first — resizable (image/bitmap) from fixed (canvas) — and each kind is
99
- * packed on its own, so no atlas ever mixes the two and a memory budget can scale a resizable atlas
100
- * whole without touching a canvas's pixels. Within a kind, sources are deduped — two defs pointing
101
- * at the same URL, or holding the same canvas object, are drawn once and share one region — and then
102
- * offered to the packer whole. Anything too big for an atlas comes back parked in a natural-size bin
103
- * of its own, which the packer flags; those are the only sources cut into tiles, and the tiles go
104
- * back through the same packer. Letting the packer decide is what keeps the guarantee that no atlas
105
- * exceeds `maxDimension` without measuring every image up front.
85
+ * The code first dedupes the defs. Two defs that point at the same URL, or that hold the same
86
+ * object, draw once and share one region. The code then decodes every source that is not drawable
87
+ * yet, which is what makes this function asynchronous: a `Blob` holds bytes and not pixels. The
88
+ * code then hands the decoded sources to {@link packSources}, which does the pixel work. The
89
+ * placements come back addressed by source index, and this function expands them into one entry
90
+ * per def.
106
91
  *
107
- * Packing reads only the sources' pixel dimensions, never `bounds`, so a def that later moves or
108
- * resizes keeps its region: the quad's matrix scales it, and nothing needs repacking. Membership
109
- * changes do, though — this is a batch call with no incremental path.
92
+ * Packing reads only the sources' pixel dimensions, never `bounds`. So a def that later moves or
93
+ * resizes keeps its region: the quad's matrix scales it, and nothing needs repacking. A change in
94
+ * membership is different. This is a batch call with no incremental path, so an added or removed
95
+ * def needs a fresh call.
96
+ *
97
+ * A worker that fails for any reason other than an abort falls back to the inline tier once. The
98
+ * worker is an optimization, and no host page may cost a layer its images by refusing one.
110
99
  * @param defs - The images to pack.
111
- * @param maxDimension - Largest atlas edge in pixels, floored to a positive integer.
112
- * @param options - Overrides for how atlas canvases are made.
113
- * @returns One entry per atlas, in packing order — resizable atlases first, then fixed.
100
+ * @param maxDimension - The largest atlas edge, in pixels. The function floors this to a positive
101
+ * integer.
102
+ * @param options - Overrides for how atlas canvases are made, and the signal that abandons the
103
+ * pack.
104
+ * @returns One entry for each atlas, in packing order: resizable atlases first, then fixed ones.
114
105
  */
115
- export declare function packAtlases(defs: readonly ImageDef[], maxDimension: number, options?: AtlasPackerOptions): Atlas[];
106
+ export declare function packAtlases(defs: readonly ImageDef[], maxDimension: number, options?: AtlasPackerOptions): Promise<Atlas[]>;
116
107
  /**
117
- * The pixel size of an image source.
108
+ * Picks the higher tier when this environment and this set of sources both allow it.
109
+ *
110
+ * A layer packs in the worker only when **every** source is a `Blob`. One source of any other kind
111
+ * keeps the whole layer on the main thread.
112
+ *
113
+ * The test names what may cross, never what must stay. A test that only excludes the known-bad
114
+ * kinds admits every kind nobody thought of, and this code shipped that mistake once: it asked
115
+ * whether a source was not a DOM canvas, which let an `<img>` through. An `<img>` neither clones
116
+ * nor moves, so `postMessage` threw on it and the layer drew nothing.
118
117
  *
119
- * Duck-typed rather than `instanceof`: the SDK runs in WebViews where `OffscreenCanvas` and
120
- * `ImageBitmap` may be missing as globals, and an `instanceof` against an absent global throws.
121
- * @param source - The source to measure.
122
- * @returns Its intrinsic size, `0 × 0` for an image element that has not decoded yet.
118
+ * A `Blob` is also the only source the worker can take without taking it from the def that owns it.
119
+ * Its handle clones, so the def keeps its bytes. Every other kind would have to move, and a moved
120
+ * source is dead on the main thread, so the next repack would find nothing to draw. Those sources
121
+ * lose nothing by packing inline. A canvas cannot cross at all — `transferControlToOffscreen` throws
122
+ * on a canvas that already holds a 2D context, and every floorplan canvas source holds one — and
123
+ * `createImageBitmap(canvas)` costs more than a pack of that canvas on the main thread (this is
124
+ * measured, see the design spec).
125
+ * @param sources - The unique sources that this pack will draw.
126
+ * @returns The tier to run.
123
127
  */
124
- export declare function imageSourceSize(source: ImageSource): {
125
- width: number;
126
- height: number;
127
- };
128
+ export declare function selectTier(sources: readonly ImageSource[]): PackTier;
128
129
  //# sourceMappingURL=atlas-packer.d.ts.map