@ifc-lite/renderer 3.0.1 → 3.2.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 (111) hide show
  1. package/README.md +22 -0
  2. package/dist/appearance-preview.d.ts +2 -0
  3. package/dist/appearance-preview.d.ts.map +1 -1
  4. package/dist/appearance-preview.js +4 -0
  5. package/dist/appearance-preview.js.map +1 -1
  6. package/dist/camera-animation-immediate.d.ts +5 -0
  7. package/dist/camera-animation-immediate.d.ts.map +1 -0
  8. package/dist/camera-animation-immediate.js +16 -0
  9. package/dist/camera-animation-immediate.js.map +1 -0
  10. package/dist/camera-animation.d.ts +3 -9
  11. package/dist/camera-animation.d.ts.map +1 -1
  12. package/dist/camera-animation.js +14 -9
  13. package/dist/camera-animation.js.map +1 -1
  14. package/dist/device-recovery.d.ts +60 -0
  15. package/dist/device-recovery.d.ts.map +1 -0
  16. package/dist/device-recovery.js +153 -0
  17. package/dist/device-recovery.js.map +1 -0
  18. package/dist/device.d.ts +2 -0
  19. package/dist/device.d.ts.map +1 -1
  20. package/dist/device.js +12 -0
  21. package/dist/device.js.map +1 -1
  22. package/dist/gpu-upload-guard.d.ts +106 -0
  23. package/dist/gpu-upload-guard.d.ts.map +1 -0
  24. package/dist/gpu-upload-guard.js +102 -0
  25. package/dist/gpu-upload-guard.js.map +1 -0
  26. package/dist/index.d.ts +44 -21
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +156 -139
  29. package/dist/index.js.map +1 -1
  30. package/dist/instanced-override-color.d.ts +8 -0
  31. package/dist/instanced-override-color.d.ts.map +1 -1
  32. package/dist/instanced-override-color.js +10 -0
  33. package/dist/instanced-override-color.js.map +1 -1
  34. package/dist/merged-mesh-extract.d.ts.map +1 -1
  35. package/dist/merged-mesh-extract.js +5 -0
  36. package/dist/merged-mesh-extract.js.map +1 -1
  37. package/dist/mesh-entity-hosting.d.ts +14 -0
  38. package/dist/mesh-entity-hosting.d.ts.map +1 -0
  39. package/dist/mesh-entity-hosting.js +25 -0
  40. package/dist/mesh-entity-hosting.js.map +1 -0
  41. package/dist/model-translation.d.ts +39 -1
  42. package/dist/model-translation.d.ts.map +1 -1
  43. package/dist/model-translation.js +103 -16
  44. package/dist/model-translation.js.map +1 -1
  45. package/dist/picking-manager.d.ts +2 -1
  46. package/dist/picking-manager.d.ts.map +1 -1
  47. package/dist/picking-manager.js +11 -2
  48. package/dist/picking-manager.js.map +1 -1
  49. package/dist/reference-images.d.ts +2 -0
  50. package/dist/reference-images.d.ts.map +1 -1
  51. package/dist/reference-images.js +2 -0
  52. package/dist/reference-images.js.map +1 -1
  53. package/dist/renderer-overlays.d.ts +3 -0
  54. package/dist/renderer-overlays.d.ts.map +1 -1
  55. package/dist/renderer-overlays.js +13 -0
  56. package/dist/renderer-overlays.js.map +1 -1
  57. package/dist/renderer-symbolic-overlays.d.ts +1 -0
  58. package/dist/renderer-symbolic-overlays.d.ts.map +1 -1
  59. package/dist/renderer-symbolic-overlays.js +3 -0
  60. package/dist/renderer-symbolic-overlays.js.map +1 -1
  61. package/dist/scene-appearance-preview.d.ts +2 -0
  62. package/dist/scene-appearance-preview.d.ts.map +1 -1
  63. package/dist/scene-appearance-preview.js +9 -0
  64. package/dist/scene-appearance-preview.js.map +1 -1
  65. package/dist/scene-authored-owner.d.ts +10 -0
  66. package/dist/scene-authored-owner.d.ts.map +1 -1
  67. package/dist/scene-authored-owner.js +44 -5
  68. package/dist/scene-authored-owner.js.map +1 -1
  69. package/dist/scene-batch-rebuild.d.ts +18 -0
  70. package/dist/scene-batch-rebuild.d.ts.map +1 -0
  71. package/dist/scene-batch-rebuild.js +49 -0
  72. package/dist/scene-batch-rebuild.js.map +1 -0
  73. package/dist/scene-batch-upload.d.ts +7 -2
  74. package/dist/scene-batch-upload.d.ts.map +1 -1
  75. package/dist/scene-batch-upload.js +26 -1
  76. package/dist/scene-batch-upload.js.map +1 -1
  77. package/dist/scene-bucket-routing.d.ts +21 -0
  78. package/dist/scene-bucket-routing.d.ts.map +1 -0
  79. package/dist/scene-bucket-routing.js +44 -0
  80. package/dist/scene-bucket-routing.js.map +1 -0
  81. package/dist/scene-contents.d.ts +8 -0
  82. package/dist/scene-contents.d.ts.map +1 -1
  83. package/dist/scene-derived-batches.d.ts +84 -0
  84. package/dist/scene-derived-batches.d.ts.map +1 -0
  85. package/dist/scene-derived-batches.js +73 -0
  86. package/dist/scene-derived-batches.js.map +1 -0
  87. package/dist/scene-derived-mesh-provenance.d.ts +13 -0
  88. package/dist/scene-derived-mesh-provenance.d.ts.map +1 -0
  89. package/dist/scene-derived-mesh-provenance.js +30 -0
  90. package/dist/scene-derived-mesh-provenance.js.map +1 -0
  91. package/dist/scene-device-recovery.d.ts +103 -0
  92. package/dist/scene-device-recovery.d.ts.map +1 -0
  93. package/dist/scene-device-recovery.js +299 -0
  94. package/dist/scene-device-recovery.js.map +1 -0
  95. package/dist/scene-geometry.d.ts +1 -0
  96. package/dist/scene-geometry.d.ts.map +1 -1
  97. package/dist/scene-geometry.js +3 -23
  98. package/dist/scene-geometry.js.map +1 -1
  99. package/dist/scene-model-translation.d.ts +11 -1
  100. package/dist/scene-model-translation.d.ts.map +1 -1
  101. package/dist/scene-model-translation.js +22 -0
  102. package/dist/scene-model-translation.js.map +1 -1
  103. package/dist/scene-precision.d.ts +16 -0
  104. package/dist/scene-precision.d.ts.map +1 -0
  105. package/dist/scene-precision.js +73 -0
  106. package/dist/scene-precision.js.map +1 -0
  107. package/dist/scene.d.ts +46 -42
  108. package/dist/scene.d.ts.map +1 -1
  109. package/dist/scene.js +211 -208
  110. package/dist/scene.js.map +1 -1
  111. package/package.json +2 -2
