@ifc-lite/renderer 6.3.3 → 6.5.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.
- package/dist/camera-animation.d.ts +7 -1
- package/dist/camera-animation.d.ts.map +1 -1
- package/dist/camera-animation.js +19 -3
- package/dist/camera-animation.js.map +1 -1
- package/dist/camera-fit-geometry.d.ts +47 -0
- package/dist/camera-fit-geometry.d.ts.map +1 -0
- package/dist/camera-fit-geometry.js +44 -0
- package/dist/camera-fit-geometry.js.map +1 -0
- package/dist/camera-framing.d.ts +27 -21
- package/dist/camera-framing.d.ts.map +1 -1
- package/dist/camera-framing.js +47 -44
- package/dist/camera-framing.js.map +1 -1
- package/dist/camera-preset-view.d.ts +18 -0
- package/dist/camera-preset-view.d.ts.map +1 -1
- package/dist/camera-preset-view.js +42 -0
- package/dist/camera-preset-view.js.map +1 -1
- package/dist/camera.d.ts +14 -1
- package/dist/camera.d.ts.map +1 -1
- package/dist/camera.js +14 -2
- package/dist/camera.js.map +1 -1
- package/dist/clip-types.d.ts +35 -0
- package/dist/clip-types.d.ts.map +1 -0
- package/dist/clip-types.js +5 -0
- package/dist/clip-types.js.map +1 -0
- package/dist/device-recovery.js +11 -1
- package/dist/device-recovery.js.map +1 -1
- package/dist/device.d.ts +4 -4
- package/dist/device.js +9 -9
- package/dist/device.js.map +1 -1
- package/dist/extra-clip-planes.d.ts +57 -0
- package/dist/extra-clip-planes.d.ts.map +1 -0
- package/dist/extra-clip-planes.js +161 -0
- package/dist/extra-clip-planes.js.map +1 -0
- package/dist/gpu-counters.d.ts +4 -2
- package/dist/gpu-counters.d.ts.map +1 -1
- package/dist/gpu-counters.js +9 -6
- package/dist/gpu-counters.js.map +1 -1
- package/dist/index.d.ts +19 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +69 -90
- package/dist/index.js.map +1 -1
- package/dist/mesh-rte-uniforms.d.ts +7 -3
- package/dist/mesh-rte-uniforms.d.ts.map +1 -1
- package/dist/mesh-rte-uniforms.js +16 -2
- package/dist/mesh-rte-uniforms.js.map +1 -1
- package/dist/opaque-visibility-commands.d.ts +3 -0
- package/dist/opaque-visibility-commands.d.ts.map +1 -0
- package/dist/opaque-visibility-commands.js +11 -0
- package/dist/opaque-visibility-commands.js.map +1 -0
- package/dist/opaque-visibility-pass.d.ts +37 -0
- package/dist/opaque-visibility-pass.d.ts.map +1 -0
- package/dist/opaque-visibility-pass.js +230 -0
- package/dist/opaque-visibility-pass.js.map +1 -0
- package/dist/pick-types.d.ts +5 -1
- package/dist/pick-types.d.ts.map +1 -1
- package/dist/picker-rte-uniforms.d.ts +1 -1
- package/dist/picker-rte-uniforms.d.ts.map +1 -1
- package/dist/picker-rte-uniforms.js +4 -2
- package/dist/picker-rte-uniforms.js.map +1 -1
- package/dist/picker-shaders.d.ts +5 -0
- package/dist/picker-shaders.d.ts.map +1 -0
- package/dist/picker-shaders.js +157 -0
- package/dist/picker-shaders.js.map +1 -0
- package/dist/picker.d.ts +3 -0
- package/dist/picker.d.ts.map +1 -1
- package/dist/picker.js +43 -133
- package/dist/picker.js.map +1 -1
- package/dist/pipeline.d.ts +5 -9
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +34 -29
- package/dist/pipeline.js.map +1 -1
- package/dist/point-picker.d.ts +2 -1
- package/dist/point-picker.d.ts.map +1 -1
- package/dist/point-picker.js +12 -4
- package/dist/point-picker.js.map +1 -1
- package/dist/pointcloud/point-cloud-renderer.d.ts +4 -4
- package/dist/pointcloud/point-cloud-renderer.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-renderer.js +1 -1
- package/dist/pointcloud/point-cloud-renderer.js.map +1 -1
- package/dist/pointcloud/point-cloud-uniforms.d.ts +3 -1
- package/dist/pointcloud/point-cloud-uniforms.d.ts.map +1 -1
- package/dist/pointcloud/point-cloud-uniforms.js +3 -1
- package/dist/pointcloud/point-cloud-uniforms.js.map +1 -1
- package/dist/pointcloud/point-pipeline.d.ts +3 -1
- package/dist/pointcloud/point-pipeline.d.ts.map +1 -1
- package/dist/pointcloud/point-pipeline.js +4 -1
- package/dist/pointcloud/point-pipeline.js.map +1 -1
- package/dist/pointcloud/point-shader.wgsl.d.ts +1 -1
- package/dist/pointcloud/point-shader.wgsl.d.ts.map +1 -1
- package/dist/pointcloud/point-shader.wgsl.js +8 -0
- package/dist/pointcloud/point-shader.wgsl.js.map +1 -1
- package/dist/post-pass-chain.d.ts +1 -0
- package/dist/post-pass-chain.d.ts.map +1 -1
- package/dist/post-pass-chain.js +1 -0
- package/dist/post-pass-chain.js.map +1 -1
- package/dist/quantized-lifecycle.d.ts +6 -0
- package/dist/quantized-lifecycle.d.ts.map +1 -0
- package/dist/quantized-lifecycle.js +19 -0
- package/dist/quantized-lifecycle.js.map +1 -0
- package/dist/raycast-engine.d.ts.map +1 -1
- package/dist/raycast-engine.js +3 -2
- package/dist/raycast-engine.js.map +1 -1
- package/dist/render-section-draw.d.ts +5 -0
- package/dist/render-section-draw.d.ts.map +1 -1
- package/dist/render-section-draw.js +59 -25
- package/dist/render-section-draw.js.map +1 -1
- package/dist/render-section-plane.d.ts +5 -33
- package/dist/render-section-plane.d.ts.map +1 -1
- package/dist/render-section-plane.js +8 -175
- package/dist/render-section-plane.js.map +1 -1
- package/dist/renderer-frame-timing.d.ts +1 -0
- package/dist/renderer-frame-timing.d.ts.map +1 -1
- package/dist/renderer-frame-timing.js +8 -1
- package/dist/renderer-frame-timing.js.map +1 -1
- package/dist/renderer-overlays.d.ts +8 -2
- package/dist/renderer-overlays.d.ts.map +1 -1
- package/dist/renderer-overlays.js +22 -45
- package/dist/renderer-overlays.js.map +1 -1
- package/dist/scene-raycaster.d.ts +1 -1
- package/dist/scene-raycaster.d.ts.map +1 -1
- package/dist/scene-raycaster.js +18 -44
- package/dist/scene-raycaster.js.map +1 -1
- package/dist/scene-rect-select.d.ts.map +1 -1
- package/dist/scene-rect-select.js +2 -1
- package/dist/scene-rect-select.js.map +1 -1
- package/dist/section-2d-lift.d.ts +25 -0
- package/dist/section-2d-lift.d.ts.map +1 -1
- package/dist/section-2d-lift.js +35 -0
- package/dist/section-2d-lift.js.map +1 -1
- package/dist/section-2d-overlay.d.ts +41 -12
- package/dist/section-2d-overlay.d.ts.map +1 -1
- package/dist/section-2d-overlay.js +121 -179
- package/dist/section-2d-overlay.js.map +1 -1
- package/dist/section-2d-types.d.ts +2 -0
- package/dist/section-2d-types.d.ts.map +1 -1
- package/dist/section-cap-geometry.d.ts +33 -0
- package/dist/section-cap-geometry.d.ts.map +1 -0
- package/dist/section-cap-geometry.js +137 -0
- package/dist/section-cap-geometry.js.map +1 -0
- package/dist/section-cap-set.d.ts +60 -0
- package/dist/section-cap-set.d.ts.map +1 -0
- package/dist/section-cap-set.js +212 -0
- package/dist/section-cap-set.js.map +1 -0
- package/dist/section-cap-style.d.ts +3 -0
- package/dist/section-cap-style.d.ts.map +1 -1
- package/dist/section-cap-style.js.map +1 -1
- package/dist/section-cap-upload.d.ts +16 -0
- package/dist/section-cap-upload.d.ts.map +1 -0
- package/dist/section-cap-upload.js +52 -0
- package/dist/section-cap-upload.js.map +1 -0
- package/dist/section-exclusions.d.ts +26 -0
- package/dist/section-exclusions.d.ts.map +1 -0
- package/dist/section-exclusions.js +95 -0
- package/dist/section-exclusions.js.map +1 -0
- package/dist/section-plane-frames.d.ts +48 -0
- package/dist/section-plane-frames.d.ts.map +1 -0
- package/dist/section-plane-frames.js +49 -0
- package/dist/section-plane-frames.js.map +1 -0
- package/dist/section-plane-resolve.d.ts +63 -0
- package/dist/section-plane-resolve.d.ts.map +1 -0
- package/dist/section-plane-resolve.js +200 -0
- package/dist/section-plane-resolve.js.map +1 -0
- package/dist/selection-mask-pass.d.ts +2 -0
- package/dist/selection-mask-pass.d.ts.map +1 -1
- package/dist/selection-mask-pass.js +16 -4
- package/dist/selection-mask-pass.js.map +1 -1
- package/dist/selection-mask-pipelines.d.ts +5 -1
- package/dist/selection-mask-pipelines.d.ts.map +1 -1
- package/dist/selection-mask-pipelines.js +27 -3
- package/dist/selection-mask-pipelines.js.map +1 -1
- package/dist/selection-outline-frame.d.ts +3 -1
- package/dist/selection-outline-frame.d.ts.map +1 -1
- package/dist/selection-outline-frame.js +2 -1
- package/dist/selection-outline-frame.js.map +1 -1
- package/dist/shaders/depth-nudge.wgsl.d.ts +2 -2
- package/dist/shaders/depth-nudge.wgsl.d.ts.map +1 -1
- package/dist/shaders/depth-nudge.wgsl.js +1 -18
- package/dist/shaders/depth-nudge.wgsl.js.map +1 -1
- package/dist/shaders/main.wgsl.d.ts +1 -1
- package/dist/shaders/main.wgsl.d.ts.map +1 -1
- package/dist/shaders/main.wgsl.js +9 -1
- package/dist/shaders/main.wgsl.js.map +1 -1
- package/dist/shaders/mesh-uniforms.wgsl.d.ts +1 -1
- package/dist/shaders/mesh-uniforms.wgsl.d.ts.map +1 -1
- package/dist/shaders/mesh-uniforms.wgsl.js +11 -3
- package/dist/shaders/mesh-uniforms.wgsl.js.map +1 -1
- package/dist/shaders/opaque-visibility.wgsl.d.ts +11 -0
- package/dist/shaders/opaque-visibility.wgsl.d.ts.map +1 -0
- package/dist/shaders/opaque-visibility.wgsl.js +55 -0
- package/dist/shaders/opaque-visibility.wgsl.js.map +1 -0
- package/dist/shaders/section-2d-overlay.wgsl.d.ts +11 -5
- package/dist/shaders/section-2d-overlay.wgsl.d.ts.map +1 -1
- package/dist/shaders/section-2d-overlay.wgsl.js +31 -5
- package/dist/shaders/section-2d-overlay.wgsl.js.map +1 -1
- package/dist/shaders/selection-mask.wgsl.d.ts +1 -1
- package/dist/shaders/selection-mask.wgsl.d.ts.map +1 -1
- package/dist/shaders/selection-mask.wgsl.js +10 -4
- package/dist/shaders/selection-mask.wgsl.js.map +1 -1
- package/dist/shaders/shadow.wgsl.d.ts +1 -1
- package/dist/shaders/shadow.wgsl.d.ts.map +1 -1
- package/dist/shaders/shadow.wgsl.js +22 -7
- package/dist/shaders/shadow.wgsl.js.map +1 -1
- package/dist/shaders/symbolic-overlay.wgsl.d.ts +1 -1
- package/dist/shaders/symbolic-overlay.wgsl.d.ts.map +1 -1
- package/dist/shadow-occluders.d.ts.map +1 -1
- package/dist/shadow-occluders.js +4 -0
- package/dist/shadow-occluders.js.map +1 -1
- package/dist/shadow-pass.d.ts +2 -5
- package/dist/shadow-pass.d.ts.map +1 -1
- package/dist/shadow-pass.js +17 -17
- package/dist/shadow-pass.js.map +1 -1
- package/dist/shadow-types.d.ts +7 -0
- package/dist/shadow-types.d.ts.map +1 -1
- package/dist/shadow-types.js.map +1 -1
- package/dist/source-curve-clipping.d.ts.map +1 -1
- package/dist/source-curve-clipping.js +7 -1
- package/dist/source-curve-clipping.js.map +1 -1
- package/dist/source-curve-snap.d.ts.map +1 -1
- package/dist/source-curve-snap.js +2 -1
- package/dist/source-curve-snap.js.map +1 -1
- package/dist/types.d.ts +12 -16
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
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
|
+
import { sectionExclusions } from './section-exclusions.js';
|
|
4
5
|
/**
|
|
5
6
|
* @ifc-lite/renderer - WebGPU renderer
|
|
6
7
|
*/
|
|
@@ -10,6 +11,7 @@ export { Camera } from './camera.js';
|
|
|
10
11
|
export { appearanceSourceTriangle, expandAppearanceCorners, equivalentAppearanceGeometry } from './appearance-uvs.js';
|
|
11
12
|
export { sameCompanionParts } from './appearance-companions.js';
|
|
12
13
|
export { invertAppearancePartition, validateAppearancePartition } from './appearance-preview.js';
|
|
14
|
+
import { deferOpaqueVisibilityFrame } from './opaque-visibility-pass.js';
|
|
13
15
|
import { createReferenceImageManager } from './reference-image-host.js';
|
|
14
16
|
import { MAX_DRAWING_BUFFER_PIXEL_RATIO, measureDrawingBuffer, resizeRendererViewport } from './renderer-viewport.js';
|
|
15
17
|
export { pickFitPolicy } from './camera-fit-policy.js';
|
|
@@ -35,6 +37,7 @@ export { SymbolicTextAtlas } from './symbolic-text-atlas.js';
|
|
|
35
37
|
// holds the styling primitives shared with the store and UI.
|
|
36
38
|
export { DEFAULT_CAP_STYLE, HATCH_PATTERN_IDS } from './section-cap-style.js';
|
|
37
39
|
export { planeBasis, nearestCardinalAxis } from './section-plane-basis.js';
|
|
40
|
+
export { capHighlightKey } from './section-2d-overlay.js';
|
|
38
41
|
export { LINE_OVERLAY_CHANNELS } from './section-2d-overlay.js';
|
|
39
42
|
export { Raycaster } from './raycaster.js';
|
|
40
43
|
export { SnapDetector, SnapType } from './snap-detector.js';
|
|
@@ -42,6 +45,7 @@ export { BVH } from './bvh.js';
|
|
|
42
45
|
export { hostsOtherEntities } from './mesh-entity-hosting.js';
|
|
43
46
|
export { FederationRegistry, federationRegistry } from './federation-registry.js';
|
|
44
47
|
export * from './types.js';
|
|
48
|
+
export { MAX_EXTRA_CLIP_PLANES } from './extra-clip-planes.js';
|
|
45
49
|
export { resolveEnvironment, deriveSkyGradient, packEnvironmentUniforms, ENVIRONMENT_UNIFORM_SIZE, } from './environment.js';
|
|
46
50
|
export { DEFAULT_OVERLAY_THEME } from './overlay-theme.js';
|
|
47
51
|
import { DEFAULT_OVERLAY_THEME } from './overlay-theme.js';
|
|
@@ -58,6 +62,7 @@ export { isEntityVisible } from './entity-visibility.js';
|
|
|
58
62
|
// Alpha constants the Cesium world view must match, since it renders the model
|
|
59
63
|
// through its own glTF pipeline rather than this one (#2591).
|
|
60
64
|
export { DEFAULT_GHOST_ALPHA, OPAQUE_ALPHA_CUTOFF } from './overlay-routing.js';
|
|
65
|
+
export { DEFAULT_MIN_CAST_ALPHA } from './shadow-occluders.js';
|
|
61
66
|
export { VisibilityEpochTracker } from './visibility-epoch.js';
|
|
62
67
|
export { decideTimingMode, passDurationsMs, frameTotalMs, aggregateFrameTimings } from './frame-timing.js';
|
|
63
68
|
export { computeDurationStats, nsToMs, isNegativeDelta } from './frame-timing-stats.js';
|
|
@@ -81,7 +86,8 @@ import { viewBasis } from './math.js';
|
|
|
81
86
|
import { isRteAabbVisible, rteFrustum, sourceFrustumFromRte } from './rte-frustum.js';
|
|
82
87
|
import { VisualEnhancementResolver, livePostEffects } from './visual-enhancement.js';
|
|
83
88
|
import { packClipBox } from './clip-box.js';
|
|
84
|
-
import {
|
|
89
|
+
import { resolveSectionPlaneFrames } from './section-plane-frames.js';
|
|
90
|
+
import { MESH_FLAGS_BYTE_OFFSET, MESH_FLAG_RTE_DRAWABLE, MESH_UNIFORM_FLOATS, MESH_UNIFORM_OFFSET, packRteCameraOrigin, packRteFragmentSpace, packSectionPlaneLanes, } from './mesh-rte-uniforms.js';
|
|
85
91
|
import { packMeshMaterial } from './mesh-material.js';
|
|
86
92
|
import { RendererOverlays } from './renderer-overlays.js';
|
|
87
93
|
import { resolveSectionPlaneFrame } from './render-section-plane.js';
|
|
@@ -117,6 +123,7 @@ import { appendPointCloudChunk as appendPointCloudChunkImpl, beginPointCloudStre
|
|
|
117
123
|
import { DeviationComputer } from './deviation/deviation-computer.js';
|
|
118
124
|
export { computeDeviationStatistics, computeDeviationStatisticsAsync, countWithinToleranceAsync, deviationHistogramAsync, summarizeDeviationAssetsAsync } from './deviation/deviation-statistics.js';
|
|
119
125
|
import { runGuardedGpuUpload, isDeviceLossThrow } from './gpu-upload-guard.js';
|
|
126
|
+
import { enableRendererQuantizedBatches } from './quantized-lifecycle.js';
|
|
120
127
|
import { recoverRendererDevice, rendererDeviceLostError } from './device-recovery.js';
|
|
121
128
|
/**
|
|
122
129
|
* The reason `whenReady()` rejects when the renderer is destroyed.
|
|
@@ -405,13 +412,17 @@ export class Renderer {
|
|
|
405
412
|
// One 336-byte buffer serves all frame batches/meshes (84 floats including RTE lanes).
|
|
406
413
|
uniformScratch = new Float32Array(MESH_UNIFORM_FLOATS);
|
|
407
414
|
uniformScratchU32 = new Uint32Array(this.uniformScratch.buffer, MESH_FLAGS_BYTE_OFFSET, 4);
|
|
408
|
-
// overrideParams
|
|
415
|
+
// overrideParams: full entity anchor for clipping, plus colour-override mode (#6076).
|
|
409
416
|
uniformOverrideU32 = new Uint32Array(this.uniformScratch.buffer, MESH_UNIFORM_OFFSET.overrideParams * 4, 4);
|
|
410
417
|
// What the last render() actually clipped, so the GPU picker can mirror it and
|
|
411
418
|
// section/crop-clipped geometry stays unpickable, not just invisible. Updated
|
|
412
419
|
// every render; read by pick()/pickRect(). null = nothing clipped that frame.
|
|
413
420
|
_activePickSection = null;
|
|
414
421
|
_activePickClipBox = null;
|
|
422
|
+
_sectionExcludedIds = new Set();
|
|
423
|
+
/** Snapshot of the extra planes the last frame clipped against (#7545), mirrored by the pickers. */
|
|
424
|
+
_activePickExtraPlanes = null;
|
|
425
|
+
_sectionFrameInput = null; // what the last frame resolved the section planes from
|
|
415
426
|
constructor(canvas) {
|
|
416
427
|
this.canvas = canvas;
|
|
417
428
|
this.device = new WebGPUDevice();
|
|
@@ -451,6 +462,7 @@ export class Renderer {
|
|
|
451
462
|
// init there is nothing to invalidate and this is a no-op.
|
|
452
463
|
const generation = ++this.initGeneration;
|
|
453
464
|
this.ready = false;
|
|
465
|
+
this.scene.setQuantizedBatches(false); // #7655: admission belongs to the retired GPU lifetime.
|
|
454
466
|
// Re-arm `whenReady()`: this instance is being brought back up, so a
|
|
455
467
|
// wait requested from here on is "not ready yet" again, not "destroyed".
|
|
456
468
|
this.destroyed = false;
|
|
@@ -633,8 +645,8 @@ export class Renderer {
|
|
|
633
645
|
w.reject(error);
|
|
634
646
|
}
|
|
635
647
|
/**
|
|
636
|
-
* Subscribe to
|
|
637
|
-
*
|
|
648
|
+
* Subscribe to GPU device loss outside owned teardown (including browser
|
|
649
|
+
* destruction, driver reset or VRAM exhaustion). Fired at most once per
|
|
638
650
|
* device. After it fires, `render()` is a no-op and the renderer reports
|
|
639
651
|
* itself un-ready (`isReady()` false, `whenReady()` rejecting with
|
|
640
652
|
* `RendererDeviceLostError`) until it is re-initialised, so the typical
|
|
@@ -1317,13 +1329,7 @@ export class Renderer {
|
|
|
1317
1329
|
* rejecting pipeline creation) batches stay on the f32 path.
|
|
1318
1330
|
*/
|
|
1319
1331
|
async enableQuantizedBatches() {
|
|
1320
|
-
this
|
|
1321
|
-
if (!this.pipeline)
|
|
1322
|
-
return false;
|
|
1323
|
-
const ok = await this.pipeline.ensureQuantizedPipelines();
|
|
1324
|
-
if (ok)
|
|
1325
|
-
this.scene.setQuantizedBatches(true);
|
|
1326
|
-
return ok;
|
|
1332
|
+
return enableRendererQuantizedBatches(this);
|
|
1327
1333
|
}
|
|
1328
1334
|
/** Draw a frame through the shared submission path, preserving the void API. */
|
|
1329
1335
|
render(options = {}) { this.renderWithResult(options); }
|
|
@@ -1569,10 +1575,6 @@ export class Renderer {
|
|
|
1569
1575
|
// would never show it. See issue #677. Pure routing decision lives in
|
|
1570
1576
|
// overlay-routing.ts and is unit-tested there.
|
|
1571
1577
|
const colorOverrides = this.scene.getColorOverrides();
|
|
1572
|
-
// PERFORMANCE FIX: Use batch-level visibility filtering instead of creating individual meshes
|
|
1573
|
-
// Only create individual meshes for selected elements (for highlighting)
|
|
1574
|
-
// Batches are filtered at render time - fully visible batches render normally,
|
|
1575
|
-
// partially visible batches are skipped (their visible elements will be in other batches or individual meshes)
|
|
1576
1578
|
// Ensure all existing meshes have GPU resources
|
|
1577
1579
|
this.ensureMeshResources();
|
|
1578
1580
|
// Frustum culling (if enabled and spatial index available)
|
|
@@ -1666,6 +1668,9 @@ export class Renderer {
|
|
|
1666
1668
|
spendLogLatch: () => { this._loggedSectionBounds = true; },
|
|
1667
1669
|
});
|
|
1668
1670
|
const sectionPlaneData = sectionFrame.sectionPlaneData;
|
|
1671
|
+
const extraClipPlanes = sectionFrame.extraPlanes;
|
|
1672
|
+
const { bounds: frameBounds } = sectionFrame;
|
|
1673
|
+
this._sectionFrameInput = frameBounds && { primary: options.sectionPlane ?? null, extras: options.extraSectionPlanes ?? [], bounds: frameBounds, buildingRotation: options.buildingRotation };
|
|
1669
1674
|
if (sectionFrame.bounds) {
|
|
1670
1675
|
// Store bounds for section plane visual and camera near/far.
|
|
1671
1676
|
// Two wrappers over the same min/max, exactly as before the
|
|
@@ -1688,6 +1693,9 @@ export class Renderer {
|
|
|
1688
1693
|
flipped: !!options.sectionPlane?.flipped,
|
|
1689
1694
|
}
|
|
1690
1695
|
: null;
|
|
1696
|
+
this._sectionExcludedIds = new Set(options.sectionExcludedIds);
|
|
1697
|
+
sectionExclusions(device).update(this._sectionExcludedIds);
|
|
1698
|
+
this._activePickExtraPlanes = extraClipPlanes.length > 0 ? extraClipPlanes.map((p) => ({ normal: [...p.normal], distance: p.distance, flipped: p.flipped })) : null;
|
|
1691
1699
|
this._activePickClipBox = options.clipBox?.enabled
|
|
1692
1700
|
? {
|
|
1693
1701
|
enabled: true,
|
|
@@ -1722,18 +1730,7 @@ export class Renderer {
|
|
|
1722
1730
|
meshBuf[35] = isSelected ? mesh.color[3] : alphaForMesh(mesh.expressId, mesh.color[3]);
|
|
1723
1731
|
packMeshMaterial(meshBuf, mesh.color[3], mesh.finish ?? mesh.material);
|
|
1724
1732
|
// Section plane data (offset 40-43)
|
|
1725
|
-
|
|
1726
|
-
meshBuf[40] = sectionPlaneData.normal[0];
|
|
1727
|
-
meshBuf[41] = sectionPlaneData.normal[1];
|
|
1728
|
-
meshBuf[42] = sectionPlaneData.normal[2];
|
|
1729
|
-
meshBuf[43] = sectionPlaneData.distance;
|
|
1730
|
-
}
|
|
1731
|
-
else {
|
|
1732
|
-
meshBuf[40] = 0;
|
|
1733
|
-
meshBuf[41] = 0;
|
|
1734
|
-
meshBuf[42] = 0;
|
|
1735
|
-
meshBuf[43] = 0;
|
|
1736
|
-
}
|
|
1733
|
+
packSectionPlaneLanes(sectionPlaneData, meshBuf);
|
|
1737
1734
|
// Clip box (offset 48-55: min.xyz + pad, max.xyz + pad) → enable bit
|
|
1738
1735
|
const clipBit = packClipBox(options.clipBox, meshBuf, 48);
|
|
1739
1736
|
// Flags (offset 44-47 as u32)
|
|
@@ -1747,7 +1744,7 @@ export class Renderer {
|
|
|
1747
1744
|
meshFlags[3] = 0;
|
|
1748
1745
|
// Individual meshes retain their origin and share the RTE
|
|
1749
1746
|
// fragment contract with colour batches.
|
|
1750
|
-
packRteFragmentSpace(relativeToEyeFrame, sectionPlaneData, options.clipBox, meshBuf);
|
|
1747
|
+
packRteFragmentSpace(relativeToEyeFrame, sectionPlaneData, options.clipBox, meshBuf, extraClipPlanes);
|
|
1751
1748
|
const meshOrigin = mesh.rteOrigin
|
|
1752
1749
|
?? [mesh.transform.m[12], mesh.transform.m[13], mesh.transform.m[14]];
|
|
1753
1750
|
if (!relativeToEyeFrame.tryPackDrawableOrigin(meshOrigin, meshBuf, MESH_UNIFORM_OFFSET.drawableDelta)) {
|
|
@@ -1755,6 +1752,7 @@ export class Renderer {
|
|
|
1755
1752
|
continue;
|
|
1756
1753
|
}
|
|
1757
1754
|
meshFlags[0] |= MESH_FLAG_RTE_DRAWABLE;
|
|
1755
|
+
new Uint32Array(meshBuf.buffer)[MESH_UNIFORM_OFFSET.overrideParams] = mesh.expressId;
|
|
1758
1756
|
device.queue.writeBuffer(mesh.uniformBuffer, 0, meshBuf);
|
|
1759
1757
|
}
|
|
1760
1758
|
}
|
|
@@ -1848,6 +1846,7 @@ export class Renderer {
|
|
|
1848
1846
|
// floor it no longer covers. `sectionPlaneData` already
|
|
1849
1847
|
// folds in the terrain clip, so that is covered as well.
|
|
1850
1848
|
this.shadowPass.render(encoder, fit.lightViewProj, occluders, {
|
|
1849
|
+
sectionExcludedIds: this._sectionExcludedIds,
|
|
1851
1850
|
section: sectionPlaneData?.enabled
|
|
1852
1851
|
? {
|
|
1853
1852
|
normal: sectionPlaneData.normal,
|
|
@@ -1858,6 +1857,7 @@ export class Renderer {
|
|
|
1858
1857
|
box: options.clipBox?.enabled
|
|
1859
1858
|
? { min: options.clipBox.min, max: options.clipBox.max }
|
|
1860
1859
|
: null,
|
|
1860
|
+
extraPlanes: extraClipPlanes,
|
|
1861
1861
|
}, { cameraWorld: shadowEye });
|
|
1862
1862
|
// Shadow uniform: light matrix + sampling params. The kernel
|
|
1863
1863
|
// width follows the sun's angular size (physical, ~0.53°
|
|
@@ -1925,7 +1925,7 @@ export class Renderer {
|
|
|
1925
1925
|
clearValue: { r: 0, g: 0, b: 0, a: 0 },
|
|
1926
1926
|
storeOp: (needsObjectIdPass ? 'store' : 'discard'),
|
|
1927
1927
|
});
|
|
1928
|
-
const pass =
|
|
1928
|
+
const pass = this.pipeline.visibility.begin(encoder, {
|
|
1929
1929
|
timestampWrites: renderPassTimestampWrites(encoder, 'main'),
|
|
1930
1930
|
colorAttachments,
|
|
1931
1931
|
depthStencilAttachment: {
|
|
@@ -1939,7 +1939,7 @@ export class Renderer {
|
|
|
1939
1939
|
stencilLoadOp: 'clear',
|
|
1940
1940
|
stencilStoreOp: 'store',
|
|
1941
1941
|
},
|
|
1942
|
-
});
|
|
1942
|
+
}, this.camera.getProjectionMode() === 'orthographic', this.canvas.width, this.canvas.height);
|
|
1943
1943
|
// Global lighting environment: write the uniform once per frame.
|
|
1944
1944
|
// The group(1) bind is deferred until AFTER the sky pass below —
|
|
1945
1945
|
// the sky pipeline has an incompatible layout (its own group(0),
|
|
@@ -1995,6 +1995,7 @@ export class Renderer {
|
|
|
1995
1995
|
// valid for every main-family draw that follows.
|
|
1996
1996
|
this.pipeline.setEntityColorTableBuffer(this.scene.getEntityColorTable().getBuffer());
|
|
1997
1997
|
pass.setBindGroup(1, this.pipeline.getEnvironmentBindGroup());
|
|
1998
|
+
pass.setBindGroup(3, sectionExclusions(device).bindGroup);
|
|
1998
1999
|
// Selected meshes drawn this frame, for the selection-mask pass
|
|
1999
2000
|
// (#5390) after `pass.end()` below. Populated inside the batched
|
|
2000
2001
|
// branch, where the highlight draw itself happens; empty in the
|
|
@@ -2183,9 +2184,6 @@ export class Renderer {
|
|
|
2183
2184
|
if (partialEpochChanged) {
|
|
2184
2185
|
this.scene.retireUnusedAlphaSlots(partialRequests.requestedKeys());
|
|
2185
2186
|
}
|
|
2186
|
-
// Build a uniform template ONCE per frame — shared across all batches.
|
|
2187
|
-
// Only the 4-float color (offset 32) differs per batch; everything else
|
|
2188
|
-
// (viewProj, identity model, material, section plane, flags) is identical.
|
|
2189
2187
|
const tpl = this.uniformScratch;
|
|
2190
2188
|
const tplFlags = this.uniformScratchU32;
|
|
2191
2189
|
tpl.set(viewProj, 0);
|
|
@@ -2211,18 +2209,7 @@ export class Renderer {
|
|
|
2211
2209
|
// Colour + material row (tpl[32..39]) are patched per draw; the
|
|
2212
2210
|
// instanced passes keep this opaque default.
|
|
2213
2211
|
packMeshMaterial(tpl);
|
|
2214
|
-
|
|
2215
|
-
tpl[40] = sectionPlaneData.normal[0];
|
|
2216
|
-
tpl[41] = sectionPlaneData.normal[1];
|
|
2217
|
-
tpl[42] = sectionPlaneData.normal[2];
|
|
2218
|
-
tpl[43] = sectionPlaneData.distance;
|
|
2219
|
-
}
|
|
2220
|
-
else {
|
|
2221
|
-
tpl[40] = 0;
|
|
2222
|
-
tpl[41] = 0;
|
|
2223
|
-
tpl[42] = 0;
|
|
2224
|
-
tpl[43] = 0;
|
|
2225
|
-
}
|
|
2212
|
+
packSectionPlaneLanes(sectionPlaneData, tpl);
|
|
2226
2213
|
// Clip box (offset 48-55: min.xyz + pad, max.xyz + pad) → enable bit
|
|
2227
2214
|
const tplClipBit = packClipBox(options.clipBox, tpl, 48);
|
|
2228
2215
|
// flags layout (main shader):
|
|
@@ -2243,7 +2230,7 @@ export class Renderer {
|
|
|
2243
2230
|
// camera-relative frame. Their fragment clip inputs must use
|
|
2244
2231
|
// that same frame; mixing a local vertex with a 5,000 km f32
|
|
2245
2232
|
// world plane loses centimetre cuts before the comparison.
|
|
2246
|
-
packRteFragmentSpace(relativeToEyeFrame, sectionPlaneData, options.clipBox, tpl);
|
|
2233
|
+
packRteFragmentSpace(relativeToEyeFrame, sectionPlaneData, options.clipBox, tpl, extraClipPlanes);
|
|
2247
2234
|
// Helper function to render a batch — patches color into the shared template.
|
|
2248
2235
|
// `paint` = a depth-writing opaque draw: colour overrides shade it from the
|
|
2249
2236
|
// entity colour table (#6076); transparent draws keep their own colour.
|
|
@@ -2257,12 +2244,7 @@ export class Renderer {
|
|
|
2257
2244
|
tpl[34] = batch.color[2];
|
|
2258
2245
|
tpl[35] = alphaForBatch(batch, batch.color[3]);
|
|
2259
2246
|
packMeshMaterial(tpl, batch.color[3], batch.finish);
|
|
2260
|
-
//
|
|
2261
|
-
// RELATIVE to batch.origin (f32-small), so set the model
|
|
2262
|
-
// matrix translation column to origin (world = origin + pos).
|
|
2263
|
-
// The 12 rotation/scale floats stay identity from the template;
|
|
2264
|
-
// the translation lives at column-major indices 12/13/14 →
|
|
2265
|
-
// tpl[28/29/30]. [0,0,0] for legacy absolute batches.
|
|
2247
|
+
// Rebase batch-local vertices; translation lives in tpl[28..30].
|
|
2266
2248
|
const o = batch.origin;
|
|
2267
2249
|
tpl[28] = o ? o[0] : 0;
|
|
2268
2250
|
tpl[29] = o ? o[1] : 0;
|
|
@@ -2281,7 +2263,8 @@ export class Renderer {
|
|
|
2281
2263
|
tpl[58] = qz ? qz.min[2] : 0;
|
|
2282
2264
|
tpl[59] = qz ? qz.step : 0;
|
|
2283
2265
|
const painted = paint && batchHasColorOverride(batch, colorOverrides, colorOverrideGen);
|
|
2284
|
-
packOverrideParams(this.uniformOverrideU32,
|
|
2266
|
+
packOverrideParams(this.uniformOverrideU32, batchEntityIdAnchor(batch), painted, options.emphasizeOverrides === true);
|
|
2267
|
+
this.uniformOverrideU32[0] = batchEntityIdAnchor(batch) ?? 0xFFFFFFFF;
|
|
2285
2268
|
device.queue.writeBuffer(batch.uniformBuffer, 0, tpl);
|
|
2286
2269
|
this.uniformOverrideU32.fill(0);
|
|
2287
2270
|
// Single draw call for entire batch! LOD1-selected batches
|
|
@@ -2385,6 +2368,7 @@ export class Renderer {
|
|
|
2385
2368
|
pass.setPipeline(this.pipeline.getInstancedPipeline());
|
|
2386
2369
|
pass.setBindGroup(0, this.pipeline.getBindGroup());
|
|
2387
2370
|
pass.setBindGroup(1, this.pipeline.getEnvironmentBindGroup());
|
|
2371
|
+
pass.setBindGroup(3, sectionExclusions(device).bindGroup);
|
|
2388
2372
|
for (const [i, it] of visibleInstanced.entries()) {
|
|
2389
2373
|
pass.setVertexBuffer(0, it.vertexBuffer);
|
|
2390
2374
|
pass.setVertexBuffer(1, it.instanceBuffer);
|
|
@@ -2460,6 +2444,7 @@ export class Renderer {
|
|
|
2460
2444
|
// CHOICE in the shader follows the same rule as everywhere
|
|
2461
2445
|
// else, for the same reason `tm.material` does.
|
|
2462
2446
|
packMeshMaterial(tpl, tm.color[3], tm.finish ?? tm.material);
|
|
2447
|
+
this.uniformOverrideU32[0] = tm.expressId;
|
|
2463
2448
|
device.queue.writeBuffer(tm.uniformBuffer, 0, tpl);
|
|
2464
2449
|
pass.setBindGroup(0, tm.bindGroup);
|
|
2465
2450
|
pass.setVertexBuffer(0, tm.vertexBuffer);
|
|
@@ -2585,6 +2570,7 @@ export class Renderer {
|
|
|
2585
2570
|
pass.setPipeline(instancedTransparentPipeline);
|
|
2586
2571
|
pass.setBindGroup(0, this.pipeline.getBindGroup());
|
|
2587
2572
|
pass.setBindGroup(1, this.pipeline.getEnvironmentBindGroup());
|
|
2573
|
+
pass.setBindGroup(3, sectionExclusions(device).bindGroup);
|
|
2588
2574
|
for (const [i, it] of visibleInstanced.entries()) {
|
|
2589
2575
|
pass.setVertexBuffer(0, it.vertexBuffer);
|
|
2590
2576
|
pass.setVertexBuffer(1, it.instanceBuffer);
|
|
@@ -2616,18 +2602,7 @@ export class Renderer {
|
|
|
2616
2602
|
tpl[34] = mesh.color[2];
|
|
2617
2603
|
tpl[35] = alphaForMesh(mesh.expressId, mesh.color[3]);
|
|
2618
2604
|
packMeshMaterial(tpl, mesh.color[3], mesh.finish ?? mesh.material);
|
|
2619
|
-
|
|
2620
|
-
tpl[40] = sectionPlaneData.normal[0];
|
|
2621
|
-
tpl[41] = sectionPlaneData.normal[1];
|
|
2622
|
-
tpl[42] = sectionPlaneData.normal[2];
|
|
2623
|
-
tpl[43] = sectionPlaneData.distance;
|
|
2624
|
-
}
|
|
2625
|
-
else {
|
|
2626
|
-
tpl[40] = 0;
|
|
2627
|
-
tpl[41] = 0;
|
|
2628
|
-
tpl[42] = 0;
|
|
2629
|
-
tpl[43] = 0;
|
|
2630
|
-
}
|
|
2605
|
+
packSectionPlaneLanes(sectionPlaneData, tpl);
|
|
2631
2606
|
tplFlags[0] = 0;
|
|
2632
2607
|
tplFlags[1] =
|
|
2633
2608
|
(sectionPlaneData?.enabled ? 1 : 0) |
|
|
@@ -2635,11 +2610,12 @@ export class Renderer {
|
|
|
2635
2610
|
tplClipBit;
|
|
2636
2611
|
tplFlags[2] = 0;
|
|
2637
2612
|
tplFlags[3] = 0;
|
|
2638
|
-
packRteFragmentSpace(relativeToEyeFrame, sectionPlaneData, options.clipBox, tpl);
|
|
2613
|
+
packRteFragmentSpace(relativeToEyeFrame, sectionPlaneData, options.clipBox, tpl, extraClipPlanes);
|
|
2639
2614
|
const transparentOrigin = mesh.rteOrigin ?? [mesh.transform.m[12], mesh.transform.m[13], mesh.transform.m[14]];
|
|
2640
2615
|
if (!relativeToEyeFrame.tryPackDrawableOrigin(transparentOrigin, tpl, MESH_UNIFORM_OFFSET.drawableDelta))
|
|
2641
2616
|
continue;
|
|
2642
2617
|
tplFlags[0] |= MESH_FLAG_RTE_DRAWABLE;
|
|
2618
|
+
this.uniformOverrideU32[0] = mesh.expressId;
|
|
2643
2619
|
device.queue.writeBuffer(mesh.uniformBuffer, 0, tpl);
|
|
2644
2620
|
pass.setBindGroup(0, mesh.bindGroup);
|
|
2645
2621
|
pass.setVertexBuffer(0, mesh.vertexBuffer);
|
|
@@ -2678,18 +2654,7 @@ export class Renderer {
|
|
|
2678
2654
|
tpl[34] = mesh.color[2];
|
|
2679
2655
|
tpl[35] = mesh.color[3];
|
|
2680
2656
|
packMeshMaterial(tpl, mesh.color[3], mesh.finish ?? mesh.material);
|
|
2681
|
-
|
|
2682
|
-
tpl[40] = sectionPlaneData.normal[0];
|
|
2683
|
-
tpl[41] = sectionPlaneData.normal[1];
|
|
2684
|
-
tpl[42] = sectionPlaneData.normal[2];
|
|
2685
|
-
tpl[43] = sectionPlaneData.distance;
|
|
2686
|
-
}
|
|
2687
|
-
else {
|
|
2688
|
-
tpl[40] = 0;
|
|
2689
|
-
tpl[41] = 0;
|
|
2690
|
-
tpl[42] = 0;
|
|
2691
|
-
tpl[43] = 0;
|
|
2692
|
-
}
|
|
2657
|
+
packSectionPlaneLanes(sectionPlaneData, tpl);
|
|
2693
2658
|
tplFlags[0] = 1; // isSelected
|
|
2694
2659
|
tplFlags[1] =
|
|
2695
2660
|
(sectionPlaneData?.enabled ? 1 : 0) |
|
|
@@ -2697,11 +2662,12 @@ export class Renderer {
|
|
|
2697
2662
|
tplClipBit;
|
|
2698
2663
|
tplFlags[2] = 0;
|
|
2699
2664
|
tplFlags[3] = 0;
|
|
2700
|
-
packRteFragmentSpace(relativeToEyeFrame, sectionPlaneData, options.clipBox, tpl);
|
|
2665
|
+
packRteFragmentSpace(relativeToEyeFrame, sectionPlaneData, options.clipBox, tpl, extraClipPlanes);
|
|
2701
2666
|
const selectedOrigin = mesh.rteOrigin ?? [mesh.transform.m[12], mesh.transform.m[13], mesh.transform.m[14]];
|
|
2702
2667
|
if (!relativeToEyeFrame.tryPackDrawableOrigin(selectedOrigin, tpl, MESH_UNIFORM_OFFSET.drawableDelta))
|
|
2703
2668
|
continue;
|
|
2704
2669
|
tplFlags[0] |= MESH_FLAG_RTE_DRAWABLE;
|
|
2670
|
+
this.uniformOverrideU32[0] = mesh.expressId;
|
|
2705
2671
|
device.queue.writeBuffer(mesh.uniformBuffer, 0, tpl);
|
|
2706
2672
|
pass.setPipeline(this.pipeline.getSelectionPipeline());
|
|
2707
2673
|
pass.setBindGroup(0, mesh.bindGroup);
|
|
@@ -2759,6 +2725,7 @@ export class Renderer {
|
|
|
2759
2725
|
? { ...sectionPlaneData, flipped: options.sectionPlane?.flipped === true }
|
|
2760
2726
|
: null,
|
|
2761
2727
|
clipBox: options.clipBox,
|
|
2728
|
+
extraPlanes: extraClipPlanes,
|
|
2762
2729
|
viewport: { width: this.canvas.width / this.pixelRatio, height: this.canvas.height / this.pixelRatio },
|
|
2763
2730
|
});
|
|
2764
2731
|
}
|
|
@@ -2776,6 +2743,8 @@ export class Renderer {
|
|
|
2776
2743
|
relativeToEyeFrame,
|
|
2777
2744
|
rteViewProj: relativeToEyeFrame.getViewProjection().m,
|
|
2778
2745
|
rteCamera: relativeToEyeFrame.getCameraWorld(),
|
|
2746
|
+
extraPlanes: extraClipPlanes,
|
|
2747
|
+
primaryPlane: sectionPlaneData && options.sectionPlane?.enabled ? { ...sectionPlaneData, flipped: options.sectionPlane.flipped === true } : null,
|
|
2779
2748
|
});
|
|
2780
2749
|
pass.end();
|
|
2781
2750
|
// Selection/hover outline input (#5390): built from the meshes the
|
|
@@ -2790,7 +2759,7 @@ export class Renderer {
|
|
|
2790
2759
|
: (this.hoverMeshes.release(), []);
|
|
2791
2760
|
const selectionOutline = buildSelectionOutlineFrame({
|
|
2792
2761
|
uniformBufferSize: this.pipeline.getUniformBufferSize(), viewProj, relativeToEyeFrame,
|
|
2793
|
-
section: sectionPlaneData, sectionFlipped: options.sectionPlane?.flipped, clipBox: options.clipBox,
|
|
2762
|
+
section: sectionPlaneData, sectionFlipped: options.sectionPlane?.flipped, clipBox: options.clipBox, extraPlanes: extraClipPlanes,
|
|
2794
2763
|
selectedMeshes: selectedMeshesForMask, hoverPieces, hoveredId: hoverId, selectedModelIndex: hoverModel,
|
|
2795
2764
|
instancedTemplates: this.scene.getInstancedTemplates(),
|
|
2796
2765
|
instancedHovered: hoverId != null ? this.scene.getInstancedTemplatesOf(hoverId, hoverModel) : [],
|
|
@@ -2812,7 +2781,7 @@ export class Renderer {
|
|
|
2812
2781
|
pixelRatio: this.pixelRatio,
|
|
2813
2782
|
// EDL only when point clouds are loaded and the user enabled it.
|
|
2814
2783
|
edl: this.edlOptions.enabled && this.pointCloudRenderer?.hasAssets() ? this.edlOptions : null,
|
|
2815
|
-
selectionOutline,
|
|
2784
|
+
selectionOutline, geometricVisibility: this.pipeline.visibility.getBinding(),
|
|
2816
2785
|
});
|
|
2817
2786
|
colorReadback = colorCapture && encodeRendererColorFrameCapture(device, encoder, colorCapture);
|
|
2818
2787
|
submitRendererGpuTiming(this, device, encoder);
|
|
@@ -2880,8 +2849,10 @@ export class Renderer {
|
|
|
2880
2849
|
// `getOrCreatePartialBatch`'s CPU-side geometry merge running out of
|
|
2881
2850
|
// host memory, and that throws a `RangeError` — which is exactly why
|
|
2882
2851
|
// the discriminator keys on the TYPE and not on "a frame threw".
|
|
2883
|
-
this.containFrameThrow(error, 'encode');
|
|
2884
2852
|
cancelRendererColorFrame(this);
|
|
2853
|
+
if (deferOpaqueVisibilityFrame(error, () => this.requestRender()))
|
|
2854
|
+
return false;
|
|
2855
|
+
this.containFrameThrow(error, 'encode');
|
|
2885
2856
|
return false;
|
|
2886
2857
|
}
|
|
2887
2858
|
}
|
|
@@ -2926,7 +2897,7 @@ export class Renderer {
|
|
|
2926
2897
|
* same fragments and clipped-away geometry can't be selected.
|
|
2927
2898
|
*/
|
|
2928
2899
|
activePickClip() {
|
|
2929
|
-
return { sectionPlane: this._activePickSection, clipBox: this._activePickClipBox };
|
|
2900
|
+
return { sectionExcludedIds: this._sectionExcludedIds, sectionPlane: this._activePickSection, extraPlanes: this._activePickExtraPlanes, clipBox: this._activePickClipBox };
|
|
2930
2901
|
}
|
|
2931
2902
|
/**
|
|
2932
2903
|
* GPU-based rectangle pick. Drag-select returns the set of
|
|
@@ -2946,7 +2917,7 @@ export class Renderer {
|
|
|
2946
2917
|
}
|
|
2947
2918
|
/** Whether the last rendered frame clipped surfaces (section, terrain or box). */
|
|
2948
2919
|
hasActiveClipping() {
|
|
2949
|
-
return this._activePickSection !== null || this._activePickClipBox !== null;
|
|
2920
|
+
return this._activePickSection !== null || this._activePickExtraPlanes !== null || this._activePickClipBox !== null;
|
|
2950
2921
|
}
|
|
2951
2922
|
/** Exact visible-surface raycast in CSS canvas coordinates. */
|
|
2952
2923
|
raycastScene(x, y, options) {
|
|
@@ -3059,14 +3030,21 @@ export class Renderer {
|
|
|
3059
3030
|
*/
|
|
3060
3031
|
uploadSection2DOverlay(polygons, lines, axis, position, // 0-100 percentage
|
|
3061
3032
|
sectionRange, // Same storey-based range as section plane
|
|
3062
|
-
flipped = false, customPlane) {
|
|
3063
|
-
this.overlays.uploadSection2DOverlay(polygons, lines, axis, position, sectionRange, flipped, customPlane);
|
|
3033
|
+
flipped = false, customPlane, planeId) {
|
|
3034
|
+
this.overlays.uploadSection2DOverlay(polygons, lines, axis, position, sectionRange, flipped, customPlane, planeId);
|
|
3064
3035
|
}
|
|
3065
3036
|
/**
|
|
3066
|
-
* Clear the 2D section overlay
|
|
3037
|
+
* Clear the 2D section overlay: the primary plane's cap, or with `planeId`
|
|
3038
|
+
* the cap of that cutting plane beyond the first (#7545).
|
|
3067
3039
|
*/
|
|
3068
|
-
clearSection2DOverlay() {
|
|
3069
|
-
this.overlays.clearSection2DOverlay();
|
|
3040
|
+
clearSection2DOverlay(planeId) {
|
|
3041
|
+
this.overlays.clearSection2DOverlay(planeId);
|
|
3042
|
+
}
|
|
3043
|
+
/** Every section plane's world frame (#7545), for the UI's tags and handle: the last frame's bounds and rotation, and `planes` (the caller's newest) when given. */
|
|
3044
|
+
getSectionPlaneFrames(planes) { const i = this._sectionFrameInput; return i ? resolveSectionPlaneFrames(planes ? { ...i, ...planes } : i) : []; }
|
|
3045
|
+
/** Clear the caps of every cutting plane beyond the first whose id is not in `keep` (#7545). */
|
|
3046
|
+
clearSection2DExtraOverlays(keep = []) {
|
|
3047
|
+
this.overlays.clearSection2DExtraOverlays(keep);
|
|
3070
3048
|
}
|
|
3071
3049
|
/**
|
|
3072
3050
|
* Set the one colour vocabulary every overlay draws in (#5484): the selection
|
|
@@ -3300,6 +3278,7 @@ export class Renderer {
|
|
|
3300
3278
|
// Render pipelines (textures + uniform buffers)
|
|
3301
3279
|
this.pipeline?.destroy();
|
|
3302
3280
|
this.pipeline = null;
|
|
3281
|
+
this.scene.setQuantizedBatches(false);
|
|
3303
3282
|
// Picker GPU resources. The manager holds its own reference, so clear
|
|
3304
3283
|
// that too — otherwise its `if (!this.picker) return null` guard keeps
|
|
3305
3284
|
// pointing at a destroyed picker and a stray click still drives dead
|
|
@@ -3334,7 +3313,7 @@ export class Renderer {
|
|
|
3334
3313
|
// above was created from it and has already been destroyed, so nothing
|
|
3335
3314
|
// will touch the device after this. Without it, an app that spins up a
|
|
3336
3315
|
// renderer per model keeps N live devices (and their VRAM) alive. The
|
|
3337
|
-
// lost-handler
|
|
3316
|
+
// lost-handler excludes this retired lifetime so this is not reported
|
|
3338
3317
|
// as a fault. render() early-returns while the device is uninitialised.
|
|
3339
3318
|
this.device.destroy();
|
|
3340
3319
|
}
|