@ifc-lite/renderer 1.40.0 → 1.41.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.
@@ -31,6 +31,22 @@ export declare class PickingManager {
31
31
  * Update the picker reference (e.g., after init)
32
32
  */
33
33
  setPicker(picker: Picker | null): void;
34
+ /**
35
+ * Prepare batched geometry for a GPU pick pass, shared by `pick()` and
36
+ * `pickRect()`.
37
+ *
38
+ * Returns `'cpu'` when the caller must fall back to a CPU test — either JS
39
+ * geometry data was released, or hydrating an individual mesh per visible
40
+ * piece would exceed the pick-mesh budget. Returns `'gpu'` after hydrating
41
+ * whatever was missing, so a following `scene.getMeshes()` covers every
42
+ * visible entity.
43
+ *
44
+ * Both pick paths MUST route through this. `pickRect` used to read
45
+ * `scene.getMeshes()` directly, which on a batched model is empty or
46
+ * partial, so rectangle select returned an empty set no matter how many
47
+ * elements the rect covered (#1904).
48
+ */
49
+ private prepareBatchedPick;
34
50
  /**
35
51
  * Pick object at screen coordinates
36
52
  * Respects visibility filtering so users can only select visible elements
@@ -51,11 +67,23 @@ export declare class PickingManager {
51
67
  * filtered (per-asset visibility is binary and the asset count is
52
68
  * tiny).
53
69
  *
54
- * Limitations: skips the CPU-raycast and dynamic-mesh-creation
55
- * fallbacks that `pick()` uses for very large batched models, so
56
- * rect pick may miss entities whose individual meshes haven't been
57
- * hydrated. Acceptable for an MVP rect select is a power-user
58
- * tool and the user can fall back to single-click pick.
70
+ * Batched models take the same route as `pick()`: hydrate the
71
+ * missing individual meshes when that is affordable, otherwise fall
72
+ * back to `Scene.selectRect`, which over-selects relative to the
73
+ * pixel-exact GPU pass in three ways: it is bounding-box granular
74
+ * (a rect over empty space inside an element's bounds selects it),
75
+ * it has no depth test (occluded entities are selected), and it
76
+ * drops a section-planed or cropped entity only when the whole box
77
+ * is clipped away, where the pick shader discards per fragment.
78
+ * Hidden and isolation filtering do apply there. Reading
79
+ * `scene.getMeshes()` unconditionally is what made this return an
80
+ * empty set on every batched model (#1904).
81
+ *
82
+ * Point clouds never depend on mesh hydration — splats render into
83
+ * the pick pass on their own — so the CPU branch still runs the GPU
84
+ * pass for them and unions the two results. Skipping it would drop
85
+ * point selection on any mixed scene big enough to miss the
86
+ * pick-mesh budget.
59
87
  */
60
88
  pickRect(x0: number, y0: number, x1: number, y1: number, options?: PickOptions, clip?: PickClipState | null): Promise<Set<number>>;
61
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"picking-manager.d.ts","sourceRoot":"","sources":["../src/picking-manager.ts"],"names":[],"mappings":"AAIA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAC5B;IAAE,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAChE,IAAI,CAAC;AAET,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,oBAAoB,CAA+B;IAC3D,OAAO,CAAC,iBAAiB,CAAkC;gBAGvD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,MAAM,EAAE,iBAAiB,EACzB,oBAAoB,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI;IAStD,+EAA+E;IAC/E,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAI9D;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAItC;;;;;;;OAOG;IACG,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA6JhH;;;;;;;;;;;;;;;;OAgBG;IACG,QAAQ,CACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,WAAW,EACrB,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CA8B1B"}
1
+ {"version":3,"file":"picking-manager.d.ts","sourceRoot":"","sources":["../src/picking-manager.ts"],"names":[],"mappings":"AAIA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,MAC5B;IAAE,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,GAChE,IAAI,CAAC;AAET,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,oBAAoB,CAA+B;IAC3D,OAAO,CAAC,iBAAiB,CAAkC;gBAGvD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,MAAM,EAAE,iBAAiB,EACzB,oBAAoB,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI;IAStD,+EAA+E;IAC/E,oBAAoB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,GAAG,IAAI;IAI9D;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAItC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,kBAAkB;IAoF1B;;;;;;;OAOG;IACG,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAmEhH;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,QAAQ,CACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,OAAO,CAAC,EAAE,WAAW,EACrB,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;CAsF1B"}
@@ -25,6 +25,99 @@ export class PickingManager {
25
25
  setPicker(picker) {
26
26
  this.picker = picker;
27
27
  }
28
+ /**
29
+ * Prepare batched geometry for a GPU pick pass, shared by `pick()` and
30
+ * `pickRect()`.
31
+ *
32
+ * Returns `'cpu'` when the caller must fall back to a CPU test — either JS
33
+ * geometry data was released, or hydrating an individual mesh per visible
34
+ * piece would exceed the pick-mesh budget. Returns `'gpu'` after hydrating
35
+ * whatever was missing, so a following `scene.getMeshes()` covers every
36
+ * visible entity.
37
+ *
38
+ * Both pick paths MUST route through this. `pickRect` used to read
39
+ * `scene.getMeshes()` directly, which on a batched model is empty or
40
+ * partial, so rectangle select returned an empty set no matter how many
41
+ * elements the rect covered (#1904).
42
+ */
43
+ prepareBatchedPick(options) {
44
+ const batchedMeshes = this.scene.getBatchedMeshes();
45
+ // Nothing batched: every mesh is already individually hydrated.
46
+ if (batchedMeshes.length === 0)
47
+ return 'gpu';
48
+ if (this.scene.isGeometryDataReleased())
49
+ return 'cpu';
50
+ // Collect every pickable expressId. We use the scene's authoritative
51
+ // mesh-data id set rather than each batch's `expressIds`, because a batch
52
+ // only records the PRIMARY expressId of each merged piece. When a door or
53
+ // window is colour-fused into a batch keyed by its host wall / opening,
54
+ // the filler's id lives only in the per-vertex entityIds (registered in
55
+ // meshDataMap by Scene.addMeshData). Reading batch.expressIds alone would
56
+ // skip the filler, so under isolation its mesh is never hydrated and
57
+ // pick() returns null (#1358).
58
+ const expressIds = new Set(this.scene.getAllMeshDataExpressIds());
59
+ // Track how many individual mesh pieces already exist for each (expressId:modelIndex).
60
+ // Multi-piece elements (windows/doors with submeshes) need all pieces for reliable picking.
61
+ const existingPieceCounts = new Map();
62
+ for (const mesh of this.scene.getMeshes()) {
63
+ const key = `${mesh.expressId}:${mesh.modelIndex ?? 'any'}`;
64
+ existingPieceCounts.set(key, (existingPieceCounts.get(key) ?? 0) + 1);
65
+ }
66
+ // Build required piece counts from MeshData for all visible entities.
67
+ const requiredPieceCounts = new Map();
68
+ const visibleExpressIds = [];
69
+ for (const expressId of expressIds) {
70
+ if (options?.hiddenIds?.has(expressId))
71
+ continue;
72
+ if (options?.isolatedIds !== null && options?.isolatedIds !== undefined && !options.isolatedIds.has(expressId))
73
+ continue;
74
+ visibleExpressIds.push(expressId);
75
+ const pieces = this.scene.getMeshDataPieces(expressId);
76
+ if (!pieces)
77
+ continue;
78
+ for (const piece of pieces) {
79
+ const key = `${piece.expressId}:${piece.modelIndex ?? 'any'}`;
80
+ requiredPieceCounts.set(key, (requiredPieceCounts.get(key) ?? 0) + 1);
81
+ }
82
+ }
83
+ // Count how many meshes we'd need to create for full GPU picking
84
+ // For multi-model and multi-piece elements, count missing piece instances per key.
85
+ let toCreate = 0;
86
+ for (const [key, requiredCount] of requiredPieceCounts) {
87
+ const existingCount = existingPieceCounts.get(key) ?? 0;
88
+ if (requiredCount > existingCount) {
89
+ toCreate += requiredCount - existingCount;
90
+ }
91
+ }
92
+ // PERFORMANCE: fall back to CPU for large models instead of creating GPU meshes.
93
+ // GPU picking requires individual mesh buffers; for 60K+ elements this is too slow.
94
+ // The CPU paths use bounding boxes - no GPU buffers needed.
95
+ const MAX_PICK_MESH_CREATION = 500;
96
+ if (toCreate > MAX_PICK_MESH_CREATION || (visibleExpressIds.length > 0 && requiredPieceCounts.size === 0)) {
97
+ return 'cpu';
98
+ }
99
+ // For smaller models, create GPU meshes for picking
100
+ // Only create meshes for VISIBLE elements (not hidden, and either no isolation or in isolated set)
101
+ // For multi-model support: create meshes for ALL (expressId, modelIndex) pairs
102
+ const baselineExistingCounts = new Map(existingPieceCounts);
103
+ const seenOrdinalsByKey = new Map();
104
+ for (const expressId of visibleExpressIds) {
105
+ const pieces = this.scene.getMeshDataPieces(expressId);
106
+ if (pieces) {
107
+ for (const piece of pieces) {
108
+ const meshKey = `${piece.expressId}:${piece.modelIndex ?? 'any'}`;
109
+ const ordinal = seenOrdinalsByKey.get(meshKey) ?? 0;
110
+ seenOrdinalsByKey.set(meshKey, ordinal + 1);
111
+ const baselineExisting = baselineExistingCounts.get(meshKey) ?? 0;
112
+ // Assume existing pieces correspond to the first N pieces in stable order.
113
+ if (ordinal < baselineExisting)
114
+ continue;
115
+ this.createMeshFromDataFn(piece);
116
+ }
117
+ }
118
+ }
119
+ return 'gpu';
120
+ }
28
121
  /**
29
122
  * Pick object at screen coordinates
30
123
  * Respects visibility filtering so users can only select visible elements
@@ -52,103 +145,18 @@ export class PickingManager {
52
145
  if (options?.isStreaming) {
53
146
  return null;
54
147
  }
55
- let meshes = this.scene.getMeshes();
56
- const batchedMeshes = this.scene.getBatchedMeshes();
57
- // If we have batched meshes, check if we need CPU raycasting
58
- // This handles the case where we have SOME individual meshes (e.g., from highlighting)
59
- // but not enough for full GPU picking coverage
60
- if (batchedMeshes.length > 0) {
61
- if (this.scene.isGeometryDataReleased()) {
62
- const ray = this.camera.unprojectToRay(scaledX, scaledY, this.canvas.width, this.canvas.height);
63
- const hit = this.scene.raycast(ray.origin, ray.direction, options?.hiddenIds, options?.isolatedIds, clip);
64
- if (!hit)
65
- return null;
66
- return {
67
- expressId: hit.expressId,
68
- modelIndex: hit.modelIndex,
69
- };
70
- }
71
- // Collect every pickable expressId. We use the scene's authoritative
72
- // mesh-data id set rather than each batch's `expressIds`, because a batch
73
- // only records the PRIMARY expressId of each merged piece. When a door or
74
- // window is colour-fused into a batch keyed by its host wall / opening,
75
- // the filler's id lives only in the per-vertex entityIds (registered in
76
- // meshDataMap by Scene.addMeshData). Reading batch.expressIds alone would
77
- // skip the filler, so under isolation its mesh is never hydrated and
78
- // pick() returns null (#1358).
79
- const expressIds = new Set(this.scene.getAllMeshDataExpressIds());
80
- // Track how many individual mesh pieces already exist for each (expressId:modelIndex).
81
- // Multi-piece elements (windows/doors with submeshes) need all pieces for reliable picking.
82
- const existingPieceCounts = new Map();
83
- for (const mesh of meshes) {
84
- const key = `${mesh.expressId}:${mesh.modelIndex ?? 'any'}`;
85
- existingPieceCounts.set(key, (existingPieceCounts.get(key) ?? 0) + 1);
86
- }
87
- // Build required piece counts from MeshData for all visible entities.
88
- const requiredPieceCounts = new Map();
89
- const visibleExpressIds = [];
90
- for (const expressId of expressIds) {
91
- if (options?.hiddenIds?.has(expressId))
92
- continue;
93
- if (options?.isolatedIds !== null && options?.isolatedIds !== undefined && !options.isolatedIds.has(expressId))
94
- continue;
95
- visibleExpressIds.push(expressId);
96
- const pieces = this.scene.getMeshDataPieces(expressId);
97
- if (!pieces)
98
- continue;
99
- for (const piece of pieces) {
100
- const key = `${piece.expressId}:${piece.modelIndex ?? 'any'}`;
101
- requiredPieceCounts.set(key, (requiredPieceCounts.get(key) ?? 0) + 1);
102
- }
103
- }
104
- // Count how many meshes we'd need to create for full GPU picking
105
- // For multi-model and multi-piece elements, count missing piece instances per key.
106
- let toCreate = 0;
107
- for (const [key, requiredCount] of requiredPieceCounts) {
108
- const existingCount = existingPieceCounts.get(key) ?? 0;
109
- if (requiredCount > existingCount) {
110
- toCreate += requiredCount - existingCount;
111
- }
112
- }
113
- // PERFORMANCE FIX: Use CPU raycasting for large models instead of creating GPU meshes
114
- // GPU picking requires individual mesh buffers; for 60K+ elements this is too slow
115
- // CPU raycasting uses bounding box filtering + triangle tests - no GPU buffers needed
116
- const MAX_PICK_MESH_CREATION = 500;
117
- if (toCreate > MAX_PICK_MESH_CREATION || (visibleExpressIds.length > 0 && requiredPieceCounts.size === 0)) {
118
- // Use CPU raycasting fallback - works regardless of how many individual meshes exist
119
- const ray = this.camera.unprojectToRay(scaledX, scaledY, this.canvas.width, this.canvas.height);
120
- const hit = this.scene.raycast(ray.origin, ray.direction, options?.hiddenIds, options?.isolatedIds, clip);
121
- if (!hit)
122
- return null;
123
- // CPU raycasting returns expressId and modelIndex
124
- return {
125
- expressId: hit.expressId,
126
- modelIndex: hit.modelIndex,
127
- };
128
- }
129
- // For smaller models, create GPU meshes for picking
130
- // Only create meshes for VISIBLE elements (not hidden, and either no isolation or in isolated set)
131
- // For multi-model support: create meshes for ALL (expressId, modelIndex) pairs
132
- const baselineExistingCounts = new Map(existingPieceCounts);
133
- const seenOrdinalsByKey = new Map();
134
- for (const expressId of visibleExpressIds) {
135
- const pieces = this.scene.getMeshDataPieces(expressId);
136
- if (pieces) {
137
- for (const piece of pieces) {
138
- const meshKey = `${piece.expressId}:${piece.modelIndex ?? 'any'}`;
139
- const ordinal = seenOrdinalsByKey.get(meshKey) ?? 0;
140
- seenOrdinalsByKey.set(meshKey, ordinal + 1);
141
- const baselineExisting = baselineExistingCounts.get(meshKey) ?? 0;
142
- // Assume existing pieces correspond to the first N pieces in stable order.
143
- if (ordinal < baselineExisting)
144
- continue;
145
- this.createMeshFromDataFn(piece);
146
- }
147
- }
148
- }
149
- // Get updated meshes list (includes newly created ones)
150
- meshes = this.scene.getMeshes();
148
+ if (this.prepareBatchedPick(options) === 'cpu') {
149
+ const ray = this.camera.unprojectToRay(scaledX, scaledY, this.canvas.width, this.canvas.height);
150
+ const hit = this.scene.raycast(ray.origin, ray.direction, options?.hiddenIds, options?.isolatedIds, clip);
151
+ if (!hit)
152
+ return null;
153
+ // CPU raycasting returns expressId and modelIndex
154
+ return {
155
+ expressId: hit.expressId,
156
+ modelIndex: hit.modelIndex,
157
+ };
151
158
  }
159
+ let meshes = this.scene.getMeshes();
152
160
  // Apply visibility filtering to meshes before picking
153
161
  // This ensures users can only select elements that are actually visible
154
162
  if (options?.hiddenIds && options.hiddenIds.size > 0) {
@@ -179,11 +187,23 @@ export class PickingManager {
179
187
  * filtered (per-asset visibility is binary and the asset count is
180
188
  * tiny).
181
189
  *
182
- * Limitations: skips the CPU-raycast and dynamic-mesh-creation
183
- * fallbacks that `pick()` uses for very large batched models, so
184
- * rect pick may miss entities whose individual meshes haven't been
185
- * hydrated. Acceptable for an MVP rect select is a power-user
186
- * tool and the user can fall back to single-click pick.
190
+ * Batched models take the same route as `pick()`: hydrate the
191
+ * missing individual meshes when that is affordable, otherwise fall
192
+ * back to `Scene.selectRect`, which over-selects relative to the
193
+ * pixel-exact GPU pass in three ways: it is bounding-box granular
194
+ * (a rect over empty space inside an element's bounds selects it),
195
+ * it has no depth test (occluded entities are selected), and it
196
+ * drops a section-planed or cropped entity only when the whole box
197
+ * is clipped away, where the pick shader discards per fragment.
198
+ * Hidden and isolation filtering do apply there. Reading
199
+ * `scene.getMeshes()` unconditionally is what made this return an
200
+ * empty set on every batched model (#1904).
201
+ *
202
+ * Point clouds never depend on mesh hydration — splats render into
203
+ * the pick pass on their own — so the CPU branch still runs the GPU
204
+ * pass for them and unions the two results. Skipping it would drop
205
+ * point selection on any mixed scene big enough to miss the
206
+ * pick-mesh budget.
187
207
  */
188
208
  async pickRect(x0, y0, x1, y1, options, clip) {
189
209
  if (!this.picker)
@@ -197,6 +217,47 @@ export class PickingManager {
197
217
  const sx1 = x1 * scaleX, sy1 = y1 * scaleY;
198
218
  if (options?.isStreaming)
199
219
  return new Set();
220
+ if (this.prepareBatchedPick(options) === 'cpu') {
221
+ const boxHits = this.scene.selectRect(sx0, sy0, sx1, sy1, this.canvas.width, this.canvas.height, this.camera.getViewProjMatrix().m, options?.hiddenIds, options?.isolatedIds, clip);
222
+ const cpuPointSnap = this.pointPickProvider?.() ?? null;
223
+ if (!cpuPointSnap || cpuPointSnap.nodes.length === 0)
224
+ return boxHits;
225
+ // Point-only pick pass. Meshes are deliberately `[]`: this branch runs
226
+ // precisely because the per-element pick buffers were NOT hydrated, so
227
+ // `scene.getMeshes()` holds an arbitrary partial set (highlight meshes
228
+ // and whatever an earlier pick left behind) whose ids `selectRect`
229
+ // already covers.
230
+ //
231
+ // Instanced templates are left out for a different reason. The
232
+ // instanced pick pass IS visibility-filtered — its fragment shader
233
+ // discards on `instFlags` bit 1, which `Scene` sets for every
234
+ // occurrence that is hidden or excluded by isolation — so unioning its
235
+ // hits would not re-admit anything. It is left out because it would
236
+ // add no ids and can only subtract. Every instanced occurrence whose
237
+ // template has geometry folds its world AABB into
238
+ // `Scene.boundingBoxes`, so `selectRect` above has already returned
239
+ // those ids under the same two filters (a template with no finite
240
+ // local box is skipped there, and rasterises nothing here either).
241
+ // Meanwhile the instanced draw shares this pass's depth target, so an
242
+ // occurrence in front of a splat would occlude it and drop a point hit
243
+ // that nothing else on this path can supply — point assets have no
244
+ // entry in `boundingBoxes` at all.
245
+ let pointHits;
246
+ try {
247
+ pointHits = await this.picker.pickRect(sx0, sy0, sx1, sy1, this.canvas.width, this.canvas.height, [], this.camera.getViewProjMatrix().m, cpuPointSnap.nodes, cpuPointSnap.sizing, undefined, clip);
248
+ }
249
+ catch (err) {
250
+ // `picker.pickRect` rethrows any readback failure that is not a
251
+ // device-loss abort. The box hits are already computed and this
252
+ // branch could not throw at all before the point pass was added,
253
+ // so degrade to them instead of failing the whole rectangle select.
254
+ console.warn('[PickingManager] point-cloud rect pick failed; returning bounding-box hits only:', err);
255
+ return boxHits;
256
+ }
257
+ for (const id of pointHits)
258
+ boxHits.add(id);
259
+ return boxHits;
260
+ }
200
261
  let meshes = this.scene.getMeshes();
201
262
  if (options?.hiddenIds && options.hiddenIds.size > 0) {
202
263
  meshes = meshes.filter((m) => !options.hiddenIds.has(m.expressId));
@@ -1 +1 @@
1
- {"version":3,"file":"picking-manager.js","sourceRoot":"","sources":["../src/picking-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"picking-manager.js","sourceRoot":"","sources":["../src/picking-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * CPU rectangle selection against bounding-box data.
3
+ *
4
+ * The rect analogue of `raycastBoundingBoxes` in `scene-raycaster.ts`, and it
5
+ * exists for the same reason: on a batched model the GPU pick pass only sees
6
+ * individually hydrated meshes, and hydrating every visible piece is too
7
+ * expensive past a few hundred entities. `pick()` has always had a CPU escape
8
+ * hatch for that case; rectangle select had none, which is why it returned an
9
+ * empty set on batched models (#1904).
10
+ *
11
+ * Granularity: bounding box, not triangle. A box whose screen-space AABB
12
+ * overlaps the rect counts as selected, so this over-selects relative to the
13
+ * pixel-exact GPU path — an entity can be picked when the rect covers only
14
+ * empty space inside its bounds. That granularity is the same one the
15
+ * released-geometry raycast path already has (`raycastBoundingBoxes` also tests
16
+ * boxes, not triangles), and over-selection is recoverable by the user in a way
17
+ * that selecting nothing is not.
18
+ *
19
+ * Two further gaps are NOT shared with that path, and both over-select. There is
20
+ * no depth test at all here, so an entity fully occluded by another is still
21
+ * selected, whereas the raycast keeps only the nearest box (`tNear <
22
+ * closestDistance`). And section-plane / crop-box filtering is whole-box: the
23
+ * `boxFullyClipped` call below skips an entity only when nothing of its box
24
+ * could be visible, so a rect over the sectioned-away half of a box still
25
+ * selects it — the raycast measures entry into the *visible* part of the box
26
+ * (`clippedBoxEntryDistance`), and the pick shader discards per fragment.
27
+ */
28
+ import { type BoundingBox } from './scene-raycaster.js';
29
+ import type { PickClipState } from './types.js';
30
+ /** Selection rectangle in canvas (device) pixels. Corners may be in any order. */
31
+ export interface ScreenRect {
32
+ x0: number;
33
+ y0: number;
34
+ x1: number;
35
+ y1: number;
36
+ }
37
+ /**
38
+ * Every entity whose bounding box projects onto the given screen rect.
39
+ *
40
+ * @param boundingBoxes World-space AABB per expressId
41
+ * @param viewProj Camera view-projection, column-major (see below)
42
+ * @param rect Selection rect in canvas pixels
43
+ * @param viewportWidth Canvas width in pixels
44
+ * @param viewportHeight Canvas height in pixels
45
+ * @param hiddenIds Skipped entirely
46
+ * @param isolatedIds When non-null, only these ids are considered
47
+ * @param clip Active section plane / crop box, so selection matches
48
+ * what is visible (same contract as the raycast paths)
49
+ */
50
+ export declare function selectBoundingBoxesInRect(boundingBoxes: Map<number, BoundingBox>, viewProj: Float32Array, rect: ScreenRect, viewportWidth: number, viewportHeight: number, hiddenIds?: Set<number>, isolatedIds?: Set<number> | null, clip?: PickClipState | null): Set<number>;
51
+ //# sourceMappingURL=scene-rect-select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene-rect-select.d.ts","sourceRoot":"","sources":["../src/scene-rect-select.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAiC,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAiBhD,kFAAkF;AAClF,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACrC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,EACvC,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,UAAU,EAChB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,EAChC,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,GAC5B,GAAG,CAAC,MAAM,CAAC,CAyIb"}