viral-viewer-2 7.2.4 → 7.2.6

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.
@@ -2,6 +2,11 @@ import { Box3, BufferGeometry, type Color, type Material, Mesh, Vector3 } from "
2
2
  import { type LineMaterial } from "three/examples/jsm/Addons";
3
3
  import { type BufferElement } from "../..";
4
4
  import type { WorkerThreadPool } from "../worker/base/worker-pool";
5
+ /**
6
+ * Special alpha value to mark selected vertices for fast outline detection.
7
+ * The AlphaSelectionOutlinePass detects this value with ZERO extra render passes.
8
+ */
9
+ export declare const SELECTION_ALPHA = 0.99;
5
10
  export declare class ViralBatchedMesh extends Mesh {
6
11
  globalMaterialIndex: number;
7
12
  private workerPool;
@@ -110,6 +115,13 @@ export declare class ViralBatchedMesh extends Mesh {
110
115
  elementId: string;
111
116
  }[];
112
117
  unselect(): void;
118
+ /**
119
+ * Set alpha value for elements (used for selection marking)
120
+ * This is VERY fast - only updates alpha channel, no geometry copying
121
+ *
122
+ * When setting alpha to 1.0 (removing selection), respects hidden/isolated state
123
+ */
124
+ private _setSelectionAlpha;
113
125
  /**
114
126
  * Hide elements by setting their alpha to 0 (GPU-accelerated)
115
127
  * Hidden elements are discarded in fragment shader - no rendering cost
@@ -11,7 +11,6 @@ import { ViralInstancedMeshV2 } from "./viral-instanced-mesh-v2";
11
11
  */
12
12
  export declare class ViralBIMWorld extends Mesh {
13
13
  workerPool: WorkerThreadPool | null;
14
- private _mergePositionsWorker;
15
14
  bimModels: ViralBIMModel[];
16
15
  constructor();
17
16
  private _initializeWorkerPool;
@@ -99,11 +98,6 @@ export declare class ViralBIMWorld extends Mesh {
99
98
  * @returns Float32Array of positions or null if no selection
100
99
  */
101
100
  getSelectedElementsPositions(): Float32Array | null;
102
- /**
103
- * Async version — offloads vertex merging to a Web Worker so the main thread stays unblocked.
104
- * Automatically cancels any in-flight request when called again.
105
- */
106
- getSelectedElementsPositionsAsync(): Promise<Float32Array | null>;
107
101
  /**
108
102
  * Changes the color of multiple elements in the merged mesh.
109
103
  * Works with RGBA color buffer (preserves existing alpha values)
@@ -1,6 +1,11 @@
1
1
  import { Box3, BufferGeometry, Color, InstancedMesh, type Material, Matrix4, Object3D, Vector3 } from "three";
2
2
  import { type LineMaterial } from "three/examples/jsm/Addons";
3
3
  import { type BufferElement } from "../..";
4
+ /**
5
+ * Special alpha value to mark selected instances for fast outline detection.
6
+ * Note: Instanced meshes use a separate instanceSelected attribute instead of alpha.
7
+ */
8
+ export declare const SELECTION_ALPHA = 0.99;
4
9
  export declare class ViralInstancedMeshV2 extends Object3D {
5
10
  protected material?: Material | undefined;
6
11
  globalMaterialIndex: number;
@@ -51,6 +56,12 @@ export declare class ViralInstancedMeshV2 extends Object3D {
51
56
  };
52
57
  }[]): void;
53
58
  unselect(): void;
59
+ /**
60
+ * Set instance selection state for fast outline detection
61
+ * @param elements - Elements to set selection for
62
+ * @param selected - 1.0 = selected, 0.0 = not selected
63
+ */
64
+ private _setInstanceSelection;
54
65
  /**
55
66
  * Changes the color of multiple elements.
56
67
  * @param elements - An array of elements, each containing `modelId` and `elementId`.
@@ -163,7 +174,10 @@ export declare class ViralInstancedMeshV2 extends Object3D {
163
174
  */
164
175
  isElementVisible(modelId: string, elementId: string): boolean;
165
176
  /**
166
- * Inject per-instance opacity shader into material
177
+ * Inject per-instance opacity and selection shader into material
178
+ * Enables:
179
+ * - Per-instance opacity (ghosting, hiding)
180
+ * - Selection alpha marker (for fast outline detection via AlphaSelectionOutlinePass)
167
181
  * Must be called after material is set and before rendering
168
182
  */
169
183
  injectOpacityShader(): void;
@@ -171,6 +185,11 @@ export declare class ViralInstancedMeshV2 extends Object3D {
171
185
  * Ensure all instanced meshes have opacity attribute
172
186
  */
173
187
  private _ensureOpacityAttributes;
188
+ /**
189
+ * Ensure all instanced meshes have selection attribute
190
+ * Used for fast outline detection via AlphaSelectionOutlinePass
191
+ */
192
+ private _ensureSelectionAttributes;
174
193
  /**
175
194
  * Update opacity for specific instances
176
195
  */
@@ -0,0 +1,49 @@
1
+ import type { WebGLRenderer } from "three";
2
+ import { Color, type Vector2, type WebGLRenderTarget } from "three";
3
+ import { Pass } from "three/examples/jsm/postprocessing/Pass";
4
+ /**
5
+ * Alpha-Based Selection Outline Pass (FASTEST)
6
+ *
7
+ * This is the FASTEST possible selection outline implementation because:
8
+ * - ZERO extra render passes for selection mask
9
+ * - ZERO geometry copying
10
+ * - O(pixels) cost - same for 1 or 10,000 selected elements
11
+ *
12
+ * How it works:
13
+ * 1. Selected elements have their alpha set to a special value (SELECTION_ALPHA = 0.99)
14
+ * 2. This pass detects edges where alpha equals SELECTION_ALPHA
15
+ * 3. Applies outline effect at those edges
16
+ *
17
+ * Requirements:
18
+ * - ViralBatchedMesh/ViralInstancedMesh must set alpha = 0.99 for selected vertices
19
+ * - Must run after main render pass but before tone mapping
20
+ */
21
+ export interface AlphaSelectionOutlineOptions {
22
+ /** Outline color (default: accent color) */
23
+ outlineColor: Color;
24
+ /** Outline opacity 0-1 (default: 1.0) */
25
+ outlineOpacity: number;
26
+ /** Outline thickness in pixels (default: 2.0) */
27
+ outlineThickness: number;
28
+ /** Alpha value that indicates selection (default: 0.99) */
29
+ selectionAlpha: number;
30
+ /** Tolerance for alpha detection (default: 0.005) */
31
+ alphaTolerance: number;
32
+ }
33
+ export declare const SELECTION_ALPHA = 0.99;
34
+ export declare class AlphaSelectionOutlinePass extends Pass {
35
+ private resolution;
36
+ private options;
37
+ private outlineMaterial;
38
+ private copyMaterial;
39
+ private fsQuad;
40
+ /** Fast bypass during camera movement */
41
+ bypass: boolean;
42
+ /** Whether there's any selection active */
43
+ hasSelection: boolean;
44
+ constructor(resolution: Vector2, options?: Partial<AlphaSelectionOutlineOptions>);
45
+ setOptions(options: Partial<AlphaSelectionOutlineOptions>): void;
46
+ render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, _deltaTime?: number, _maskActive?: boolean): void;
47
+ setSize(width: number, height: number): void;
48
+ dispose(): void;
49
+ }
@@ -6,6 +6,7 @@ import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass";
6
6
  import { SMAAPass } from "three/examples/jsm/postprocessing/SMAAPass";
7
7
  import { type ViralViewerApi } from "../..";
8
8
  import { DevicePerformanceChecker } from "../../utils/device";
9
+ import { AlphaSelectionOutlinePass } from "./alpha-selection-outline-pass";
9
10
  import { type ScreenSpaceEdgesOptions, ScreenSpaceEdgesPass } from "./screen-space-edges-pass";
10
11
  import { type SelectionOutlineOptions, SelectionOutlinePass } from "./selection-outline-pass";
11
12
  export declare class PostProcessingRenderer {
@@ -26,6 +27,7 @@ export declare class PostProcessingRenderer {
26
27
  outlinePass: OutlinePass | null;
27
28
  screenSpaceEdgesPass: ScreenSpaceEdgesPass | null;
28
29
  selectionOutlinePass: SelectionOutlinePass | null;
30
+ alphaSelectionOutlinePass: AlphaSelectionOutlinePass | null;
29
31
  n8aoPass: any;
30
32
  perfChecker: DevicePerformanceChecker;
31
33
  constructor(renderer: WebGLRenderer, viralViewerApi: ViralViewerApi);
@@ -127,6 +129,11 @@ export declare class PostProcessingRenderer {
127
129
  * @param positions - Merged Float32Array of selected element positions, or null to clear
128
130
  */
129
131
  updateSelectionOutline(positions: Float32Array | null): void;
132
+ /**
133
+ * Notify the outline pass whether elements are currently selected.
134
+ * The GPU reads selection state directly from vertex colors — no data transfer needed.
135
+ */
136
+ setSelectionOutlineActive(hasSelection: boolean): void;
130
137
  /**
131
138
  * Enable selection outline rendering
132
139
  */
@@ -158,4 +165,43 @@ export declare class PostProcessingRenderer {
158
165
  * Set selection outline thickness in pixels
159
166
  */
160
167
  setSelectionOutlineThickness(thickness: number): void;
168
+ /**
169
+ * Initialize alpha-based selection outline pass
170
+ * ZERO extra render passes - detects selection via alpha channel in main render
171
+ * Cost: 1 fullscreen pass only (no geometry re-render)
172
+ *
173
+ * This is MUCH faster than SelectionOutlinePass for large selections
174
+ * Works with both batched meshes (per-vertex alpha) and instanced meshes (per-instance alpha)
175
+ */
176
+ initAlphaSelectionOutlinePass(): void;
177
+ /**
178
+ * Enable alpha selection outline rendering
179
+ */
180
+ enableAlphaSelectionOutline(): void;
181
+ /**
182
+ * Disable alpha selection outline rendering
183
+ */
184
+ disableAlphaSelectionOutline(): void;
185
+ /**
186
+ * Bypass alpha selection outline (instant, zero cost)
187
+ */
188
+ bypassAlphaSelectionOutline(): void;
189
+ /**
190
+ * Resume alpha selection outline after bypassing
191
+ */
192
+ resumeAlphaSelectionOutline(): void;
193
+ /**
194
+ * Set alpha selection outline color
195
+ */
196
+ setAlphaSelectionOutlineColor(color: Color | number | string): void;
197
+ /**
198
+ * Set alpha selection outline thickness in pixels
199
+ */
200
+ setAlphaSelectionOutlineThickness(thickness: number): void;
201
+ /**
202
+ * Update alpha selection outline state
203
+ * Call this when selection changes
204
+ * @param hasSelection - Whether there's any selection active
205
+ */
206
+ updateAlphaSelectionOutline(hasSelection: boolean): void;
161
207
  }
@@ -1,14 +1,17 @@
1
- import type { Camera, WebGLRenderer } from "three";
2
- import { Color, Scene, type Vector2, WebGLRenderTarget } from "three";
1
+ import type { Camera, Vector2, WebGLRenderer } from "three";
2
+ import { Color, type Scene, WebGLRenderTarget } from "three";
3
3
  import { Pass } from "three/examples/jsm/postprocessing/Pass";
4
4
  /**
5
5
  * Selection Outline Pass
6
6
  *
7
- * Lightweight outline effect for selected elements in merged geometry.
8
- * Cost: 1 extra draw call (for mask) + 1 fullscreen Sobel pass
7
+ * GPU-based outline effect for selected elements.
8
+ * Renders the scene with a filter shader that outputs white only for
9
+ * fragments matching the selection color — zero CPU vertex work.
10
+ *
11
+ * Cost: 1-2 extra draw calls (mask render with overrideMaterial) + 1 fullscreen Sobel pass
9
12
  *
10
13
  * Process:
11
- * 1. Render selected geometry to mask texture (white on black)
14
+ * 1. Render entire scene with overrideMaterial that filters by SELECT_COLOR
12
15
  * 2. Sobel edge detection on mask
13
16
  * 3. Composite colored edges over scene
14
17
  */
@@ -25,32 +28,33 @@ export interface SelectionOutlineOptions {
25
28
  occludedOpacity: number;
26
29
  }
27
30
  export declare class SelectionOutlinePass extends Pass {
31
+ private scene;
28
32
  private camera;
29
33
  private resolution;
30
34
  private options;
31
35
  private maskRenderTarget;
32
36
  private maskDepthRenderTarget;
33
- private maskMaterial;
37
+ private selectionFilterMaterial;
38
+ private selectionFilterMaterialDepth;
34
39
  private outlineMaterial;
35
40
  private copyMaterial;
36
- private maskScene;
37
- private selectionMesh;
38
- private selectionGeometry;
39
- private selectionBuffer;
40
- private selectionAttribute;
41
41
  private fsQuad;
42
42
  private hasSelection;
43
43
  /**
44
- * 🔧 FAST TOGGLE:
44
+ * FAST TOGGLE:
45
45
  * - `bypass = false`: Full outline rendering (normal mode)
46
46
  * - `bypass = true`: Pass runs but just copies input to output (very fast, no mask render)
47
47
  */
48
48
  bypass: boolean;
49
- constructor(_scene: Scene, camera: Camera, resolution: Vector2, options?: Partial<SelectionOutlineOptions>);
49
+ constructor(scene: Scene, camera: Camera, resolution: Vector2, options?: Partial<SelectionOutlineOptions>);
50
+ /**
51
+ * Notify the pass whether there is an active selection.
52
+ * No data transfer needed — the GPU reads selection state from vertex colors.
53
+ */
54
+ setHasSelection(hasSelection: boolean): void;
50
55
  /**
51
- * Update selection geometry from buffer elements
52
- * Call this when selection changes
53
- * @param positions - Merged Float32Array of all selected element positions
56
+ * Legacy method kept for backward compatibility.
57
+ * With the GPU-based approach, this just toggles hasSelection.
54
58
  */
55
59
  updateSelectionGeometry(positions: Float32Array | null): void;
56
60
  /**
@@ -62,6 +66,7 @@ export declare class SelectionOutlinePass extends Pass {
62
66
  */
63
67
  setOptions(options: Partial<SelectionOutlineOptions>): void;
64
68
  render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, _deltaTime?: number, _maskActive?: boolean): void;
69
+ private _renderCopyPass;
65
70
  setSize(width: number, height: number): void;
66
71
  dispose(): void;
67
72
  }
@@ -0,0 +1,54 @@
1
+ import type { WebGLRenderer } from "three";
2
+ import { Color, type Vector2, type WebGLRenderTarget } from "three";
3
+ import { Pass } from "three/examples/jsm/postprocessing/Pass";
4
+ /**
5
+ * Stencil-Based Selection Outline Pass (FAST)
6
+ *
7
+ * This is a MUCH faster alternative to geometry-based selection outline.
8
+ * Instead of copying vertex data, it reads from a selection mask texture
9
+ * that's been written to during the main render pass.
10
+ *
11
+ * Performance: O(pixels) instead of O(selected_vertices)
12
+ * - 1000 selected elements = same cost as 1 selected element
13
+ * - No geometry copying
14
+ * - No extra mesh rendering
15
+ *
16
+ * Requirements:
17
+ * - Selection mask must be written by ViralBatchedMesh/ViralInstancedMesh during render
18
+ * - Main renderer must call updateSelectionMask() before this pass runs
19
+ */
20
+ export interface StencilSelectionOutlineOptions {
21
+ /** Outline color (default: accent color) */
22
+ outlineColor: Color;
23
+ /** Outline opacity 0-1 (default: 1.0) */
24
+ outlineOpacity: number;
25
+ /** Outline thickness in pixels (default: 2.0) */
26
+ outlineThickness: number;
27
+ }
28
+ export declare class StencilSelectionOutlinePass extends Pass {
29
+ private resolution;
30
+ private options;
31
+ private selectionMaskTarget;
32
+ private outlineMaterial;
33
+ private copyMaterial;
34
+ private fsQuad;
35
+ bypass: boolean;
36
+ private hasSelection;
37
+ constructor(resolution: Vector2, options?: Partial<StencilSelectionOutlineOptions>);
38
+ /**
39
+ * Set the selection mask render target
40
+ * This should be called by the renderer after writing selection mask
41
+ */
42
+ setSelectionMaskTarget(target: WebGLRenderTarget | null): void;
43
+ /**
44
+ * Set whether there's an active selection
45
+ */
46
+ setHasSelection(value: boolean): void;
47
+ /**
48
+ * Update outline options
49
+ */
50
+ setOptions(options: Partial<StencilSelectionOutlineOptions>): void;
51
+ render(renderer: WebGLRenderer, writeBuffer: WebGLRenderTarget, readBuffer: WebGLRenderTarget, _deltaTime?: number, _maskActive?: boolean): void;
52
+ setSize(width: number, height: number): void;
53
+ dispose(): void;
54
+ }
@@ -5,15 +5,13 @@ export declare class ViralVisibilityManager {
5
5
  private viralViewerApi;
6
6
  /** Whether selection outline is enabled (default: true) */
7
7
  private _selectionOutlineEnabled;
8
- /** Whether an outline update is already scheduled for the next frame */
9
- private _outlineUpdateScheduled;
10
8
  constructor(viralViewerApi: ViralViewerApi);
11
9
  /**
12
10
  * show all elements and reset back to normal visualization
13
11
  */
14
12
  showAll2(): void;
15
13
  /**
16
- * hide all elements and reset back to normal visualization
14
+ * Hide all elements (sets all meshes invisible)
17
15
  */
18
16
  hideAllElements(): void;
19
17
  /**
@@ -170,11 +168,10 @@ export declare class ViralVisibilityManager {
170
168
  */
171
169
  updateSelectionOutline(): void;
172
170
  /**
173
- * Schedule outline update for the next animation frame.
174
- * Batches multiple rapid selection changes into a single update.
175
- * Uses Web Worker to avoid blocking the main thread.
171
+ * Notify the outline pass whether there is an active selection.
172
+ * The GPU reads selection state directly from vertex colors — no CPU work needed.
176
173
  */
177
- private scheduleOutlineUpdate;
174
+ private notifySelectionOutline;
178
175
  /**
179
176
  * Enable selection outline effect
180
177
  */
@@ -192,6 +189,40 @@ export declare class ViralVisibilityManager {
192
189
  * Get whether selection outline mode is enabled
193
190
  */
194
191
  get selectionOutlineEnabled(): boolean;
192
+ /** Whether alpha selection outline is enabled (default: false, as it requires opt-in) */
193
+ private _alphaSelectionOutlineEnabled;
194
+ /**
195
+ * Update alpha selection outline state
196
+ * This is MUCH faster than updateSelectionOutline() - no geometry copying needed
197
+ */
198
+ updateAlphaSelectionOutline(): void;
199
+ /**
200
+ * Enable alpha selection outline effect
201
+ * This is the FAST outline mode - constant cost regardless of selection size
202
+ */
203
+ enableAlphaSelectionOutline(): void;
204
+ /**
205
+ * Disable alpha selection outline effect
206
+ */
207
+ disableAlphaSelectionOutline(): void;
208
+ /**
209
+ * Set whether alpha selection outline mode is enabled
210
+ * This is the recommended mode for large selections (1000+ elements)
211
+ * @param enabled - true to enable, false to disable
212
+ */
213
+ setAlphaSelectionOutlineMode(enabled: boolean): void;
214
+ /**
215
+ * Get whether alpha selection outline mode is enabled
216
+ */
217
+ get alphaSelectionOutlineEnabled(): boolean;
218
+ /**
219
+ * Bypass alpha selection outline (fast, for camera movement)
220
+ */
221
+ bypassAlphaSelectionOutline(): void;
222
+ /**
223
+ * Resume alpha selection outline after bypass
224
+ */
225
+ resumeAlphaSelectionOutline(): void;
195
226
  enableNight(): void;
196
227
  disableNight(): void;
197
228
  enableSectionBox(): void;