@expofp/renderer 3.35.0 → 3.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/core/SquareDataTexture.d.ts +2 -2
  2. package/dist/core/SquareDataTexture.js +2 -2
  3. package/dist/core/batch/BatchedMesh.d.ts +3 -3
  4. package/dist/core/batch/BatchedMesh.js +3 -3
  5. package/dist/core/instanced/InstancedMesh.d.ts +7 -7
  6. package/dist/core/instanced/InstancedMesh.js +4 -4
  7. package/dist/core/instanced/instanced-material.js +1 -1
  8. package/dist/core/lines/BatchedLines.d.ts +4 -4
  9. package/dist/core/lines/BatchedLines.js +4 -4
  10. package/dist/core/text/BatchedText.d.ts +14 -14
  11. package/dist/core/text/BatchedText.js +9 -9
  12. package/dist/core/text/MemberTexture.d.ts +2 -2
  13. package/dist/core/text/Text.d.ts +5 -5
  14. package/dist/core/text/Text.js +4 -4
  15. package/dist/core/text/glyph-packing.d.ts +2 -2
  16. package/dist/events/layout-targets.d.ts +7 -3
  17. package/dist/events/layout-targets.js +13 -1
  18. package/dist/objects/containers/SlotContainer.d.ts +27 -2
  19. package/dist/objects/containers/SlotContainer.js +29 -0
  20. package/dist/objects/containers/mesh-writes.d.ts +1 -1
  21. package/dist/objects/images/Images.js +1 -1
  22. package/dist/objects/images/image-container.d.ts +5 -5
  23. package/dist/objects/images/image-container.js +1 -1
  24. package/dist/objects/lines/line-container.d.ts +4 -4
  25. package/dist/objects/materials/LineMaterial.d.ts +1 -1
  26. package/dist/objects/materials/effects/color-dim.d.ts +1 -1
  27. package/dist/objects/materials/effects/color-dim.js +1 -1
  28. package/dist/objects/models/Models.js +2 -2
  29. package/dist/objects/models/model-container.d.ts +4 -20
  30. package/dist/objects/models/model-container.js +1 -21
  31. package/dist/objects/shapes/shape-container.d.ts +3 -20
  32. package/dist/objects/shapes/shape-container.js +0 -21
  33. package/dist/objects/text/text-container.d.ts +6 -6
  34. package/dist/objects/text/text-container.js +3 -3
  35. package/dist/objects/text/text-layout.d.ts +2 -2
  36. package/package.json +2 -2
