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