@@ -0,0 +1,73 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ /** Quantization mode for a batch whose depth must match `sourceBatch`'s. */
5
+ export function inheritedQuantization(quantizedBatchesEnabled, sourceBatch) {
6
+ if (!quantizedBatchesEnabled)
7
+ return 'off';
8
+ // Source not built yet (mid-stream): nothing to inherit from, so decide like
9
+ // a base batch would. `Scene.finalizeStreaming*` re-applies the installed
10
+ // overrides once the buckets are built, so this choice never outlives them.
11
+ if (!sourceBatch)
12
+ return 'auto';
13
+ return sourceBatch.quantized ? 'required' : 'off';
14
+ }
15
+ /** Mutable copy of an installed override map, in `Scene.setColorOverrides` input shape. */
16
+ export function cloneOverrides(overrides) {
17
+ const copy = new Map();
18
+ for (const [id, c] of overrides)
19
+ copy.set(id, [c[0], c[1], c[2], c[3]]);
20
+ return copy;
21
+ }
22
+ /**
23
+ * Whether a non-streaming rebuild invalidated the installed overlays: a
24
+ * rebuilt bucket holding an overridden piece flipped f32↔quantized, or an
25
+ * overridden piece now lives in a different bucket than the one its overlay
26
+ * inherited from (`overlaySources`: piece → source bucket key at build time).
27
+ * Anything else — e.g. N meshes appended one by one into a bucket whose
28
+ * decision holds — leaves the overlays bit-coincident, so rebuilding them
29
+ * would only be quadratic churn.
30
+ */
31
+ export function overlaysInvalidatedBy(rebuilt, overlaySources) {
32
+ if (overlaySources.size === 0)
33
+ return false;
34
+ for (const { bucket, previousQuantized } of rebuilt) {
35
+ const flipped = (bucket.batchedMesh?.quantized !== undefined) !== previousQuantized;
36
+ for (const piece of bucket.meshData) {
37
+ const source = overlaySources.get(piece);
38
+ if (source !== undefined && (flipped || source !== bucket.key))
39
+ return true;
40
+ }
41
+ }
42
+ return false;
43
+ }
44
+ /**
45
+ * Group override pieces by `(source bucket, override colour)`.
46
+ *
47
+ * `sourceOf` resolves a piece to its owning bucket (key + built batch) or
48
+ * undefined when it is not bucketed (textured meshes, mid-stream pieces);
49
+ * `fallbackKey` then supplies a spatial key with the same cell/model shape
50
+ * so unbucketed pieces still group compactly. Fallback keys live in their
51
+ * own namespace: a bucket's key IS a base key, so an unbucketed piece must
52
+ * never share a group (and thus a `sourceBatch`) with a bucketed one.
53
+ */
54
+ export function groupOverridePieces(overrides, piecesOf, sourceOf, fallbackKey, colorKey) {
55
+ const groups = new Map();
56
+ for (const [expressId, color] of overrides) {
57
+ for (const piece of piecesOf(expressId) ?? []) {
58
+ const source = sourceOf(piece);
59
+ const key = `${source ? source.key : `unbucketed:${fallbackKey(piece)}`}:${colorKey(color)}`;
60
+ let group = groups.get(key);
61
+ if (!group) {
62
+ group = {
63
+ color: [color[0], color[1], color[2], color[3]], meshData: [],
64
+ sourceBatch: source?.batchedMesh ?? null, sourceKey: source?.key ?? null,
65
+ };
66
+ groups.set(key, group);
67
+ }
68
+ group.meshData.push(piece);
69
+ }
70
+ }
71
+ return groups;
72
+ }
73
+ //# sourceMappingURL=scene-derived-batches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-derived-batches.js","sourceRoot":"","sources":["../src/scene-derived-batches.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { MeshData } from '@ifc-lite/geometry';
2
+ import { ModelTranslations } from './model-translation.js';
3
+ /** Links transient extracted/merged geometry back to its bucket-owned source. */
4
+ export declare class DerivedMeshProvenance {
5
+ private sources;
6
+ sourceFor(meshData: MeshData): MeshData;
7
+ /** Resolve before placement so the returned object is the identity stored in
8
+ * Scene's live bucket reverse index, including after a model move/restore. */
9
+ placedSourceFor(meshData: MeshData, translations: ModelTranslations): MeshData;
10
+ extract(merged: MeshData, expressId: number): MeshData | undefined;
11
+ remember(derived: MeshData, source: MeshData): void;
12
+ }
13
+ //# sourceMappingURL=scene-derived-mesh-provenance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-derived-mesh-provenance.d.ts","sourceRoot":"","sources":["../src/scene-derived-mesh-provenance.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG3D,iFAAiF;AACjF,qBAAa,qBAAqB;IAChC,OAAO,CAAC,OAAO,CAAqC;IAEpD,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,QAAQ;IAOvC;kFAC8E;IAC9E,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,iBAAiB,GAAG,QAAQ;IAI9E,OAAO,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAMlE,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI;CAGpD"}
@@ -0,0 +1,30 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { extractEntityFromMergedMesh } from './merged-mesh-extract.js';
5
+ /** Links transient extracted/merged geometry back to its bucket-owned source. */
6
+ export class DerivedMeshProvenance {
7
+ sources = new WeakMap();
8
+ sourceFor(meshData) {
9
+ let source = meshData;
10
+ let parent;
11
+ while ((parent = this.sources.get(source)))
12
+ source = parent;
13
+ return source;
14
+ }
15
+ /** Resolve before placement so the returned object is the identity stored in
16
+ * Scene's live bucket reverse index, including after a model move/restore. */
17
+ placedSourceFor(meshData, translations) {
18
+ return translations.placeMesh(this.sourceFor(meshData));
19
+ }
20
+ extract(merged, expressId) {
21
+ const extracted = extractEntityFromMergedMesh(merged, expressId);
22
+ if (extracted)
23
+ this.sources.set(extracted, this.sourceFor(merged));
24
+ return extracted;
25
+ }
26
+ remember(derived, source) {
27
+ this.sources.set(derived, this.sourceFor(source));
28
+ }
29
+ }
30
+ //# sourceMappingURL=scene-derived-mesh-provenance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-derived-mesh-provenance.js","sourceRoot":"","sources":["../src/scene-derived-mesh-provenance.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAI/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAEvE,iFAAiF;AACjF,MAAM,OAAO,qBAAqB;IACxB,OAAO,GAAG,IAAI,OAAO,EAAsB,CAAC;IAEpD,SAAS,CAAC,QAAkB;QAC1B,IAAI,MAAM,GAAG,QAAQ,CAAC;QACtB,IAAI,MAA4B,CAAC;QACjC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAAE,MAAM,GAAG,MAAM,CAAC;QAC5D,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;kFAC8E;IAC9E,eAAe,CAAC,QAAkB,EAAE,YAA+B;QACjE,OAAO,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,CAAC,MAAgB,EAAE,SAAiB;QACzC,MAAM,SAAS,GAAG,2BAA2B,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACjE,IAAI,SAAS;YAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QACnE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,QAAQ,CAAC,OAAiB,EAAE,MAAgB;QAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACpD,CAAC;CACF"}
@@ -0,0 +1,103 @@
1
+ import type { MeshData } from '@ifc-lite/geometry';
2
+ import type { RenderPipeline } from './pipeline.js';
3
+ import type { BatchedMesh, Mesh } from './types.js';
4
+ import type { InstancedOccurrence, InstancedTemplateCpu, InstancedTemplateGPU } from './scene-instance-types.js';
5
+ import type { TexturedMesh } from './scene.js';
6
+ export interface RecoveryBucket {
7
+ key: string;
8
+ meshData: MeshData[];
9
+ batchedMesh: BatchedMesh | null;
10
+ vertexBytes: number;
11
+ }
12
+ interface WorldBox {
13
+ minX: number;
14
+ minY: number;
15
+ minZ: number;
16
+ maxX: number;
17
+ maxY: number;
18
+ maxZ: number;
19
+ }
20
+ export interface SceneRecoveryHost {
21
+ geometryReleased: boolean;
22
+ ephemeralStreamingMode: boolean;
23
+ finalizeInProgress: boolean;
24
+ streamingFragments: BatchedMesh[];
25
+ pendingBatchKeys: Set<string>;
26
+ appearanceController?: {
27
+ hasActiveDrafts(): boolean;
28
+ };
29
+ appearanceBuckets?: {
30
+ forget(): void;
31
+ };
32
+ authoredGeneration: number;
33
+ authoredPreparations: {
34
+ invalidate(): void;
35
+ };
36
+ meshes: Mesh[];
37
+ batchedMeshes: BatchedMesh[];
38
+ buckets: Map<string, RecoveryBucket>;
39
+ meshDataBucket: Map<MeshData, RecoveryBucket>;
40
+ activeBucketKey: Map<string, string>;
41
+ dirtyBuckets: Set<string>;
42
+ nextSplitId: number;
43
+ nextBatchId: number;
44
+ coldBuckets: Set<string>;
45
+ texturedMeshes: TexturedMesh[];
46
+ sharedTextures: Map<number, {
47
+ texture: GPUTexture;
48
+ refs: number;
49
+ }>;
50
+ rgbaTexturePool: {
51
+ clear(): void;
52
+ };
53
+ texturedDevice?: GPUDevice;
54
+ instancedTemplates: (InstancedTemplateGPU | undefined)[];
55
+ liveInstancedTemplates: InstancedTemplateGPU[];
56
+ instancedTemplateCpu: (InstancedTemplateCpu | undefined)[];
57
+ instancedEntityMap: Map<number, InstancedOccurrence[]>;
58
+ instanceSuppression: {
59
+ has(expressId: number): boolean;
60
+ };
61
+ instancedSelected: Set<number>;
62
+ instancedOverrideColors: ReadonlyMap<number, readonly [number, number, number, number]> | null;
63
+ instancedOverridden: Set<number>;
64
+ instancedHasTransparent: boolean;
65
+ instancedGhosted: Set<number>;
66
+ lastGhostAlpha: number;
67
+ instancedDevice?: GPUDevice;
68
+ cachedMaxBufferSize: number;
69
+ lastDrawnFrame: Map<number, number>;
70
+ residencyRestoreQueue: Set<string>;
71
+ meshDataMap: Map<number, MeshData[]>;
72
+ colorOverrides: ReadonlyMap<number, readonly [number, number, number, number]> | null;
73
+ appearanceAccessState?: unknown;
74
+ modelTranslations: {
75
+ registerDrawable<T>(drawable: T, modelIndex: number): T;
76
+ };
77
+ dropAllPartialCaches(): void;
78
+ destroyOverrideBatches(): void;
79
+ releaseTexturedMeshTexture(mesh: Pick<TexturedMesh, 'texture' | 'sharedTextureKey'>): void;
80
+ bindAppearanceAccess(device: GPUDevice, pipeline: RenderPipeline): unknown;
81
+ createBatchedMesh(meshes: MeshData[], color: [number, number, number, number], device: GPUDevice, pipeline: RenderPipeline, bucketKey?: string): BatchedMesh;
82
+ createTexturedMesh(mesh: MeshData, device: GPUDevice, pipeline: RenderPipeline): void;
83
+ setColorOverrides(colors: Map<number, [number, number, number, number]>, device: GPUDevice, pipeline: RenderPipeline): void;
84
+ writeInstanceFlags(device: GPUDevice, eid: number): void;
85
+ writeInstanceColor(device: GPUDevice, eid: number, color: readonly [number, number, number, number]): void;
86
+ writeOriginalInstanceColors(device: GPUDevice, eid: number, alpha: number): void;
87
+ unionInstancedWorldAabb(eid: number, view: DataView, offset: number, minX: number, minY: number, minZ: number, maxX: number, maxY: number, maxZ: number): WorldBox;
88
+ refreshLiveInstancedTemplates(): void;
89
+ }
90
+ export type SceneDeviceRecoveryPreparation = {
91
+ ok: true;
92
+ } | {
93
+ ok: false;
94
+ reason: 'cpu-geometry-released' | 'scene-not-settled' | 'unsupported-authored-meshes' | 'cold-restore-failed';
95
+ };
96
+ export declare function prepareSceneDeviceRecovery(host: SceneRecoveryHost): SceneDeviceRecoveryPreparation;
97
+ export declare function discardSceneGpuResourcesForRecovery(host: SceneRecoveryHost): void;
98
+ /** Split a newly hydrated cold bucket against the replacement adapter limit
99
+ * before any GPU upload. Each returned shell can then restore independently. */
100
+ export declare function repartitionHydratedRecoveryBucket(host: SceneRecoveryHost, key: string, bucket: RecoveryBucket, shell: BatchedMesh): string[];
101
+ export declare function restoreSceneGpuResourcesAfterRecovery(host: SceneRecoveryHost, device: GPUDevice, pipeline: RenderPipeline): void;
102
+ export {};
103
+ //# sourceMappingURL=scene-device-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-device-recovery.d.ts","sourceRoot":"","sources":["../src/scene-device-recovery.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,299 @@
1
+ /* This Source Code Form is subject to the terms of the Mozilla Public
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
+ import { destroyGpuResources, splitMeshDataForBufferLimit } from './scene-geometry.js';
5
+ import { cloneOverrides } from './scene-derived-batches.js';
6
+ import { foldOccurrenceWorldBox, INSTANCE_STRIDE_BYTES } from './instanced-render.js';
7
+ import { composeInstancedOverrideColor } from './instanced-override-color.js';
8
+ import { BATCH_CONSTANTS } from './constants.js';
9
+ import { createSceneBatchShell } from './scene-batch-upload.js';
10
+ function recoveryBlocker(host) {
11
+ if (host.geometryReleased || host.ephemeralStreamingMode) {
12
+ return { ok: false, reason: 'cpu-geometry-released' };
13
+ }
14
+ if (host.finalizeInProgress || host.streamingFragments.length > 0 || host.pendingBatchKeys.size > 0 ||
15
+ host.appearanceController?.hasActiveDrafts()) {
16
+ return { ok: false, reason: 'scene-not-settled' };
17
+ }
18
+ if (host.meshes.some((mesh) => !mesh.hydrated)) {
19
+ return { ok: false, reason: 'unsupported-authored-meshes' };
20
+ }
21
+ return null;
22
+ }
23
+ export function prepareSceneDeviceRecovery(host) {
24
+ const initialBlocker = recoveryBlocker(host);
25
+ if (initialBlocker)
26
+ return initialBlocker;
27
+ // Cold buckets already carry GPU-free shells and remain provider-restorable.
28
+ // Warming them here would defeat the host-residency budget during recovery.
29
+ return { ok: true };
30
+ }
31
+ export function discardSceneGpuResourcesForRecovery(host) {
32
+ // Fence detached authoring transactions before any old-device handle dies.
33
+ // Their commit validation will release the staged buffers instead of
34
+ // publishing them into the recovered scene.
35
+ host.authoredGeneration++;
36
+ host.authoredPreparations.invalidate();
37
+ const evicted = new Set();
38
+ for (const bucket of host.buckets.values()) {
39
+ if (bucket.batchedMesh?.gpuResident === false)
40
+ evicted.add(bucket.batchedMesh);
41
+ }
42
+ for (const mesh of host.meshes)
43
+ destroyGpuResources(mesh);
44
+ host.meshes = [];
45
+ for (const batch of host.batchedMeshes)
46
+ if (!evicted.has(batch))
47
+ destroyGpuResources(batch);
48
+ host.batchedMeshes = [...evicted];
49
+ for (const bucket of host.buckets.values()) {
50
+ if (!bucket.batchedMesh || !evicted.has(bucket.batchedMesh))
51
+ bucket.batchedMesh = null;
52
+ }
53
+ host.dropAllPartialCaches();
54
+ host.destroyOverrideBatches();
55
+ for (const mesh of host.texturedMeshes) {
56
+ mesh.vertexBuffer.destroy();
57
+ mesh.indexBuffer.destroy();
58
+ mesh.uniformBuffer.destroy();
59
+ host.releaseTexturedMeshTexture(mesh);
60
+ }
61
+ host.texturedMeshes = [];
62
+ for (const entry of host.sharedTextures.values())
63
+ entry.texture.destroy();
64
+ host.sharedTextures.clear();
65
+ host.rgbaTexturePool.clear();
66
+ host.texturedDevice = undefined;
67
+ for (const template of host.instancedTemplates) {
68
+ template?.vertexBuffer.destroy();
69
+ template?.indexBuffer.destroy();
70
+ template?.instanceBuffer.destroy();
71
+ }
72
+ host.instancedTemplates = new Array(host.instancedTemplateCpu.length);
73
+ host.liveInstancedTemplates = [];
74
+ host.instancedDevice = undefined;
75
+ host.cachedMaxBufferSize = 0;
76
+ host.lastDrawnFrame.clear();
77
+ host.residencyRestoreQueue.clear();
78
+ }
79
+ const bucketVertexBytes = (parts) => parts.reduce((sum, part) => sum + (part.positions.length / 3) * BATCH_CONSTANTS.BYTES_PER_VERTEX, 0);
80
+ function nextRecoveryBucketKey(host, base) {
81
+ let key;
82
+ do
83
+ key = `${base}#${host.nextSplitId++}`;
84
+ while (host.buckets.has(key));
85
+ return key;
86
+ }
87
+ /** Split a newly hydrated cold bucket against the replacement adapter limit
88
+ * before any GPU upload. Each returned shell can then restore independently. */
89
+ export function repartitionHydratedRecoveryBucket(host, key, bucket, shell) {
90
+ const chunks = splitMeshDataForBufferLimit(bucket.meshData, host.cachedMaxBufferSize);
91
+ if (chunks.length <= 1)
92
+ return [key];
93
+ const hash = key.lastIndexOf('#'), baseKey = hash >= 0 ? key.slice(0, hash) : key;
94
+ const shells = [], keys = [];
95
+ host.buckets.delete(key);
96
+ for (let index = 0; index < chunks.length; index++) {
97
+ const targetKey = nextRecoveryBucketKey(host, baseKey);
98
+ const parts = chunks[index];
99
+ const target = index === 0 ? bucket : { key: targetKey, meshData: [], batchedMesh: null, vertexBytes: 0 };
100
+ const nextShell = host.modelTranslations.registerDrawable(createSceneBatchShell(parts, shell, host.nextBatchId++, targetKey), parts[0].modelIndex ?? 0);
101
+ target.key = targetKey;
102
+ target.meshData = parts;
103
+ target.batchedMesh = nextShell;
104
+ target.vertexBytes = bucketVertexBytes(parts);
105
+ host.buckets.set(targetKey, target);
106
+ for (const part of parts)
107
+ host.meshDataBucket.set(part, target);
108
+ shells.push(nextShell);
109
+ keys.push(targetKey);
110
+ }
111
+ const shellIndex = host.batchedMeshes.indexOf(shell);
112
+ if (shellIndex >= 0)
113
+ host.batchedMeshes.splice(shellIndex, 1, ...shells);
114
+ else
115
+ host.batchedMeshes.push(...shells);
116
+ host.lastDrawnFrame.delete(shell.id);
117
+ host.activeBucketKey.set(baseKey, keys.at(-1));
118
+ host.appearanceBuckets?.forget();
119
+ return keys;
120
+ }
121
+ function restoreFlatBuckets(host, device, pipeline) {
122
+ const maxBufferSize = Math.floor((device.limits?.maxBufferSize ?? BATCH_CONSTANTS.FALLBACK_MAX_BUFFER_SIZE) *
123
+ BATCH_CONSTANTS.BUFFER_SIZE_SAFETY_FACTOR);
124
+ host.cachedMaxBufferSize = maxBufferSize;
125
+ const restored = [];
126
+ host.batchedMeshes = restored;
127
+ let repartitioned = false;
128
+ // Recovery can repartition and replace entries, so iterate a stable snapshot.
129
+ const originalBuckets = Array.from(host.buckets);
130
+ for (const [originalKey, bucket] of originalBuckets) {
131
+ if (bucket.meshData.length === 0) {
132
+ if (bucket.batchedMesh?.gpuResident === false)
133
+ restored.push(bucket.batchedMesh);
134
+ continue;
135
+ }
136
+ const chunks = splitMeshDataForBufferLimit(bucket.meshData, maxBufferSize);
137
+ if (chunks.length === 1) {
138
+ if (bucket.batchedMesh?.gpuResident === false) {
139
+ restored.push(bucket.batchedMesh);
140
+ }
141
+ else {
142
+ const batch = host.createBatchedMesh(chunks[0], chunks[0][0].color, device, pipeline, originalKey);
143
+ bucket.batchedMesh = batch;
144
+ restored.push(batch);
145
+ }
146
+ continue;
147
+ }
148
+ repartitioned = true;
149
+ const evicted = bucket.batchedMesh?.gpuResident === false;
150
+ const evictedShell = bucket.batchedMesh;
151
+ const dirty = host.dirtyBuckets.has(originalKey);
152
+ const hash = originalKey.lastIndexOf('#');
153
+ const baseKey = hash >= 0 ? originalKey.slice(0, hash) : originalKey;
154
+ const staged = [];
155
+ try {
156
+ for (const parts of chunks) {
157
+ const key = nextRecoveryBucketKey(host, baseKey);
158
+ const batch = evicted
159
+ ? host.modelTranslations.registerDrawable(createSceneBatchShell(parts, evictedShell, host.nextBatchId++, key), parts[0].modelIndex ?? 0)
160
+ : host.createBatchedMesh(parts, parts[0].color, device, pipeline, key);
161
+ staged.push({ key, parts, batch });
162
+ }
163
+ }
164
+ catch (error) {
165
+ // None of the staged batches is reachable from the scene yet, so the
166
+ // outer recovery cleanup cannot see it. Release successful allocations
167
+ // here and leave the original CPU bucket intact for the automatic retry.
168
+ if (!evicted)
169
+ for (const entry of staged)
170
+ destroyGpuResources(entry.batch);
171
+ throw error;
172
+ }
173
+ // Commit only after every replacement exists. Until this point the source
174
+ // bucket and every meshDataBucket edge still describe the complete model.
175
+ host.buckets.delete(originalKey);
176
+ host.dirtyBuckets.delete(originalKey);
177
+ for (let index = 0; index < staged.length; index++) {
178
+ const { key, parts, batch } = staged[index];
179
+ const target = index === 0 ? bucket : { key, meshData: [], batchedMesh: null, vertexBytes: 0 };
180
+ target.key = key;
181
+ target.meshData = parts;
182
+ target.vertexBytes = bucketVertexBytes(parts);
183
+ target.batchedMesh = batch;
184
+ host.buckets.set(key, target);
185
+ for (const part of parts)
186
+ host.meshDataBucket.set(part, target);
187
+ if (dirty)
188
+ host.dirtyBuckets.add(key);
189
+ restored.push(batch);
190
+ }
191
+ host.activeBucketKey.set(baseKey, staged.at(-1).key);
192
+ }
193
+ if (repartitioned)
194
+ host.appearanceBuckets?.forget();
195
+ }
196
+ function restoreInstancedTemplates(host, device) {
197
+ host.instancedDevice = device;
198
+ host.instancedTemplates = new Array(host.instancedTemplateCpu.length);
199
+ for (let slot = 0; slot < host.instancedTemplateCpu.length; slot++) {
200
+ const cpu = host.instancedTemplateCpu[slot];
201
+ if (!cpu)
202
+ continue;
203
+ let vertexBuffer, indexBuffer, instanceBuffer;
204
+ try {
205
+ const vertexData = new ArrayBuffer((cpu.positions.length / 3) * 28);
206
+ const floats = new Float32Array(vertexData);
207
+ for (let i = 0; i < cpu.positions.length / 3; i++) {
208
+ const offset = i * 7;
209
+ floats[offset] = cpu.positions[i * 3];
210
+ floats[offset + 1] = cpu.positions[i * 3 + 1];
211
+ floats[offset + 2] = cpu.positions[i * 3 + 2];
212
+ floats[offset + 3] = cpu.normals[i * 3] ?? 0;
213
+ floats[offset + 4] = cpu.normals[i * 3 + 1] ?? 0;
214
+ floats[offset + 5] = cpu.normals[i * 3 + 2] ?? 0;
215
+ }
216
+ vertexBuffer = device.createBuffer({ size: vertexData.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST, mappedAtCreation: true });
217
+ new Uint8Array(vertexBuffer.getMappedRange()).set(new Uint8Array(vertexData));
218
+ vertexBuffer.unmap();
219
+ indexBuffer = device.createBuffer({ size: cpu.indices.byteLength, usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST, mappedAtCreation: true });
220
+ new Uint32Array(indexBuffer.getMappedRange()).set(cpu.indices);
221
+ indexBuffer.unmap();
222
+ instanceBuffer = device.createBuffer({ size: cpu.instanceData.byteLength, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST, mappedAtCreation: true });
223
+ new Uint8Array(instanceBuffer.getMappedRange()).set(new Uint8Array(cpu.instanceData));
224
+ instanceBuffer.unmap();
225
+ host.instancedTemplates[slot] = {
226
+ modelIndex: cpu.modelIndex, vertexBuffer, indexBuffer, indexCount: cpu.indices.length,
227
+ instanceBuffer, instanceCount: cpu.instanceData.byteLength / INSTANCE_STRIDE_BYTES,
228
+ bounds: null, maxOccRadius: 0, selectedCount: 0,
229
+ };
230
+ }
231
+ catch (error) {
232
+ vertexBuffer?.destroy();
233
+ indexBuffer?.destroy();
234
+ instanceBuffer?.destroy();
235
+ throw error;
236
+ }
237
+ }
238
+ for (const [eid, occurrences] of host.instancedEntityMap) {
239
+ if (host.instanceSuppression.has(eid))
240
+ continue;
241
+ for (const occurrence of occurrences) {
242
+ const cpu = host.instancedTemplateCpu[occurrence.templateIndex];
243
+ const template = host.instancedTemplates[occurrence.templateIndex];
244
+ if (!cpu || !template || !Number.isFinite(cpu.localMin[0]))
245
+ continue;
246
+ const world = host.unionInstancedWorldAabb(eid, new DataView(cpu.instanceData), occurrence.byteOffset, cpu.localMin[0], cpu.localMin[1], cpu.localMin[2], cpu.localMax[0], cpu.localMax[1], cpu.localMax[2]);
247
+ foldOccurrenceWorldBox(template, world);
248
+ if (host.instancedSelected.has(eid))
249
+ template.selectedCount++;
250
+ }
251
+ }
252
+ host.refreshLiveInstancedTemplates();
253
+ }
254
+ function hasRenderableTexture(mesh) {
255
+ return Boolean(mesh.uvs) && Boolean(mesh.texture || (mesh.textureRef && mesh.textureBitmap));
256
+ }
257
+ function restoreInstancedAppearance(host, device) {
258
+ for (const eid of host.instancedEntityMap.keys()) {
259
+ host.writeInstanceFlags(device, eid);
260
+ const override = host.instancedOverrideColors?.get(eid);
261
+ if (override) {
262
+ host.writeInstanceColor(device, eid, composeInstancedOverrideColor(override, host.instancedGhosted.has(eid), host.lastGhostAlpha));
263
+ }
264
+ else if (host.instancedGhosted.has(eid)) {
265
+ host.writeOriginalInstanceColors(device, eid, host.lastGhostAlpha);
266
+ }
267
+ }
268
+ }
269
+ export function restoreSceneGpuResourcesAfterRecovery(host, device, pipeline) {
270
+ try {
271
+ if (host.appearanceAccessState)
272
+ host.bindAppearanceAccess(device, pipeline);
273
+ restoreFlatBuckets(host, device, pipeline);
274
+ const textured = new Set();
275
+ for (const pieces of host.meshDataMap.values()) {
276
+ for (const piece of pieces)
277
+ if (hasRenderableTexture(piece))
278
+ textured.add(piece);
279
+ }
280
+ for (const piece of textured)
281
+ host.createTexturedMesh(piece, device, pipeline);
282
+ restoreInstancedTemplates(host, device);
283
+ if (host.colorOverrides) {
284
+ const instanced = host.instancedOverrideColors;
285
+ const overridden = host.instancedOverridden;
286
+ const transparent = host.instancedHasTransparent;
287
+ host.setColorOverrides(cloneOverrides(host.colorOverrides), device, pipeline);
288
+ host.instancedOverrideColors = instanced;
289
+ host.instancedOverridden = overridden;
290
+ host.instancedHasTransparent = transparent;
291
+ }
292
+ restoreInstancedAppearance(host, device);
293
+ }
294
+ catch (error) {
295
+ discardSceneGpuResourcesForRecovery(host);
296
+ throw error;
297
+ }
298
+ }
299
+ //# sourceMappingURL=scene-device-recovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-device-recovery.js","sourceRoot":"","sources":["../src/scene-device-recovery.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import type { MeshData } from '@ifc-lite/geometry';
8
8
  import type { BoundingBox } from './scene-raycaster.js';