@@ -91,8 +91,8 @@ export declare function getSquareTextureInfo(arrayType: TypedArrayConstructor, c
91
91
  * 2. **The index varying is always `float`**, so `getUniformsGLSL` no longer takes an index type.
92
92
  * It follows from the first: GLSL ES 3.00 requires integer varyings to be `flat`, so an index
93
93
  * that is not float could not have the qualifier removed. **Callers must therefore hand it a float
94
- * index** — `BatchedMeshExt` does, from three's own `getIndirectIndex( gl_DrawID )`, and
95
- * `InstancedMeshExt` does, from the float index texture that replaced upstream's `uint` attribute.
94
+ * index** — `BatchedMeshImpl` does, from three's own `getIndirectIndex( gl_DrawID )`, and
95
+ * `InstancedMeshImpl` does, from the float index texture that replaced upstream's `uint` attribute.
96
96
  * 3. **`clone` and `copy` produce an independent texture.** See each method.
97
97
  */
98
98
  export declare class SquareDataTexture extends DataTexture {
@@ -68,8 +68,8 @@ export function getSquareTextureInfo(arrayType, channels, pixelsPerInstance, cap
68
68
  * 2. **The index varying is always `float`**, so `getUniformsGLSL` no longer takes an index type.
69
69
  * It follows from the first: GLSL ES 3.00 requires integer varyings to be `flat`, so an index
70
70
  * that is not float could not have the qualifier removed. **Callers must therefore hand it a float
71
- * index** — `BatchedMeshExt` does, from three's own `getIndirectIndex( gl_DrawID )`, and
72
- * `InstancedMeshExt` does, from the float index texture that replaced upstream's `uint` attribute.
71
+ * index** — `BatchedMeshImpl` does, from three's own `getIndirectIndex( gl_DrawID )`, and
72
+ * `InstancedMeshImpl` does, from the float index texture that replaced upstream's `uint` attribute.
73
73
  * 3. **`clone` and `copy` produce an independent texture.** See each method.
74
74
  */
75
75
  export class SquareDataTexture extends DataTexture {
@@ -19,8 +19,8 @@ import { type UniformValue, type UniformValueObj } from '../SquareDataTexture';
19
19
  * - **Bounds invalidate themselves.** Every mutation that can move the mesh's extents nulls the
20
20
  * cached bounds, so callers cannot forget; three's frustum test recomputes a null one on demand.
21
21
  */
22
- export declare class BatchedMeshExt extends BatchedMeshBase {
23
- /** Per-instance uniform store, shared with {@link InstancedMeshExt}. */
22
+ export declare class BatchedMeshImpl extends BatchedMeshBase {
23
+ /** Per-instance uniform store, shared with {@link InstancedMeshImpl}. */
24
24
  private readonly uniforms;
25
25
  /** The material whose `onBeforeCompile` is already wrapped, so it is wrapped exactly once. */
26
26
  private patchedMaterial;
@@ -70,5 +70,5 @@ export declare class BatchedMeshExt extends BatchedMeshBase {
70
70
  * Registers the class as an R3F element, by value so the generated key cannot collide with the
71
71
  * `BatchedMesh` three already puts in the catalog when the canvas mounts.
72
72
  */
73
- export declare const BatchedMesh: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<BatchedMeshExt, import("@react-three/fiber").MathProps<BatchedMeshExt> & import("@react-three/fiber").ReactProps<BatchedMeshExt> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<BatchedMeshExt, typeof BatchedMeshExt>, "object">>>>;
73
+ export declare const BatchedMesh: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<BatchedMeshImpl, import("@react-three/fiber").MathProps<BatchedMeshImpl> & import("@react-three/fiber").ReactProps<BatchedMeshImpl> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<BatchedMeshImpl, typeof BatchedMeshImpl>, "object">>>>;
74
74
  //# sourceMappingURL=BatchedMesh.d.ts.map
@@ -20,8 +20,8 @@ import { openMain } from '../shader-source';
20
20
  * - **Bounds invalidate themselves.** Every mutation that can move the mesh's extents nulls the
21
21
  * cached bounds, so callers cannot forget; three's frustum test recomputes a null one on demand.
22
22
  */
23
- export class BatchedMeshExt extends BatchedMeshBase {
24
- /** Per-instance uniform store, shared with {@link InstancedMeshExt}. */
23
+ export class BatchedMeshImpl extends BatchedMeshBase {
24
+ /** Per-instance uniform store, shared with {@link InstancedMeshImpl}. */
25
25
  uniforms = new InstanceUniforms();
26
26
  /** The material whose `onBeforeCompile` is already wrapped, so it is wrapped exactly once. */
27
27
  patchedMaterial = null;
@@ -146,4 +146,4 @@ export class BatchedMeshExt extends BatchedMeshBase {
146
146
  * Registers the class as an R3F element, by value so the generated key cannot collide with the
147
147
  * `BatchedMesh` three already puts in the catalog when the canvas mounts.
148
148
  */
149
- export const BatchedMesh = extend(BatchedMeshExt);
149
+ export const BatchedMesh = extend(BatchedMeshImpl);
@@ -3,8 +3,8 @@ import { type UniformSchemaShader } from '../InstanceUniforms';
3
3
  import { type UniformValue, type UniformValueObj } from '../SquareDataTexture';
4
4
  import { FrustumCulling } from './FrustumCulling';
5
5
  import { Raycasting } from './Raycasting';
6
- /** Constructor options for {@link InstancedMeshExt}. */
7
- export interface InstancedMeshExtParams {
6
+ /** Constructor options for {@link InstancedMeshImpl}. */
7
+ export interface InstancedMeshImplParams {
8
8
  /** Initial instance capacity; the buffers grow past it on demand. */
9
9
  capacity?: number;
10
10
  }
@@ -34,10 +34,10 @@ export type CustomSortFn = (list: InstancedRenderItem[]) => void;
34
34
  * - **Batched-style texture handling.** The data textures bind as ordinary shader uniforms and
35
35
  * flush through {@link SquareDataTexture.update}, so there is no manual texture-unit binding,
36
36
  * `updateTextures`/`bindTextures` split, or `PropertiesOverride` — the vendored texture already
37
- * works this way for `BatchedMeshExt`.
37
+ * works this way for `BatchedMeshImpl`.
38
38
  * - **The draw list is a texture, not a vertex attribute.** Upstream stamps a `uint` index attribute
39
39
  * onto whatever geometry it is handed; this fetches the instance id by `gl_InstanceID` from a texture of
40
- * its own, the way `BatchedMeshExt` resolves `gl_DrawID`. So the mesh never writes to a geometry it
40
+ * its own, the way `BatchedMeshImpl` resolves `gl_DrawID`. So the mesh never writes to a geometry it
41
41
  * does not own — several may draw one cached geometry — and the cull list flushes through
42
42
  * {@link SquareDataTexture.update} in `onBeforeRender` like every other per-instance buffer, rather
43
43
  * than needing an attribute that owns its GL buffer to beat three's upload in `projectObject`. It
@@ -53,7 +53,7 @@ export type CustomSortFn = (list: InstancedRenderItem[]) => void;
53
53
  *
54
54
  * Render it with {@link InstancedMesh}.
55
55
  */
56
- export declare class InstancedMeshExt extends Mesh<BufferGeometry, Material | Material[], Object3DEventMap & {
56
+ export declare class InstancedMeshImpl extends Mesh<BufferGeometry, Material | Material[], Object3DEventMap & {
57
57
  dispose: object;
58
58
  }> {
59
59
  /**
@@ -110,7 +110,7 @@ export declare class InstancedMeshExt extends Mesh<BufferGeometry, Material | Ma
110
110
  private drawList;
111
111
  /** Puts back what {@link patchInstancedMaterial} wrapped; null between draws. */
112
112
  private _unpatchMaterial;
113
- constructor(params?: InstancedMeshExtParams);
113
+ constructor(params?: InstancedMeshImplParams);
114
114
  /**
115
115
  * The instance capacity the textures currently hold.
116
116
  */
@@ -298,5 +298,5 @@ export declare class InstancedMeshExt extends Mesh<BufferGeometry, Material | Ma
298
298
  * Registers the class as an R3F element, by value so the generated key cannot collide with the
299
299
  * `InstancedMesh` three already puts in the catalog when the canvas mounts.
300
300
  */
301
- export declare const InstancedMesh: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<InstancedMeshExt, import("@react-three/fiber").MathProps<InstancedMeshExt> & import("@react-three/fiber").ReactProps<InstancedMeshExt> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<InstancedMeshExt, typeof InstancedMeshExt>, "object">>>>;
301
+ export declare const InstancedMesh: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<InstancedMeshImpl, import("@react-three/fiber").MathProps<InstancedMeshImpl> & import("@react-three/fiber").ReactProps<InstancedMeshImpl> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<InstancedMeshImpl, typeof InstancedMeshImpl>, "object">>>>;
302
302
  //# sourceMappingURL=InstancedMesh.d.ts.map
@@ -26,10 +26,10 @@ patchInstancedShaderChunks();
26
26
  * - **Batched-style texture handling.** The data textures bind as ordinary shader uniforms and
27
27
  * flush through {@link SquareDataTexture.update}, so there is no manual texture-unit binding,
28
28
  * `updateTextures`/`bindTextures` split, or `PropertiesOverride` — the vendored texture already
29
- * works this way for `BatchedMeshExt`.
29
+ * works this way for `BatchedMeshImpl`.
30
30
  * - **The draw list is a texture, not a vertex attribute.** Upstream stamps a `uint` index attribute
31
31
  * onto whatever geometry it is handed; this fetches the instance id by `gl_InstanceID` from a texture of
32
- * its own, the way `BatchedMeshExt` resolves `gl_DrawID`. So the mesh never writes to a geometry it
32
+ * its own, the way `BatchedMeshImpl` resolves `gl_DrawID`. So the mesh never writes to a geometry it
33
33
  * does not own — several may draw one cached geometry — and the cull list flushes through
34
34
  * {@link SquareDataTexture.update} in `onBeforeRender` like every other per-instance buffer, rather
35
35
  * than needing an attribute that owns its GL buffer to beat three's upload in `projectObject`. It
@@ -45,7 +45,7 @@ patchInstancedShaderChunks();
45
45
  *
46
46
  * Render it with {@link InstancedMesh}.
47
47
  */
48
- export class InstancedMeshExt extends Mesh {
48
+ export class InstancedMeshImpl extends Mesh {
49
49
  /**
50
50
  * The number of instances rendered in the last frame.
51
51
  * @default 0
@@ -489,7 +489,7 @@ export class InstancedMeshExt extends Mesh {
489
489
  * Registers the class as an R3F element, by value so the generated key cannot collide with the
490
490
  * `InstancedMesh` three already puts in the catalog when the canvas mounts.
491
491
  */
492
- export const InstancedMesh = extend(InstancedMeshExt);
492
+ export const InstancedMesh = extend(InstancedMeshImpl);
493
493
  const DEFAULT_CAPACITY = 1000;
494
494
  const _matrix = new Matrix4();
495
495
  const _color = new Color();
@@ -55,7 +55,7 @@ const INSTANCED_DECLARATIONS = /* glsl */ `
55
55
  * The matrix is declared here rather than where the transform chunks use it, so it lands in `main`
56
56
  * whether or not the material includes those chunks. It shadows the `attribute mat4 instanceMatrix`
57
57
  * three declares for any `isInstancedMesh` object — which is what the placeholder attribute on
58
- * `InstancedMeshExt` exists to satisfy — and a material doing its own transform simply never reads
58
+ * `InstancedMeshImpl` exists to satisfy — and a material doing its own transform simply never reads
59
59
  * it.
60
60
  */
61
61
  const INSTANCED_RESOLVE = /* glsl */ `
@@ -1,7 +1,7 @@
1
1
  import { type Box3, type BufferGeometry, type Camera, type Group, type Material, type Scene, type Sphere, Vector3, type Vector3Like, type WebGLRenderer } from 'three';
2
2
  import { LineMaterial } from 'three/addons/lines/LineMaterial.js';
3
3
  import { LineSegmentsGeometry } from 'three/addons/lines/LineSegmentsGeometry.js';
4
- import { InstancedMeshExt, type InstancedMeshExtParams } from '../instanced/InstancedMesh';
4
+ import { InstancedMeshImpl, type InstancedMeshImplParams } from '../instanced/InstancedMesh';
5
5
  import { FrustumCulling } from './FrustumCulling';
6
6
  import { Raycasting } from './Raycasting';
7
7
  /**
@@ -31,7 +31,7 @@ import { Raycasting } from './Raycasting';
31
31
  *
32
32
  * Render it with {@link BatchedLines}.
33
33
  */
34
- export declare class BatchedLinesExt extends InstancedMeshExt {
34
+ export declare class BatchedLinesImpl extends InstancedMeshImpl {
35
35
  /**
36
36
  * The segment template every member is drawn from, and the whole of what the geometry carries: the
37
37
  * per-instance data three would put in instanced attributes is in the uniforms instead.
@@ -58,7 +58,7 @@ export declare class BatchedLinesExt extends InstancedMeshExt {
58
58
  /**
59
59
  * @param params - Instance capacity; the buffers grow past it on demand.
60
60
  */
61
- constructor(params?: InstancedMeshExtParams);
61
+ constructor(params?: InstancedMeshImplParams);
62
62
  /**
63
63
  * Reads a member's endpoints.
64
64
  * @param id - The member to read.
@@ -131,5 +131,5 @@ export declare class BatchedLinesExt extends InstancedMeshExt {
131
131
  * Registers the class as an R3F element, by value so the generated key cannot collide with anything
132
132
  * three puts in the catalog when the canvas mounts.
133
133
  */
134
- export declare const BatchedLines: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<BatchedLinesExt, import("@react-three/fiber").MathProps<BatchedLinesExt> & import("@react-three/fiber").ReactProps<BatchedLinesExt> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<BatchedLinesExt, typeof BatchedLinesExt>, "object">>>>;
134
+ export declare const BatchedLines: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<BatchedLinesImpl, import("@react-three/fiber").MathProps<BatchedLinesImpl> & import("@react-three/fiber").ReactProps<BatchedLinesImpl> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<BatchedLinesImpl, typeof BatchedLinesImpl>, "object">>>>;
135
135
  //# sourceMappingURL=BatchedLines.d.ts.map
@@ -2,7 +2,7 @@ import { extend } from '@react-three/fiber';
2
2
  import { Vector3, Vector4, } from 'three';
3
3
  import { LineMaterial } from 'three/addons/lines/LineMaterial.js';
4
4
  import { LineSegmentsGeometry } from 'three/addons/lines/LineSegmentsGeometry.js';
5
- import { InstancedMeshExt } from '../instanced/InstancedMesh';
5
+ import { InstancedMeshImpl } from '../instanced/InstancedMesh';
6
6
  import { FrustumCulling } from './FrustumCulling';
7
7
  import { END_UNIFORM, patchLineMaterial, START_UNIFORM, WIDTH_UNIFORM } from './lines-material';
8
8
  import { Raycasting } from './Raycasting';
@@ -33,7 +33,7 @@ import { Raycasting } from './Raycasting';
33
33
  *
34
34
  * Render it with {@link BatchedLines}.
35
35
  */
36
- export class BatchedLinesExt extends InstancedMeshExt {
36
+ export class BatchedLinesImpl extends InstancedMeshImpl {
37
37
  /**
38
38
  * The segment template every member is drawn from, and the whole of what the geometry carries: the
39
39
  * per-instance data three would put in instanced attributes is in the uniforms instead.
@@ -188,7 +188,7 @@ export class BatchedLinesExt extends InstancedMeshExt {
188
188
  * Registers the class as an R3F element, by value so the generated key cannot collide with anything
189
189
  * three puts in the catalog when the canvas mounts.
190
190
  */
191
- export const BatchedLines = extend(BatchedLinesExt);
191
+ export const BatchedLines = extend(BatchedLinesImpl);
192
192
  /**
193
193
  * Whether a material is one three's line shader compiles from.
194
194
  * @param material - The material three is about to draw with.
@@ -199,7 +199,7 @@ function isLineMaterial(material) {
199
199
  }
200
200
  /**
201
201
  * The width a member starts at: negative, which is how "none of its own" is marked, so it draws at
202
- * the material's. See {@link BatchedLinesExt.setWidthAt} for why the marker is a negative value and
202
+ * the material's. See {@link BatchedLinesImpl.setWidthAt} for why the marker is a negative value and
203
203
  * not zero.
204
204
  */
205
205
  const MATERIAL_WIDTH = -1;
@@ -2,7 +2,7 @@ import { type BufferGeometry, type Camera, type Intersection, type Material, typ
2
2
  import { BatchedText as TroikaBatchedText, type TextMaterial } from 'troika-three-text';
3
3
  import { type UniformSchemaShader } from '../InstanceUniforms';
4
4
  import { type UniformValue, type UniformValueObj } from '../SquareDataTexture';
5
- import { type TextExt } from './Text';
5
+ import { type TextImpl } from './Text';
6
6
  /**
7
7
  * troika's `BatchedText` with stable member ids, explicit paint order, and per-instance uniforms.
8
8
  *
@@ -24,7 +24,7 @@ import { type TextExt } from './Text';
24
24
  * Other departures from upstream:
25
25
  *
26
26
  * - **Sync is flag-driven, not scanned.** Members report property writes through
27
- * `TextExt._batchParent`, so an idle frame costs nothing instead of walking every member.
27
+ * `TextImpl._batchParent`, so an idle frame costs nothing instead of walking every member.
28
28
  * - **Per-member frustum culling and visibility**, by zeroing a hidden member's matrix so its glyphs
29
29
  * collapse to a degenerate triangle. See {@link MemberTexture}.
30
30
  * - **Bounds are cached**, recomputed only when {@link invalidateBounds} says they moved, where
@@ -34,7 +34,7 @@ import { type TextExt } from './Text';
34
34
  * - **The derived material inherits the base's `transparent`**, rather than troika forcing it true.
35
35
  * See {@link configureDerivedMaterial}.
36
36
  *
37
- * **Not built on {@link InstancedMeshExt}'s machinery**, despite the family resemblance. That mesh
37
+ * **Not built on {@link InstancedMeshImpl}'s machinery**, despite the family resemblance. That mesh
38
38
  * draws one shared geometry through a per-frame list of instance ids, so it culls and sorts by
39
39
  * rewriting the list; here draw order *is* the order glyph runs sit in the attributes, so a reorder
40
40
  * costs a repack and culling collapses a matrix row instead. Its members are real objects carrying
@@ -42,14 +42,14 @@ import { type TextExt } from './Text';
42
42
  * per member rather than in bulk by count, and visibility rides on the member's own `visible`. What
43
43
  * the two genuinely share is {@link InstanceUniforms}.
44
44
  *
45
- * Members must be {@link TextExt}, and are assumed to agree on `orientation` and `sdfGlyphSize`:
45
+ * Members must be {@link TextImpl}, and are assumed to agree on `orientation` and `sdfGlyphSize`:
46
46
  * both feed uniforms that are batch-wide rather than per-member, so mixing them across a batch
47
47
  * leaves whichever member was written last in charge.
48
48
  *
49
49
  * Render it with {@link BatchedText}.
50
50
  */
51
- export declare class BatchedTextExt extends TroikaBatchedText {
52
- /** Per-instance uniform store, shared with {@link BatchedMeshExt} and {@link InstancedMeshExt}. */
51
+ export declare class BatchedTextImpl extends TroikaBatchedText {
52
+ /** Per-instance uniform store, shared with {@link BatchedMeshImpl} and {@link InstancedMeshImpl}. */
53
53
  private readonly uniforms;
54
54
  /** The per-member transform and style rows the batch's shader draws from. */
55
55
  private readonly memberTexture;
@@ -76,7 +76,7 @@ export declare class BatchedTextExt extends TroikaBatchedText {
76
76
  * hole.
77
77
  *
78
78
  * **A pure high-water mark: removing a member never pulls it back in**, unlike `Instances`, the
79
- * equivalent for {@link InstancedMeshExt}, which shrinks past trailing dead ids. Converting either
79
+ * equivalent for {@link InstancedMeshImpl}, which shrinks past trailing dead ids. Converting either
80
80
  * to the other buys nothing. A dead row costs the sweeps here one array read and a `continue`; and
81
81
  * this same number also sizes both textures, where `Instances` has a separate `capacity` for that
82
82
  * — so shrinking it would reallocate the matrix and uniform textures every time the last member
@@ -85,10 +85,10 @@ export declare class BatchedTextExt extends TroikaBatchedText {
85
85
  get addedMembersCount(): number;
86
86
  /** The material whose `onBeforeCompile` is already wrapped, so it is wrapped exactly once. */
87
87
  private patchedMaterial;
88
- /** Marks the batch as needing a sync pass. Members call this through `TextExt._batchParent`. */
88
+ /** Marks the batch as needing a sync pass. Members call this through `TextImpl._batchParent`. */
89
89
  requestSync(): void;
90
90
  /**
91
- * Marks the batch's bounds as stale. Members call this through `TextExt._batchParent` whenever
91
+ * Marks the batch's bounds as stale. Members call this through `TextImpl._batchParent` whenever
92
92
  * their transform changes, so no caller has to remember to.
93
93
  */
94
94
  invalidateBounds(): void;
@@ -97,7 +97,7 @@ export declare class BatchedTextExt extends TroikaBatchedText {
97
97
  * @param memberId - The member to read.
98
98
  * @returns The member, or `undefined` when the id holds none.
99
99
  */
100
- getText(memberId: number): TextExt | undefined;
100
+ getText(memberId: number): TextImpl | undefined;
101
101
  /**
102
102
  * Shows or hides a member. A hidden member keeps its id and its glyphs; it is collapsed at draw
103
103
  * time rather than repacked out, so hiding costs no repack.
@@ -119,7 +119,7 @@ export declare class BatchedTextExt extends TroikaBatchedText {
119
119
  * @param texts - Every member, in paint order. Members missing from it are not drawn, and anything
120
120
  * that is not a member is dropped.
121
121
  */
122
- setOrder(texts: readonly TextExt[]): void;
122
+ setOrder(texts: readonly TextImpl[]): void;
123
123
  /**
124
124
  * Declares per-instance uniforms, merging with any already declared and rebuilding the backing
125
125
  * texture (existing values carried across). See {@link InstanceUniforms.add}.
@@ -147,8 +147,8 @@ export declare class BatchedTextExt extends TroikaBatchedText {
147
147
  * @returns The member’s id — stable for as long as it stays in the batch, and the index every
148
148
  * other method here takes.
149
149
  */
150
- addText(text: TextExt): number;
151
- removeText(text: TextExt): void;
150
+ addText(text: TextImpl): number;
151
+ removeText(text: TextImpl): void;
152
152
  /**
153
153
  * Copies the text-level properties, and deliberately not the membership.
154
154
  *
@@ -223,5 +223,5 @@ export declare class BatchedTextExt extends TroikaBatchedText {
223
223
  * Registers the class as an R3F element, by value so the generated key cannot collide with anything
224
224
  * three puts in the catalog when the canvas mounts.
225
225
  */
226
- export declare const BatchedText: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<BatchedTextExt, import("@react-three/fiber").MathProps<BatchedTextExt> & import("@react-three/fiber").ReactProps<BatchedTextExt> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<BatchedTextExt, typeof BatchedTextExt>, "object">>>>;
226
+ export declare const BatchedText: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<BatchedTextImpl, import("@react-three/fiber").MathProps<BatchedTextImpl> & import("@react-three/fiber").ReactProps<BatchedTextImpl> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<BatchedTextImpl, typeof BatchedTextImpl>, "object">>>>;
227
227
  //# sourceMappingURL=BatchedText.d.ts.map
@@ -26,7 +26,7 @@ import { MemberTexture } from './MemberTexture';
26
26
  * Other departures from upstream:
27
27
  *
28
28
  * - **Sync is flag-driven, not scanned.** Members report property writes through
29
- * `TextExt._batchParent`, so an idle frame costs nothing instead of walking every member.
29
+ * `TextImpl._batchParent`, so an idle frame costs nothing instead of walking every member.
30
30
  * - **Per-member frustum culling and visibility**, by zeroing a hidden member's matrix so its glyphs
31
31
  * collapse to a degenerate triangle. See {@link MemberTexture}.
32
32
  * - **Bounds are cached**, recomputed only when {@link invalidateBounds} says they moved, where
@@ -36,7 +36,7 @@ import { MemberTexture } from './MemberTexture';
36
36
  * - **The derived material inherits the base's `transparent`**, rather than troika forcing it true.
37
37
  * See {@link configureDerivedMaterial}.
38
38
  *
39
- * **Not built on {@link InstancedMeshExt}'s machinery**, despite the family resemblance. That mesh
39
+ * **Not built on {@link InstancedMeshImpl}'s machinery**, despite the family resemblance. That mesh
40
40
  * draws one shared geometry through a per-frame list of instance ids, so it culls and sorts by
41
41
  * rewriting the list; here draw order *is* the order glyph runs sit in the attributes, so a reorder
42
42
  * costs a repack and culling collapses a matrix row instead. Its members are real objects carrying
@@ -44,14 +44,14 @@ import { MemberTexture } from './MemberTexture';
44
44
  * per member rather than in bulk by count, and visibility rides on the member's own `visible`. What
45
45
  * the two genuinely share is {@link InstanceUniforms}.
46
46
  *
47
- * Members must be {@link TextExt}, and are assumed to agree on `orientation` and `sdfGlyphSize`:
47
+ * Members must be {@link TextImpl}, and are assumed to agree on `orientation` and `sdfGlyphSize`:
48
48
  * both feed uniforms that are batch-wide rather than per-member, so mixing them across a batch
49
49
  * leaves whichever member was written last in charge.
50
50
  *
51
51
  * Render it with {@link BatchedText}.
52
52
  */
53
- export class BatchedTextExt extends TroikaBatchedText {
54
- /** Per-instance uniform store, shared with {@link BatchedMeshExt} and {@link InstancedMeshExt}. */
53
+ export class BatchedTextImpl extends TroikaBatchedText {
54
+ /** Per-instance uniform store, shared with {@link BatchedMeshImpl} and {@link InstancedMeshImpl}. */
55
55
  uniforms = new InstanceUniforms();
56
56
  /** The per-member transform and style rows the batch's shader draws from. */
57
57
  memberTexture = new MemberTexture();
@@ -85,7 +85,7 @@ export class BatchedTextExt extends TroikaBatchedText {
85
85
  * hole.
86
86
  *
87
87
  * **A pure high-water mark: removing a member never pulls it back in**, unlike `Instances`, the
88
- * equivalent for {@link InstancedMeshExt}, which shrinks past trailing dead ids. Converting either
88
+ * equivalent for {@link InstancedMeshImpl}, which shrinks past trailing dead ids. Converting either
89
89
  * to the other buys nothing. A dead row costs the sweeps here one array read and a `continue`; and
90
90
  * this same number also sizes both textures, where `Instances` has a separate `capacity` for that
91
91
  * — so shrinking it would reallocate the matrix and uniform textures every time the last member
@@ -96,12 +96,12 @@ export class BatchedTextExt extends TroikaBatchedText {
96
96
  }
97
97
  /** The material whose `onBeforeCompile` is already wrapped, so it is wrapped exactly once. */
98
98
  patchedMaterial = null;
99
- /** Marks the batch as needing a sync pass. Members call this through `TextExt._batchParent`. */
99
+ /** Marks the batch as needing a sync pass. Members call this through `TextImpl._batchParent`. */
100
100
  requestSync() {
101
101
  this.batchNeedsSync = true;
102
102
  }
103
103
  /**
104
- * Marks the batch's bounds as stale. Members call this through `TextExt._batchParent` whenever
104
+ * Marks the batch's bounds as stale. Members call this through `TextImpl._batchParent` whenever
105
105
  * their transform changes, so no caller has to remember to.
106
106
  */
107
107
  invalidateBounds() {
@@ -456,7 +456,7 @@ export class BatchedTextExt extends TroikaBatchedText {
456
456
  * Registers the class as an R3F element, by value so the generated key cannot collide with anything
457
457
  * three puts in the catalog when the canvas mounts.
458
458
  */
459
- export const BatchedText = extend(BatchedTextExt);
459
+ export const BatchedText = extend(BatchedTextImpl);
460
460
  // Reused rather than built per dispatch: three's `dispatchEvent` stamps `target` on the object it
461
461
  // is handed, so these are one allocation for the batch's lifetime instead of one per event.
462
462
  const syncStartEvent = { type: 'syncstart' };
@@ -1,6 +1,6 @@
1
1
  import { type Camera, type ColorRepresentation, Matrix4 } from 'three';
2
2
  import { type BatchTextMaterial } from 'troika-three-text';
3
- import { type TextExt } from './Text';
3
+ import { type TextImpl } from './Text';
4
4
  /** What {@link MemberTexture} reads off the batch it fills for. */
5
5
  export interface MemberTextureHost {
6
6
  /**
@@ -18,7 +18,7 @@ export interface MemberTextureHost {
18
18
  * @param memberId - The member to read.
19
19
  * @returns The member, or `undefined` when the id holds none.
20
20
  */
21
- getText(memberId: number): TextExt | undefined;
21
+ getText(memberId: number): TextImpl | undefined;
22
22
  }
23
23
  /**
24
24
  * The data texture a batch's shader reads each member's transform and style from: one 32-float row
@@ -1,6 +1,6 @@
1
1
  import { Matrix4 } from 'three';
2
2
  import { Text as TroikaText, type TextMaterial } from 'troika-three-text';
3
- import { type BatchedTextExt } from './BatchedText';
3
+ import { type BatchedTextImpl } from './BatchedText';
4
4
  /**
5
5
  * troika's `Text` with the deviations a batched, 2D-painter renderer needs.
6
6
  *
@@ -30,13 +30,13 @@ import { type BatchedTextExt } from './BatchedText';
30
30
  *
31
31
  * Render it with {@link Text}.
32
32
  */
33
- export declare class TextExt extends TroikaText {
33
+ export declare class TextImpl extends TroikaText {
34
34
  /**
35
- * The batch this text belongs to, set by {@link BatchedTextExt.addText}. It is how a member
35
+ * The batch this text belongs to, set by {@link BatchedTextImpl.addText}. It is how a member
36
36
  * reaches its batch without the batch scanning for changes: property writes invalidate the sync
37
37
  * through it, and transform writes invalidate the bounds.
38
38
  */
39
- _batchParent: BatchedTextExt | undefined;
39
+ _batchParent: BatchedTextImpl | undefined;
40
40
  /**
41
41
  * Backing store for the `_needsSync` accessor installed on the prototype below.
42
42
  *
@@ -69,5 +69,5 @@ export declare class TextExt extends TroikaText {
69
69
  * Registers the class as an R3F element, by value so the generated key cannot collide with anything
70
70
  * three puts in the catalog when the canvas mounts.
71
71
  */
72
- export declare const Text: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<TextExt, import("@react-three/fiber").MathProps<TextExt> & import("@react-three/fiber").ReactProps<TextExt> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<TextExt, typeof TextExt>, "object">>>>;
72
+ export declare const Text: import("react").ExoticComponent<import("@react-three/fiber/dist/declarations/src/core/utils").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils").Overwrite<TextImpl, import("@react-three/fiber").MathProps<TextImpl> & import("@react-three/fiber").ReactProps<TextImpl> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<TextImpl, typeof TextImpl>, "object">>>>;
73
73
  //# sourceMappingURL=Text.d.ts.map
@@ -30,9 +30,9 @@ import { Text as TroikaText } from 'troika-three-text';
30
30
  *
31
31
  * Render it with {@link Text}.
32
32
  */
33
- export class TextExt extends TroikaText {
33
+ export class TextImpl extends TroikaText {
34
34
  /**
35
- * The batch this text belongs to, set by {@link BatchedTextExt.addText}. It is how a member
35
+ * The batch this text belongs to, set by {@link BatchedTextImpl.addText}. It is how a member
36
36
  * reaches its batch without the batch scanning for changes: property writes invalidate the sync
37
37
  * through it, and transform writes invalidate the bounds.
38
38
  */
@@ -189,7 +189,7 @@ export class TextExt extends TroikaText {
189
189
  * Runs during `super()` — the base constructor seeds the syncable properties — at which point the
190
190
  * `_batchParent` field initializer has not run yet, so the optional call is doing real work.
191
191
  */
192
- Object.defineProperty(TextExt.prototype, '_needsSync', {
192
+ Object.defineProperty(TextImpl.prototype, '_needsSync', {
193
193
  configurable: true,
194
194
  get() {
195
195
  return this._syncFlag;
@@ -206,7 +206,7 @@ Object.defineProperty(TextExt.prototype, '_needsSync', {
206
206
  * Registers the class as an R3F element, by value so the generated key cannot collide with anything
207
207
  * three puts in the catalog when the canvas mounts.
208
208
  */
209
- export const Text = extend(TextExt);
209
+ export const Text = extend(TextImpl);
210
210
  // Scratch reused across calls, each filled and consumed within a single synchronous block.
211
211
  const _matrix = new Matrix4();
212
212
  const _horizontal = new Vector3();
@@ -1,5 +1,5 @@
1
1
  import { type GlyphsGeometry, type TextRenderInfo } from 'troika-three-text';
2
- import { type TextExt } from './Text';
2
+ import { type TextImpl } from './Text';
3
3
  /**
4
4
  * Rewrites a batch's glyph attributes from its members' render info.
5
5
  *
@@ -13,5 +13,5 @@ import { type TextExt } from './Text';
13
13
  * @returns The render info the batch should adopt as its own — any member's will do, since a batch
14
14
  * shares one SDF atlas — or `undefined` when no member has synced.
15
15
  */
16
- export declare function packGlyphs(geometry: GlyphsGeometry, ordered: readonly number[], textAt: (memberId: number) => TextExt | undefined): TextRenderInfo | undefined;
16
+ export declare function packGlyphs(geometry: GlyphsGeometry, ordered: readonly number[], textAt: (memberId: number) => TextImpl | undefined): TextRenderInfo | undefined;
17
17
  //# sourceMappingURL=glyph-packing.d.ts.map
@@ -57,9 +57,13 @@ export interface LayoutTargets {
57
57
  * Two passes, in the legacy `UpdatesSystem`'s shape: the stale defs first, except that a hidden
58
58
  * def or one the frustum rejects is *deferred* rather than laid out; then the deferred ones, with
59
59
  * whatever budget is left. Priority is all deferral buys — every def is still laid out before the
60
- * sweep ends, because whether a def draws can be exactly what its rule decides. The budget is
61
- * checked before each def, so even a blown budget lays at least one out and a sweep can never
62
- * stall.
60
+ * sweep ends, because whether a def draws can be exactly what its rule decides.
61
+ *
62
+ * **A drain always takes at least one def**, across the two passes together, however little
63
+ * budget is left — including none, which is what a worker descheduled before the first check
64
+ * leaves. That is what makes a sweep unable to stall: each drain shortens the backlog, so the
65
+ * frames the driver keeps asking for eventually end it. Without the guarantee a drain can dequeue
66
+ * nothing, return "more to do", and be asked again on the next frame with the same result.
63
67
  * @param frustum - The camera's frustum in plan space, when the caller has one; without it only
64
68
  * hidden defs are deferred.
65
69
  * @param budgetMs - How much of the frame a call may spend. Non-positive means no limit.
@@ -208,14 +208,25 @@ export function createLayoutTargets(invalidate, pixelSize, roll = 0) {
208
208
  if (pending.size === 0 && deferred.size === 0)
209
209
  return false;
210
210
  const start = performance.now();
211
- const overBudget = () => budgetMs > 0 && performance.now() - start >= budgetMs;
212
211
  let wrote = 0;
212
+ /**
213
+ * Defs this drain has taken off a queue, laid out or deferred.
214
+ *
215
+ * It gates the budget so that the **first** def of a drain is always taken. Without that, a
216
+ * budget already spent before the loop began — the worker descheduled between `start` and the
217
+ * check, which a loaded machine does routinely — dequeues nothing at all, and a drain that
218
+ * dequeues nothing is the stall this budget exists to prevent. Shared across both passes, so
219
+ * the guarantee is one def per drain rather than one per pass.
220
+ */
221
+ let processed = 0;
222
+ const overBudget = () => processed > 0 && budgetMs > 0 && performance.now() - start >= budgetMs;
213
223
  // Sets iterate in insertion order and tolerate deletion mid-walk, which is what makes the two
214
224
  // passes below plain loops: the order moves arrived is the priority within a pass, and a
215
225
  // processed def leaves its set before its rules run.
216
226
  for (const def of pending) {
217
227
  if (overBudget())
218
228
  break;
229
+ processed++;
219
230
  pending.delete(def);
220
231
  // Deferral is priority, never a skip: a hidden def, or one the camera cannot see, joins the
221
232
  // second pass rather than being laid out now. `def.hidden` needs no frustum — hidden is not
@@ -230,6 +241,7 @@ export function createLayoutTargets(invalidate, pixelSize, roll = 0) {
230
241
  for (const def of deferred) {
231
242
  if (overBudget())
232
243
  break;
244
+ processed++;
233
245
  deferred.delete(def);
234
246
  if (layOutStale(def))
235
247
  wrote++;
@@ -5,8 +5,8 @@ import { type RenderableDef } from '../../types/defs';
5
5
  /**
6
6
  * What a container needs from the mesh it writes into.
7
7
  *
8
- * A capability rather than a union of our mesh classes: `BatchedMeshExt`, `InstancedMeshExt`,
9
- * `BatchedLinesExt` and `BatchedTextExt` share no base below `Object3D`, yet every one of them
8
+ * A capability rather than a union of our mesh classes: `BatchedMeshImpl`, `InstancedMeshImpl`,
9
+ * `BatchedLinesImpl` and `BatchedTextImpl` share no base below `Object3D`, yet every one of them
10
10
  * declares per-instance uniforms and hides an instance the same way — which is all a container
11
11
  * touches generically. Everything else it reaches through its own mesh type, which the subclass
12
12
  * names.
@@ -148,6 +148,8 @@ export declare abstract class SlotContainer<R, M extends SlotMesh = SlotMesh, T
148
148
  private readonly sortDirection;
149
149
  /** Set by {@link bind}, which runs before any effect can claim a slot. */
150
150
  private boundMesh;
151
+ /** What to run when a member turns out to belong in a sibling container; see {@link reportKindMismatch}. */
152
+ private kindMismatchHandler;
151
153
  /**
152
154
  * @param options - How this container differs from the default.
153
155
  */
@@ -201,6 +203,29 @@ export declare abstract class SlotContainer<R, M extends SlotMesh = SlotMesh, T
201
203
  * @returns The def, or `undefined` when the hit cannot be traced to one.
202
204
  */
203
205
  defFromHit(hit: Intersection): RenderableDef | undefined;
206
+ /**
207
+ * Registers what to do when a member turns out to belong in a sibling container; `undefined`
208
+ * clears it.
209
+ *
210
+ * Here rather than on each subclass because the situation is one situation: a layer is split
211
+ * across several containers by some property of the def, and that property can move after the def
212
+ * was placed. What splits them differs — a shape's color crossing alpha 1, a model's `opacity`,
213
+ * an image's orientation — but what a container does about it does not, and the component that
214
+ * owns the split is always the one that can repair it.
215
+ *
216
+ * A method rather than an assignable field because the container is held in `useState`, and the
217
+ * React Compiler rejects writing to a property of a state value ("This value cannot be modified").
218
+ * Calling a method is fine, which is how {@link reserve} already mutates.
219
+ * @param handler - The re-split to run, or `undefined` to clear it.
220
+ */
221
+ setKindMismatchHandler(handler: (() => void) | undefined): void;
222
+ /**
223
+ * Reports that a member no longer belongs in this container, so it is drawing from the wrong mesh.
224
+ * Runs the registered handler, if any; a container mounted without one — in a spec, or bare —
225
+ * drops the report rather than failing, since nothing it could do would be more correct than
226
+ * carrying on.
227
+ */
228
+ reportKindMismatch(): void;
204
229
  /**
205
230
  * Shows or hides one instance. Every def type carries `hidden`, so `useDefSync` drives this for
206
231
  * all of them.
@@ -79,6 +79,8 @@ export class SlotContainer {
79
79
  sortDirection;
80
80
  /** Set by {@link bind}, which runs before any effect can claim a slot. */
81
81
  boundMesh;
82
+ /** What to run when a member turns out to belong in a sibling container; see {@link reportKindMismatch}. */
83
+ kindMismatchHandler;
82
84
  /**
83
85
  * @param options - How this container differs from the default.
84
86
  */
@@ -175,6 +177,33 @@ export class SlotContainer {
175
177
  defFromHit(hit) {
176
178
  return this.defAt(hit.instanceId);
177
179
  }
180
+ /**
181
+ * Registers what to do when a member turns out to belong in a sibling container; `undefined`
182
+ * clears it.
183
+ *
184
+ * Here rather than on each subclass because the situation is one situation: a layer is split
185
+ * across several containers by some property of the def, and that property can move after the def
186
+ * was placed. What splits them differs — a shape's color crossing alpha 1, a model's `opacity`,
187
+ * an image's orientation — but what a container does about it does not, and the component that
188
+ * owns the split is always the one that can repair it.
189
+ *
190
+ * A method rather than an assignable field because the container is held in `useState`, and the
191
+ * React Compiler rejects writing to a property of a state value ("This value cannot be modified").
192
+ * Calling a method is fine, which is how {@link reserve} already mutates.
193
+ * @param handler - The re-split to run, or `undefined` to clear it.
194
+ */
195
+ setKindMismatchHandler(handler) {
196
+ this.kindMismatchHandler = handler;
197
+ }
198
+ /**
199
+ * Reports that a member no longer belongs in this container, so it is drawing from the wrong mesh.
200
+ * Runs the registered handler, if any; a container mounted without one — in a spec, or bare —
201
+ * drops the report rather than failing, since nothing it could do would be more correct than
202
+ * carrying on.
203
+ */
204
+ reportKindMismatch() {
205
+ this.kindMismatchHandler?.();
206
+ }
178
207
  /**
179
208
  * Shows or hides one instance. Every def type carries `hidden`, so `useDefSync` drives this for
180
209
  * all of them.
@@ -6,7 +6,7 @@ import { type Logger } from '../../utils/logging';
6
6
  * A mesh whose instances carry a transform.
7
7
  *
8
8
  * Named as a capability rather than listed as a union of our mesh classes, because not every batch
9
- * has one: `BatchedLinesExt` places its members by their endpoints and has no per-instance matrix
9
+ * has one: `BatchedLinesImpl` places its members by their endpoints and has no per-instance matrix
10
10
  * at all, yet still writes colors through the helper below. A class that satisfies only one of
11
11
  * these two interfaces is the point — the alternative was no-op matrix methods on a class that has
12
12
  * no transforms, which would read as a capability it does not have.
@@ -99,7 +99,7 @@ function ImageAtlas(props) {
99
99
  // rejecting its render reads.
100
100
  // The quad and the material are children so R3F creates, attaches, and disposes both — the args
101
101
  // pair are placeholders the constructor demands (see `ImageMeshArgs`). The material has to be per
102
- // mesh: `InstancedMeshExt` wraps whatever it draws with in a closure over its own textures, and two
102
+ // mesh: `InstancedMeshImpl` wraps whatever it draws with in a closure over its own textures, and two
103
103
  // instanced meshes on one material would both render against the first one's.
104
104
  return (_jsxs(_Fragment, { children: [_jsxs(InstancedMesh, { args: container.args, ref: (mesh) => container.bind(mesh), sortObjects: true, customSort: container.customSort, perObjectFrustumCulled: true, children: [_jsx("planeGeometry", {}), _jsx(TextureMaterial, { map: texture, uvOffset: UV_OFFSET_UNIFORM })] }), atlas.images.slice(0, mounted).map((packed) => (_jsx(ImageInstance, { def: packed.def, packed: packed, container: container }, `${defKey(packed.def)}:${packed.uv.u0}:${packed.uv.v0}`)))] }));
105
105
  }
@@ -1,4 +1,4 @@
1
- import { type InstancedMeshExt, type InstancedMeshExtParams } from '../../core/instanced/InstancedMesh';
1
+ import { type InstancedMeshImpl, type InstancedMeshImplParams } from '../../core/instanced/InstancedMesh';
2
2
  import { type ImageDef } from '../../types/defs';
3
3
  import { SlotContainer } from '../containers';
4
4
  import { type Atlas, type PackedImage } from './atlas-packer';
@@ -15,16 +15,16 @@ export declare const UV_OFFSET_UNIFORM = "uvOffset";
15
15
  * R3F diffs `args` element-wise and rebuilds the object when any element changes, so this is
16
16
  * snapshotted once and never mutated.
17
17
  *
18
- * Only the options: `InstancedMeshExt` takes no geometry or material, seeding throwaways that the
18
+ * Only the options: `InstancedMeshImpl` takes no geometry or material, seeding throwaways that the
19
19
  * element's `<planeGeometry>` and `<TextureMaterial>` children replace (R3F creates, attaches, and
20
20
  * disposes those).
21
21
  */
22
- export type ImageMeshArgs = [params: InstancedMeshExtParams];
22
+ export type ImageMeshArgs = [params: InstancedMeshImplParams];
23
23
  /**
24
24
  * One atlas's mesh bookkeeping.
25
25
  *
26
26
  * Simpler than a shape container, and deliberately so: an atlas draws one shared quad, so there is
27
- * no geometry cache and no geometry-id juggling, and `InstancedMeshExt` grows its own buffers, so
27
+ * no geometry cache and no geometry-id juggling, and `InstancedMeshImpl` grows its own buffers, so
28
28
  * there is no capacity pre-scan — the mesh is merely sized to the atlas's packed-image count and
29
29
  * left to resize itself if a claim ever overflows it. What remains is a slot per packed image and
30
30
  * the uv region each one samples, written once at claim since a def's source never changes.
@@ -34,7 +34,7 @@ export type ImageMeshArgs = [params: InstancedMeshExtParams];
34
34
  * change to the *set* of images is the harder case and still repacks into a fresh container —
35
35
  * packing has no incremental path for that — but a pure reorder does not.
36
36
  */
37
- export declare class ImageContainer extends SlotContainer<PackedImage, InstancedMeshExt, ImageDef> {
37
+ export declare class ImageContainer extends SlotContainer<PackedImage, InstancedMeshImpl, ImageDef> {
38
38
  /** The constructor args R3F builds the mesh from; a frozen snapshot, never mutated. */
39
39
  readonly args: ImageMeshArgs;
40
40
  /**
@@ -13,7 +13,7 @@ export const UV_OFFSET_UNIFORM = 'uvOffset';
13
13
  * One atlas's mesh bookkeeping.
14
14
  *
15
15
  * Simpler than a shape container, and deliberately so: an atlas draws one shared quad, so there is
16
- * no geometry cache and no geometry-id juggling, and `InstancedMeshExt` grows its own buffers, so
16
+ * no geometry cache and no geometry-id juggling, and `InstancedMeshImpl` grows its own buffers, so
17
17
  * there is no capacity pre-scan — the mesh is merely sized to the atlas's packed-image count and
18
18
  * left to resize itself if a claim ever overflows it. What remains is a slot per packed image and
19
19
  * the uv region each one samples, written once at claim since a def's source never changes.
@@ -1,5 +1,5 @@
1
- import { type InstancedMeshExtParams } from '../../core/instanced/InstancedMesh';
2
- import { type BatchedLinesExt } from '../../core/lines/BatchedLines';
1
+ import { type InstancedMeshImplParams } from '../../core/instanced/InstancedMesh';
2
+ import { type BatchedLinesImpl } from '../../core/lines/BatchedLines';
3
3
  import { type LineDef } from '../../types/defs';
4
4
  import { SlotContainer } from '../containers';
5
5
  /**
@@ -10,7 +10,7 @@ import { SlotContainer } from '../containers';
10
10
  * Only the options: the batch builds its own segment template and takes its material from the
11
11
  * `<LineMaterial>` child R3F mounts under it.
12
12
  */
13
- export type LineMeshArgs = [params: InstancedMeshExtParams];
13
+ export type LineMeshArgs = [params: InstancedMeshImplParams];
14
14
  /**
15
15
  * One line layer's bookkeeping.
16
16
  *
@@ -19,7 +19,7 @@ export type LineMeshArgs = [params: InstancedMeshExtParams];
19
19
  * endpoints. That is why the resource type is `null` here: nothing about a `LineDef` can force a
20
20
  * re-claim, so a def keeps its slot for as long as it is mounted, `points` included.
21
21
  */
22
- export declare class LineContainer extends SlotContainer<null, BatchedLinesExt, LineDef> {
22
+ export declare class LineContainer extends SlotContainer<null, BatchedLinesImpl, LineDef> {
23
23
  /** The constructor args R3F builds the batch from; a frozen snapshot, never mutated. */
24
24
  readonly args: LineMeshArgs;
25
25
  /**
@@ -4,7 +4,7 @@ export interface LineMaterialProps {
4
4
  /** Base color. Defaults to white, which is what a per-instance tint multiplies against. */
5
5
  color?: ColorRepresentation;
6
6
  /**
7
- * Width every member without one of its own draws at, in screen-space pixels — `BatchedLinesExt`
7
+ * Width every member without one of its own draws at, in screen-space pixels — `BatchedLinesImpl`
8
8
  * resolves an unset per-member width to this. Defaults to 1.
9
9
  */
10
10
  width?: number;
@@ -32,7 +32,7 @@ export declare function useDimPatch(): DimPatch;
32
32
  * is the exception: troika calls the base material's handler first and then rebuilds `main` around
33
33
  * it — renaming the original `troikaOrigMain` and calling it from a new one — so a patch installed
34
34
  * there would land in a scope the prologue's local never reaches. With this guard that early call
35
- * simply does nothing, and `BatchedTextExt` runs the same patch again once its prologue is in.
35
+ * simply does nothing, and `BatchedTextImpl` runs the same patch again once its prologue is in.
36
36
  * @param parameters - The shader being compiled.
37
37
  * @param uniform - The layer's dim amount.
38
38
  * @returns Whether the shader was patched.
@@ -42,7 +42,7 @@ export function useDimPatch() {
42
42
  * is the exception: troika calls the base material's handler first and then rebuilds `main` around
43
43
  * it — renaming the original `troikaOrigMain` and calling it from a new one — so a patch installed
44
44
  * there would land in a scope the prologue's local never reaches. With this guard that early call
45
- * simply does nothing, and `BatchedTextExt` runs the same patch again once its prologue is in.
45
+ * simply does nothing, and `BatchedTextImpl` runs the same patch again once its prologue is in.
46
46
  * @param parameters - The shader being compiled.
47
47
  * @param uniform - The layer's dim amount.
48
48
  * @returns Whether the shader was patched.
@@ -136,7 +136,7 @@ function ModelPartMesh(props) {
136
136
  // Only the instances are staged; the container is sized and ordered from every member.
137
137
  const mounted = props.mounted ?? defs.length;
138
138
  // Ordering is a no-op for models — their container declares it so, and the mesh depth-sorts itself
139
- // instead — but the hit resolution is not: `InstancedMeshExt.raycast` walks the live slots,
139
+ // instead — but the hit resolution is not: `InstancedMeshImpl.raycast` walks the live slots,
140
140
  // skipping deleted and hidden ones, and raycasts the real merged geometry, so a hit names the
141
141
  // model's actual triangles and the slot that drew them.
142
142
  const container = useContainer(() => new ModelContainer(asset.extents, defs.length, kind), defs);
@@ -150,7 +150,7 @@ function ModelPartMesh(props) {
150
150
  }, [container, onKindMismatch]);
151
151
  // The geometry belongs to the module-level cache and may be drawing in another layer, so it is
152
152
  // mounted as a `primitive` with `dispose={null}` — R3F must not free it on unmount. Sharing it is
153
- // safe because `InstancedMeshExt` never writes to the geometry it is handed: its draw list lives in
153
+ // safe because `InstancedMeshImpl` never writes to the geometry it is handed: its draw list lives in
154
154
  // a texture of its own, addressed by `gl_InstanceID`. The material cannot be shared the same way —
155
155
  // the mesh wraps it in a closure over its own textures — so `ModelMaterial` clones it per mesh.
156
156
  //
@@ -1,6 +1,6 @@
1
1
  import { type Rect } from '@expofp/geometry';
2
2
  import { type Box3, Matrix4 } from 'three';
3
- import { type InstancedMeshExt, type InstancedMeshExtParams } from '../../core/instanced/InstancedMesh';
3
+ import { type InstancedMeshImpl, type InstancedMeshImplParams } from '../../core/instanced/InstancedMesh';
4
4
  import { type ModelDef } from '../../types/defs';
5
5
  import { SlotContainer } from '../containers';
6
6
  /**
@@ -10,7 +10,7 @@ import { SlotContainer } from '../containers';
10
10
  */
11
11
  export declare const OPACITY_UNIFORM = "instanceOpacity";
12
12
  /** The constructor tuple R3F builds one model mesh from. Frozen, so R3F never rebuilds the mesh. */
13
- export type ModelMeshArgs = [params: InstancedMeshExtParams];
13
+ export type ModelMeshArgs = [params: InstancedMeshImplParams];
14
14
  /**
15
15
  * Every kind of model batch, **in the order they draw within a layer** — which is what `Models`
16
16
  * numbers them by.
@@ -34,11 +34,11 @@ export declare function modelKindOf(def: ModelDef): ModelKind;
34
34
  * twenty copies of a chair are one draw call rather than twenty.
35
35
  *
36
36
  * Much simpler than a shape container. The geometry is the part's — shared, never per instance — so
37
- * there is no geometry cache and no capacity pre-scan, and `InstancedMeshExt` grows its own buffers,
37
+ * there is no geometry cache and no capacity pre-scan, and `InstancedMeshImpl` grows its own buffers,
38
38
  * so nothing here has to size anything. What is left is a slot per def and the transform each one
39
39
  * draws with.
40
40
  */
41
- export declare class ModelContainer extends SlotContainer<null, InstancedMeshExt, ModelDef> {
41
+ export declare class ModelContainer extends SlotContainer<null, InstancedMeshImpl, ModelDef> {
42
42
  /** The constructor args R3F builds the mesh from; a frozen snapshot, never mutated. */
43
43
  readonly args: ModelMeshArgs;
44
44
  /** Which kind of member this container holds, and so which render list its mesh draws from. */
@@ -50,7 +50,6 @@ export declare class ModelContainer extends SlotContainer<null, InstancedMeshExt
50
50
  readonly meshMatrix: Matrix4;
51
51
  /** The model's bounds in plan units; every instance is fitted against them. */
52
52
  private readonly extents;
53
- private kindMismatchHandler;
54
53
  /**
55
54
  * Builds the bookkeeping for one model part.
56
55
  * @param extents - The model's own bounds, y-up, as `bakeGltf` left them.
@@ -74,21 +73,6 @@ export declare class ModelContainer extends SlotContainer<null, InstancedMeshExt
74
73
  * quietly appear to order this one.
75
74
  */
76
75
  setPaintOrder(): void;
77
- /**
78
- * Registers what to do when a member turns out to be the wrong kind. `Models` supplies a re-split;
79
- * `undefined` clears it.
80
- *
81
- * A method rather than an assignable field because the container is held in `useState`, and the
82
- * React Compiler rejects writing to a property of a state value.
83
- * @param handler - The re-split to run, or `undefined` to clear it.
84
- */
85
- setKindMismatchHandler(handler: (() => void) | undefined): void;
86
- /**
87
- * Reports that a member no longer matches {@link kind} — its `opacity` crossed 1 — so it is
88
- * drawing from a mesh whose material describes the wrong render list. Runs the registered handler,
89
- * if any; a container mounted outside `Models` has none and the report is simply dropped.
90
- */
91
- reportKindMismatch(): void;
92
76
  /**
93
77
  * Writes a def's placement into its slot: the model's extents fitted into `bounds`.
94
78
  *
@@ -30,7 +30,7 @@ export function modelKindOf(def) {
30
30
  * twenty copies of a chair are one draw call rather than twenty.
31
31
  *
32
32
  * Much simpler than a shape container. The geometry is the part's — shared, never per instance — so
33
- * there is no geometry cache and no capacity pre-scan, and `InstancedMeshExt` grows its own buffers,
33
+ * there is no geometry cache and no capacity pre-scan, and `InstancedMeshImpl` grows its own buffers,
34
34
  * so nothing here has to size anything. What is left is a slot per def and the transform each one
35
35
  * draws with.
36
36
  */
@@ -46,7 +46,6 @@ export class ModelContainer extends SlotContainer {
46
46
  meshMatrix = PLAN_FROM_GLTF;
47
47
  /** The model's bounds in plan units; every instance is fitted against them. */
48
48
  extents;
49
- kindMismatchHandler;
50
49
  /**
51
50
  * Builds the bookkeeping for one model part.
52
51
  * @param extents - The model's own bounds, y-up, as `bakeGltf` left them.
@@ -78,25 +77,6 @@ export class ModelContainer extends SlotContainer {
78
77
  setPaintOrder() {
79
78
  // Nothing: the depth buffer orders models, and a layer's parts are separate meshes regardless.
80
79
  }
81
- /**
82
- * Registers what to do when a member turns out to be the wrong kind. `Models` supplies a re-split;
83
- * `undefined` clears it.
84
- *
85
- * A method rather than an assignable field because the container is held in `useState`, and the
86
- * React Compiler rejects writing to a property of a state value.
87
- * @param handler - The re-split to run, or `undefined` to clear it.
88
- */
89
- setKindMismatchHandler(handler) {
90
- this.kindMismatchHandler = handler;
91
- }
92
- /**
93
- * Reports that a member no longer matches {@link kind} — its `opacity` crossed 1 — so it is
94
- * drawing from a mesh whose material describes the wrong render list. Runs the registered handler,
95
- * if any; a container mounted outside `Models` has none and the report is simply dropped.
96
- */
97
- reportKindMismatch() {
98
- this.kindMismatchHandler?.();
99
- }
100
80
  /**
101
81
  * Writes a def's placement into its slot: the model's extents fitted into `bounds`.
102
82
  *
@@ -1,6 +1,6 @@
1
1
  import { type Shape } from '@expofp/geometry';
2
2
  import { type BufferGeometry, type Intersection } from 'three';
3
- import { type BatchedMeshExt } from '../../core/batch/BatchedMesh';
3
+ import { type BatchedMeshImpl } from '../../core/batch/BatchedMesh';
4
4
  import { type RenderableDef, type ShapeDef } from '../../types/defs';
5
5
  import { SlotContainer } from '../containers';
6
6
  /**
@@ -21,7 +21,7 @@ export declare const SHAPE_KINDS: readonly ['planar', 'solid', 'translucent'];
21
21
  * One value rather than the `solid`/`translucent` pair it replaces. The pair could express a
22
22
  * translucent-but-flat batch, which nothing partitions for and no material describes, and it split
23
23
  * one fact across a field each reader needed and a field none did. This is also the "kind" that
24
- * {@link ShapeContainer.reportKindMismatch} and its handler have always named.
24
+ * {@link SlotContainer.reportKindMismatch} and its handler have always named.
25
25
  *
26
26
  * Derived from {@link SHAPE_KINDS} rather than listed again, so the two cannot drift.
27
27
  */
@@ -67,7 +67,7 @@ export declare function shapeKindOf(def: ShapeDef): ShapeKind;
67
67
  * which of its geometry ids each template was given. Building the templates is not its work either;
68
68
  * they come from {@link shapeGeometry}, which caches them across every container.
69
69
  */
70
- export declare class ShapeContainer extends SlotContainer<BufferGeometry, BatchedMeshExt, ShapeDef> {
70
+ export declare class ShapeContainer extends SlotContainer<BufferGeometry, BatchedMeshImpl, ShapeDef> {
71
71
  /**
72
72
  * The mesh's constructor args, sized to hold the defs the container was created with exactly.
73
73
  * Passed as `<batchedMesh args={container.capacity}>`; R3F diffs `args` element-wise and a change
@@ -96,7 +96,6 @@ export declare class ShapeContainer extends SlotContainer<BufferGeometry, Batche
96
96
  * going to do anyway.
97
97
  */
98
98
  private readonly target;
99
- private kindMismatchHandler;
100
99
  /**
101
100
  * Builds a shape layer's container, sized to hold `defs` exactly so a layer that mounts full never
102
101
  * reallocates. The mesh itself is R3F's: the component renders `<batchedMesh>` from
@@ -130,22 +129,6 @@ export declare class ShapeContainer extends SlotContainer<BufferGeometry, Batche
130
129
  * @param defs - The shapes this container is about to hold.
131
130
  */
132
131
  reserve(defs: readonly ShapeDef[]): void;
133
- /**
134
- * Registers what to do when a member turns out to be the wrong kind. `Shapes` supplies a re-split;
135
- * `undefined` clears it.
136
- *
137
- * A method rather than an assignable field because the container is held in `useState`, and the
138
- * React Compiler rejects writing to a property of a state value ("This value cannot be modified").
139
- * Calling a method is fine, which is how {@link reserve} already mutates.
140
- * @param handler - The re-split to run, or `undefined` to clear it.
141
- */
142
- setKindMismatchHandler(handler: (() => void) | undefined): void;
143
- /**
144
- * Reports that a member no longer matches {@link kind} — its color crossed alpha 1, or its shape
145
- * was replaced with one of another kind — so it is drawing from the wrong batch. Runs the registered handler, if any;
146
- * a container mounted outside `Shapes` has none and the report is simply dropped.
147
- */
148
- reportKindMismatch(): void;
149
132
  /**
150
133
  * A batched mesh reports the instance it hit as `batchId`, which is the slot this container
151
134
  * allocated.
@@ -84,7 +84,6 @@ export class ShapeContainer extends SlotContainer {
84
84
  * going to do anyway.
85
85
  */
86
86
  target;
87
- kindMismatchHandler;
88
87
  /**
89
88
  * Builds a shape layer's container, sized to hold `defs` exactly so a layer that mounts full never
90
89
  * reallocates. The mesh itself is R3F's: the component renders `<batchedMesh>` from
@@ -152,26 +151,6 @@ export class ShapeContainer extends SlotContainer {
152
151
  this.target.vertices = vertices;
153
152
  this.target.indices = indices;
154
153
  }
155
- /**
156
- * Registers what to do when a member turns out to be the wrong kind. `Shapes` supplies a re-split;
157
- * `undefined` clears it.
158
- *
159
- * A method rather than an assignable field because the container is held in `useState`, and the
160
- * React Compiler rejects writing to a property of a state value ("This value cannot be modified").
161
- * Calling a method is fine, which is how {@link reserve} already mutates.
162
- * @param handler - The re-split to run, or `undefined` to clear it.
163
- */
164
- setKindMismatchHandler(handler) {
165
- this.kindMismatchHandler = handler;
166
- }
167
- /**
168
- * Reports that a member no longer matches {@link kind} — its color crossed alpha 1, or its shape
169
- * was replaced with one of another kind — so it is drawing from the wrong batch. Runs the registered handler, if any;
170
- * a container mounted outside `Shapes` has none and the report is simply dropped.
171
- */
172
- reportKindMismatch() {
173
- this.kindMismatchHandler?.();
174
- }
175
154
  /**
176
155
  * A batched mesh reports the instance it hit as `batchId`, which is the slot this container
177
156
  * allocated.
@@ -1,12 +1,12 @@
1
1
  import { type Intersection } from 'three';
2
- import { type BatchedTextExt } from '../../core/text/BatchedText';
3
- import { TextExt } from '../../core/text/Text';
2
+ import { type BatchedTextImpl } from '../../core/text/BatchedText';
3
+ import { TextImpl } from '../../core/text/Text';
4
4
  import { type RenderableDef, type TextDef } from '../../types/defs';
5
5
  import { SlotContainer } from '../containers';
6
- /** One def's members: a `TextExt` per line, and the batch slot each of them occupies. */
6
+ /** One def's members: a `TextImpl` per line, and the batch slot each of them occupies. */
7
7
  export interface LineGroup {
8
8
  /** The members, in the def's line order. */
9
- readonly texts: readonly TextExt[];
9
+ readonly texts: readonly TextImpl[];
10
10
  /** Each member's batch slot, index-parallel to {@link texts}. */
11
11
  readonly slots: readonly number[];
12
12
  }
@@ -14,7 +14,7 @@ export interface LineGroup {
14
14
  * One text layer's bookkeeping: a group of members per def, and the paint order across them.
15
15
  *
16
16
  * The slot a def claims here is a **group**, not a batch member — a `TextDef` holds an array of
17
- * lines and each line is its own `TextExt`. That is the one place this differs from the shape and
17
+ * lines and each line is its own `TextImpl`. That is the one place this differs from the shape and
18
18
  * image containers, and it falls out of the def type rather than being a choice: the lines of one
19
19
  * def are laid out together (a centered block needs every line's height before it can place the
20
20
  * first), so they cannot be independent instances.
@@ -27,7 +27,7 @@ export interface LineGroup {
27
27
  * draw list, so {@link applyOrder} hands the batch a rebuilt member list instead of labeling slots,
28
28
  * and the inherited `customSort` goes unused.
29
29
  */
30
- export declare class TextContainer extends SlotContainer<number, BatchedTextExt, TextDef> {
30
+ export declare class TextContainer extends SlotContainer<number, BatchedTextImpl, TextDef> {
31
31
  /** Groups by slot, with holes for released ones. */
32
32
  private readonly groups;
33
33
  private readonly freeGroups;
@@ -1,4 +1,4 @@
1
- import { TextExt } from '../../core/text/Text';
1
+ import { TextImpl } from '../../core/text/Text';
2
2
  import { sameSequence } from '../../utils/arrays';
3
3
  import { SlotContainer } from '../containers';
4
4
  import { dimOrdered, isDimmed } from '../materials/effects/color-dim';
@@ -7,7 +7,7 @@ import { LAYOUT_FONT_SIZE, LINE_HEIGHT } from './text-layout';
7
7
  * One text layer's bookkeeping: a group of members per def, and the paint order across them.
8
8
  *
9
9
  * The slot a def claims here is a **group**, not a batch member — a `TextDef` holds an array of
10
- * lines and each line is its own `TextExt`. That is the one place this differs from the shape and
10
+ * lines and each line is its own `TextImpl`. That is the one place this differs from the shape and
11
11
  * image containers, and it falls out of the def type rather than being a choice: the lines of one
12
12
  * def are laid out together (a centered block needs every line's height before it can place the
13
13
  * first), so they cannot be independent instances.
@@ -194,7 +194,7 @@ export class TextContainer extends SlotContainer {
194
194
  * @returns The member.
195
195
  */
196
196
  function makeMember() {
197
- const text = new TextExt();
197
+ const text = new TextImpl();
198
198
  text.fontSize = LAYOUT_FONT_SIZE;
199
199
  text.lineHeight = LINE_HEIGHT;
200
200
  // Wrapping is the floorplan's job: it measures and breaks lines itself, then hands over the
@@ -1,5 +1,5 @@
1
1
  import { type Rect } from '@expofp/geometry';
2
- import { type TextExt } from '../../core/text/Text';
2
+ import { type TextImpl } from '../../core/text/Text';
3
3
  import { type TextDef, type TextLineDef } from '../../types/defs';
4
4
  /**
5
5
  * The em size every member lays out at, fixed for its lifetime.
@@ -70,7 +70,7 @@ export declare function layoutText(def: TextDef): LaidOutLine[];
70
70
  * @param line - The line's local placement.
71
71
  * @param bounds - The def's bounds, supplying the rotation, center and elevation.
72
72
  */
73
- export declare function applyPlacement(text: TextExt, line: LaidOutLine, bounds: Rect): void;
73
+ export declare function applyPlacement(text: TextImpl, line: LaidOutLine, bounds: Rect): void;
74
74
  /**
75
75
  * The height one line's box occupies.
76
76
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expofp/renderer",
3
- "version": "3.35.0",
3
+ "version": "3.35.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/expofp/efp-app.git",
@@ -42,7 +42,7 @@
42
42
  "troika-three-text": "^0.52.5",
43
43
  "tslib": "^2.3.0",
44
44
  "webgl-memory": "^1.1.3",
45
- "@expofp/geometry": "3.35.0"
45
+ "@expofp/geometry": "3.35.1"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@react-three/test-renderer": "^9.1.0",