9
+ export { originPreservesTriangleTopology, topologySafeBatchOrigin } from './scene-precision.js';
9
10
  /** The subset of `MeshData` a world-space AABB needs. */
10
11
  export interface AabbPiece {
11
12
  positions: Float32Array;
@@ -1 +1 @@
1
- {"version":3,"file":"scene-geometry.d.ts","sourceRoot":"","sources":["../src/scene-geometry.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,yDAAyD;AACzD,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,GAAG,WAAW,GAAG,IAAI,CAkChG;AAKD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAAG,MAAM,CAStE;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,CAAC,EAAE;IAAE,YAAY,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,SAAS,CAAC;IAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IAAC,eAAe,CAAC,EAAE,SAAS,CAAA;CAAE,GAC7G,IAAI,CAKN;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,QAAQ,EAAE,EASzB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GACtC;IACD,UAAU,EAAE,YAAY,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE;QAAE,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IACzE;;qEAEiE;IACjE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CAsGA;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,QAAQ,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,QAAQ,EAAE,EAAE,CA6C1G;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAC7B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GACpF,WAAW,GAAG,IAAI,CAMpB"}
1
+ {"version":3,"file":"scene-geometry.d.ts","sourceRoot":"","sources":["../src/scene-geometry.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAEhG,yDAAyD;AACzD,MAAM,WAAW,SAAS;IACxB,SAAS,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,GAAG,WAAW,GAAG,IAAI,CAkChG;AAKD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAAG,MAAM,CAStE;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEtE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,CAAC,EAAE;IAAE,YAAY,EAAE,SAAS,CAAC;IAAC,WAAW,EAAE,SAAS,CAAC;IAAC,aAAa,CAAC,EAAE,SAAS,CAAC;IAAC,eAAe,CAAC,EAAE,SAAS,CAAA;CAAE,GAC7G,IAAI,CAKN;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,QAAQ,EAAE,EASzB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GACtC;IACD,UAAU,EAAE,YAAY,CAAC;IACzB,OAAO,EAAE,WAAW,CAAC;IACrB,MAAM,EAAE;QAAE,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IACzE;;qEAEiE;IACjE,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC,CA0FA;AAED;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,QAAQ,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,QAAQ,EAAE,EAAE,CA6C1G;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAC7B,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,GACpF,WAAW,GAAG,IAAI,CAMpB"}
@@ -2,6 +2,8 @@
2
2
  * License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
4
  import { BATCH_CONSTANTS } from './constants.js';
5
+ import { worldBounds } from './scene-precision.js';
6
+ export { originPreservesTriangleTopology, topologySafeBatchOrigin } from './scene-precision.js';
5
7
  /**
6
8
  * World-space AABB over an entity's mesh pieces, or `null` when they contain
7
9
  * no vertex a box can be built from (issue #2480).
@@ -152,29 +154,7 @@ forcedOrigin) {
152
154
  // magnitudes small (≈ half the batch's spatial spread) regardless of the
153
155
  // model's world placement — which is what prevents f32 fan collapse. A mesh
154
156
  // without an origin contributes its absolute positions (legacy no-op shift).
155
- let minX = Infinity, minY = Infinity, minZ = Infinity;
156
- let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
157
- for (const mesh of meshDataArray) {
158
- const p = mesh.positions;
159
- const ox = mesh.origin ? mesh.origin[0] : 0;
160
- const oy = mesh.origin ? mesh.origin[1] : 0;
161
- const oz = mesh.origin ? mesh.origin[2] : 0;
162
- for (let i = 0; i < p.length; i += 3) {
163
- const x = p[i] + ox, y = p[i + 1] + oy, z = p[i + 2] + oz;
164
- if (x < minX)
165
- minX = x;
166
- if (y < minY)
167
- minY = y;
168
- if (z < minZ)
169
- minZ = z;
170
- if (x > maxX)
171
- maxX = x;
172
- if (y > maxY)
173
- maxY = y;
174
- if (z > maxZ)
175
- maxZ = z;
176
- }
177
- }
157
+ const { minX, minY, minZ, maxX, maxY, maxZ } = worldBounds(meshDataArray);
178
158
  // Prefer the caller's shared scene origin (consistent across all batches → no
179
159
  // seam z-fight); fall back to this batch's own world bbox centre.
180
160
  const batchOrigin = forcedOrigin