vim-web 0.3.42 → 0.3.44-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/types/core-viewers/ultra/index.d.ts +1 -1
  2. package/dist/types/core-viewers/ultra/viewer/camera.d.ts +1 -13
  3. package/dist/types/core-viewers/ultra/viewer/marshal.d.ts +37 -24
  4. package/dist/types/core-viewers/ultra/viewer/rpcClient.d.ts +9 -7
  5. package/dist/types/core-viewers/ultra/viewer/rpcSafeClient.d.ts +8 -1
  6. package/dist/types/core-viewers/ultra/viewer/sectionBox.d.ts +31 -0
  7. package/dist/types/core-viewers/ultra/viewer/socketClient.d.ts +14 -5
  8. package/dist/types/core-viewers/ultra/viewer/viewer.d.ts +7 -3
  9. package/dist/types/core-viewers/webgl/loader/materials/ghostMaterial.d.ts +16 -0
  10. package/dist/types/core-viewers/webgl/loader/materials/simpleMaterial.d.ts +10 -5
  11. package/dist/types/core-viewers/webgl/loader/materials/viewerMaterials.d.ts +9 -8
  12. package/dist/types/core-viewers/webgl/loader/mesh.d.ts +2 -1
  13. package/dist/types/core-viewers/webgl/loader/progressive/insertableMesh.d.ts +2 -1
  14. package/dist/types/core-viewers/webgl/loader/progressive/instancedMesh.d.ts +3 -1
  15. package/dist/types/core-viewers/webgl/loader/scene.d.ts +3 -2
  16. package/dist/types/core-viewers/webgl/viewer/camera/ICamera.d.ts +102 -0
  17. package/dist/types/core-viewers/webgl/viewer/environment/cameraLight.d.ts +1 -1
  18. package/dist/types/core-viewers/webgl/viewer/environment/environment.d.ts +1 -7
  19. package/dist/types/core-viewers/webgl/viewer/environment/skybox.d.ts +1 -1
  20. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/SectionBoxMesh.d.ts +15 -0
  21. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBox.d.ts +55 -21
  22. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxGizmo.d.ts +13 -43
  23. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxHandle.d.ts +15 -0
  24. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxHandles.d.ts +19 -0
  25. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxInputs.d.ts +143 -28
  26. package/dist/types/core-viewers/webgl/viewer/gizmos/sectionBox/sectionBoxOutline.d.ts +15 -0
  27. package/dist/types/core-viewers/webgl/viewer/inputs/input.d.ts +4 -4
  28. package/dist/types/core-viewers/webgl/viewer/rendering/renderScene.d.ts +8 -4
  29. package/dist/types/core-viewers/webgl/viewer/rendering/renderer.d.ts +5 -9
  30. package/dist/types/core-viewers/webgl/viewer/selection.d.ts +1 -0
  31. package/dist/types/core-viewers/webgl/viewer/settings/viewerSettings.d.ts +4 -39
  32. package/dist/types/core-viewers/webgl/viewer/viewer.d.ts +1 -1
  33. package/dist/types/react-viewers/helpers/inputs.d.ts +1 -2
  34. package/dist/types/react-viewers/helpers/isolation.d.ts +91 -50
  35. package/dist/types/react-viewers/settings/settings.d.ts +3 -2
  36. package/dist/vim-web.iife.js +1507 -1199
  37. package/dist/vim-web.iife.js.map +1 -1
  38. package/dist/vim-web.js +1505 -1197
  39. package/dist/vim-web.js.map +1 -1
  40. package/package.json +1 -1
  41. package/dist/types/core-viewers/webgl/images.d.ts +0 -4
  42. package/dist/types/core-viewers/webgl/loader/materials/isolationMaterial.d.ts +0 -12
  43. package/dist/types/core-viewers/webgl/viewer/environment/groundPlane.d.ts +0 -25
  44. /package/dist/types/core-viewers/webgl/viewer/inputs/{keyboard.d.ts → keyboardHandler.d.ts} +0 -0
  45. /package/dist/types/core-viewers/webgl/viewer/inputs/{mouse.d.ts → mouseHandler.d.ts} +0 -0
  46. /package/dist/types/core-viewers/webgl/viewer/inputs/{touch.d.ts → touchHandler.d.ts} +0 -0
@@ -45349,6 +45349,7 @@ void main() {
45349
45349
  return this._value;
45350
45350
  }
45351
45351
  apply(value) {
45352
+ value ?? this.defaultValue;
45352
45353
  if (this._value === value) return false;
45353
45354
  this._value = value;
45354
45355
  if (!this._meshes) return false;
@@ -45716,9 +45717,15 @@ void main() {
45716
45717
  return this._visibleAttribute.value;
45717
45718
  }
45718
45719
  set visible(value) {
45720
+ var _a2;
45719
45721
  if (this._visibleAttribute.apply(value)) {
45720
45722
  this.vim.scene.setDirty();
45721
45723
  }
45724
+ if (value) {
45725
+ (_a2 = this._meshes) == null ? void 0 : _a2.forEach((m) => {
45726
+ m.mesh.mesh.visible = true;
45727
+ });
45728
+ }
45722
45729
  }
45723
45730
  /**
45724
45731
  * Gets or sets the display color of this object.
@@ -47157,6 +47164,154 @@ void main() {
47157
47164
  this.scene.dispose();
47158
47165
  }
47159
47166
  };
47167
+ function mergeGeometries(geometries, useGroups = false) {
47168
+ const isIndexed = geometries[0].index !== null;
47169
+ const attributesUsed = new Set(Object.keys(geometries[0].attributes));
47170
+ const morphAttributesUsed = new Set(Object.keys(geometries[0].morphAttributes));
47171
+ const attributes = {};
47172
+ const morphAttributes = {};
47173
+ const morphTargetsRelative = geometries[0].morphTargetsRelative;
47174
+ const mergedGeometry = new BufferGeometry();
47175
+ let offset = 0;
47176
+ for (let i2 = 0; i2 < geometries.length; ++i2) {
47177
+ const geometry = geometries[i2];
47178
+ let attributesCount = 0;
47179
+ if (isIndexed !== (geometry.index !== null)) {
47180
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i2 + ". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.");
47181
+ return null;
47182
+ }
47183
+ for (const name in geometry.attributes) {
47184
+ if (!attributesUsed.has(name)) {
47185
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i2 + '. All geometries must have compatible attributes; make sure "' + name + '" attribute exists among all geometries, or in none of them.');
47186
+ return null;
47187
+ }
47188
+ if (attributes[name] === void 0) attributes[name] = [];
47189
+ attributes[name].push(geometry.attributes[name]);
47190
+ attributesCount++;
47191
+ }
47192
+ if (attributesCount !== attributesUsed.size) {
47193
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i2 + ". Make sure all geometries have the same number of attributes.");
47194
+ return null;
47195
+ }
47196
+ if (morphTargetsRelative !== geometry.morphTargetsRelative) {
47197
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i2 + ". .morphTargetsRelative must be consistent throughout all geometries.");
47198
+ return null;
47199
+ }
47200
+ for (const name in geometry.morphAttributes) {
47201
+ if (!morphAttributesUsed.has(name)) {
47202
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i2 + ". .morphAttributes must be consistent throughout all geometries.");
47203
+ return null;
47204
+ }
47205
+ if (morphAttributes[name] === void 0) morphAttributes[name] = [];
47206
+ morphAttributes[name].push(geometry.morphAttributes[name]);
47207
+ }
47208
+ if (useGroups) {
47209
+ let count;
47210
+ if (isIndexed) {
47211
+ count = geometry.index.count;
47212
+ } else if (geometry.attributes.position !== void 0) {
47213
+ count = geometry.attributes.position.count;
47214
+ } else {
47215
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index " + i2 + ". The geometry must have either an index or a position attribute");
47216
+ return null;
47217
+ }
47218
+ mergedGeometry.addGroup(offset, count, i2);
47219
+ offset += count;
47220
+ }
47221
+ }
47222
+ if (isIndexed) {
47223
+ let indexOffset = 0;
47224
+ const mergedIndex = [];
47225
+ for (let i2 = 0; i2 < geometries.length; ++i2) {
47226
+ const index2 = geometries[i2].index;
47227
+ for (let j = 0; j < index2.count; ++j) {
47228
+ mergedIndex.push(index2.getX(j) + indexOffset);
47229
+ }
47230
+ indexOffset += geometries[i2].attributes.position.count;
47231
+ }
47232
+ mergedGeometry.setIndex(mergedIndex);
47233
+ }
47234
+ for (const name in attributes) {
47235
+ const mergedAttribute = mergeAttributes(attributes[name]);
47236
+ if (!mergedAttribute) {
47237
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the " + name + " attribute.");
47238
+ return null;
47239
+ }
47240
+ mergedGeometry.setAttribute(name, mergedAttribute);
47241
+ }
47242
+ for (const name in morphAttributes) {
47243
+ const numMorphTargets = morphAttributes[name][0].length;
47244
+ if (numMorphTargets === 0) break;
47245
+ mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {};
47246
+ mergedGeometry.morphAttributes[name] = [];
47247
+ for (let i2 = 0; i2 < numMorphTargets; ++i2) {
47248
+ const morphAttributesToMerge = [];
47249
+ for (let j = 0; j < morphAttributes[name].length; ++j) {
47250
+ morphAttributesToMerge.push(morphAttributes[name][j][i2]);
47251
+ }
47252
+ const mergedMorphAttribute = mergeAttributes(morphAttributesToMerge);
47253
+ if (!mergedMorphAttribute) {
47254
+ console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the " + name + " morphAttribute.");
47255
+ return null;
47256
+ }
47257
+ mergedGeometry.morphAttributes[name].push(mergedMorphAttribute);
47258
+ }
47259
+ }
47260
+ return mergedGeometry;
47261
+ }
47262
+ function mergeAttributes(attributes) {
47263
+ let TypedArray;
47264
+ let itemSize;
47265
+ let normalized;
47266
+ let gpuType = -1;
47267
+ let arrayLength = 0;
47268
+ for (let i2 = 0; i2 < attributes.length; ++i2) {
47269
+ const attribute = attributes[i2];
47270
+ if (TypedArray === void 0) TypedArray = attribute.array.constructor;
47271
+ if (TypedArray !== attribute.array.constructor) {
47272
+ console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.");
47273
+ return null;
47274
+ }
47275
+ if (itemSize === void 0) itemSize = attribute.itemSize;
47276
+ if (itemSize !== attribute.itemSize) {
47277
+ console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.");
47278
+ return null;
47279
+ }
47280
+ if (normalized === void 0) normalized = attribute.normalized;
47281
+ if (normalized !== attribute.normalized) {
47282
+ console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.");
47283
+ return null;
47284
+ }
47285
+ if (gpuType === -1) gpuType = attribute.gpuType;
47286
+ if (gpuType !== attribute.gpuType) {
47287
+ console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.");
47288
+ return null;
47289
+ }
47290
+ arrayLength += attribute.count * itemSize;
47291
+ }
47292
+ const array = new TypedArray(arrayLength);
47293
+ const result = new BufferAttribute(array, itemSize, normalized);
47294
+ let offset = 0;
47295
+ for (let i2 = 0; i2 < attributes.length; ++i2) {
47296
+ const attribute = attributes[i2];
47297
+ if (attribute.isInterleavedBufferAttribute) {
47298
+ const tupleOffset = offset / itemSize;
47299
+ for (let j = 0, l = attribute.count; j < l; j++) {
47300
+ for (let c = 0; c < itemSize; c++) {
47301
+ const value = attribute.getComponent(j, c);
47302
+ result.setComponent(j + tupleOffset, c, value);
47303
+ }
47304
+ }
47305
+ } else {
47306
+ array.set(attribute.array, offset);
47307
+ }
47308
+ offset += attribute.count * itemSize;
47309
+ }
47310
+ if (gpuType !== void 0) {
47311
+ result.gpuType = gpuType;
47312
+ }
47313
+ return result;
47314
+ }
47160
47315
  function estimateBytesUsed(geometry) {
47161
47316
  let mem = 0;
47162
47317
  for (const name in geometry.attributes) {
@@ -47662,7 +47817,6 @@ void main() {
47662
47817
  vertexColors: true,
47663
47818
  flatShading: true,
47664
47819
  side: DoubleSide
47665
- //shininess: 20
47666
47820
  });
47667
47821
  }
47668
47822
  function createBasicTransparent() {
@@ -47928,107 +48082,69 @@ void main() {
47928
48082
  `
47929
48083
  });
47930
48084
  }
47931
- function createIsolationMaterial() {
48085
+ function createGhostMaterial() {
47932
48086
  return new ShaderMaterial({
48087
+ userData: {
48088
+ isGhost: true
48089
+ },
47933
48090
  uniforms: {
47934
- opacity: { value: 0.1 },
48091
+ // Uniform controlling the overall transparency of the non-visible objects.
48092
+ opacity: { value: 1e-3 },
48093
+ // Uniform specifying the fill color for non-visible objects.
47935
48094
  fillColor: { value: new Vector3$1(0, 0, 0) }
47936
48095
  },
48096
+ // Render only the front side of faces to prevent drawing internal geometry.
48097
+ side: FrontSide,
48098
+ // Enable support for vertex colors.
47937
48099
  vertexColors: true,
48100
+ // Enable transparency for the material.
47938
48101
  transparent: true,
48102
+ // Enable clipping planes for geometry slicing.
47939
48103
  clipping: true,
48104
+ // Prevent writing to the depth buffer for proper blending of transparent objects.
48105
+ depthWrite: false,
48106
+ // Perform depth testing to ensure correct rendering order.
48107
+ depthTest: true,
47940
48108
  vertexShader: (
47941
48109
  /* glsl */
47942
48110
  `
47943
-
47944
- #include <common>
47945
- #include <logdepthbuf_pars_vertex>
47946
48111
  #include <clipping_planes_pars_vertex>
47947
-
47948
- // VISIBILITY
47949
- // Instance or vertex attribute to hide objects
47950
- // Used as instance attribute for instanced mesh and as vertex attribute for merged meshes.
47951
- attribute float ignore;
47952
-
47953
- // Passed to fragment to discard them
47954
- varying float vIgnore;
47955
- varying vec3 vPosition;
47956
-
47957
-
47958
- // COLORING
47959
- varying vec3 vColor;
47960
-
47961
- // attribute for color override
47962
- // merged meshes use it as vertex attribute
47963
- // instanced meshes use it as an instance attribute
47964
- attribute float colored;
47965
48112
 
47966
- // There seems to be an issue where setting mehs.instanceColor
47967
- // doesn't properly set USE_INSTANCING_COLOR
47968
- // so we always use it as a fix
47969
- #ifndef USE_INSTANCING_COLOR
47970
- attribute vec3 instanceColor;
47971
- #endif
48113
+ // Attribute to determine if an object or vertex should be visible.
48114
+ // Used as an instance attribute for instanced meshes or a vertex attribute for merged meshes.
48115
+ attribute float ignore;
47972
48116
 
47973
48117
  void main() {
48118
+ // Standard transformations to calculate vertex position.
47974
48119
  #include <begin_vertex>
47975
48120
  #include <project_vertex>
47976
48121
  #include <clipping_planes_vertex>
47977
- #include <logdepthbuf_vertex>
47978
-
47979
- // VISIBILITY
47980
- // Set frag ignore from instance or vertex attribute
47981
- vIgnore = ignore;
47982
-
47983
- // COLORING
47984
- vColor = color.xyz;
47985
-
47986
- // colored == 1 -> instance color
47987
- // colored == 0 -> vertex color
47988
- #ifdef USE_INSTANCING
47989
- vColor.xyz = colored * instanceColor.xyz + (1.0f - colored) * color.xyz;
47990
- #endif
47991
48122
 
47992
-
47993
- // ORDERING
47994
- if(vIgnore > 0.0f){
47995
- gl_Position.z = 1.0f;
47996
- }else{
47997
- gl_Position.z = -1.0f;
48123
+ // Hide objects or vertices where the 'ignore' attribute is set to 0.
48124
+ if (ignore == 0.0) {
48125
+ // Push the vertex far out of view, effectively hiding it.
48126
+ gl_Position = vec4(1e20, 1e20, 1e20, 1.0);
47998
48127
  }
47999
-
48000
- // LIGHTING
48001
- vPosition = vec3(mvPosition ) / mvPosition .w;
48002
48128
  }
48003
- `
48129
+ `
48004
48130
  ),
48005
48131
  fragmentShader: (
48006
48132
  /* glsl */
48007
48133
  `
48008
48134
  #include <clipping_planes_pars_fragment>
48009
- varying float vIgnore;
48135
+
48136
+ // Uniform controlling the transparency level of the material.
48010
48137
  uniform float opacity;
48138
+ // Uniform specifying the fill color for non-visible objects.
48011
48139
  uniform vec3 fillColor;
48012
- varying vec3 vPosition;
48013
- varying vec3 vColor;
48014
48140
 
48015
48141
  void main() {
48142
+ // Handle clipping planes to discard fragments outside the defined planes.
48016
48143
  #include <clipping_planes_fragment>
48017
-
48018
- if (vIgnore > 0.0f){
48019
- gl_FragColor = vec4(fillColor, opacity);
48020
- }
48021
- else{
48022
- gl_FragColor = vec4(vColor.x, vColor.y, vColor.z, 1.0f);
48023
-
48024
- // LIGHTING
48025
- vec3 normal = normalize( cross(dFdx(vPosition), dFdy(vPosition)) );
48026
- float light = dot(normal, normalize(vec3(1.4142f, 1.732f, 2.2360f)));
48027
- light = 0.5 + (light *0.5);
48028
- gl_FragColor.xyz *= light;
48029
- }
48144
+ // Set the fragment color to the specified fill color and opacity.
48145
+ gl_FragColor = vec4(fillColor, opacity);
48030
48146
  }
48031
- `
48147
+ `
48032
48148
  )
48033
48149
  });
48034
48150
  }
@@ -48316,42 +48432,40 @@ void main() {
48316
48432
  }
48317
48433
  function createSimpleMaterial() {
48318
48434
  return new ShaderMaterial({
48319
- uniforms: {
48320
- opacity: { value: 0.1 },
48321
- fillColor: { value: new Vector3$1(0, 0, 0) }
48322
- },
48435
+ side: DoubleSide,
48436
+ // No uniforms are needed for this shader.
48437
+ uniforms: {},
48438
+ // Enable vertex colors for both instanced and merged meshes.
48323
48439
  vertexColors: true,
48324
- // transparent: true,
48440
+ // Enable support for clipping planes.
48325
48441
  clipping: true,
48326
48442
  vertexShader: (
48327
48443
  /* glsl */
48328
48444
  `
48329
-
48330
48445
  #include <common>
48331
48446
  #include <logdepthbuf_pars_vertex>
48332
48447
  #include <clipping_planes_pars_vertex>
48333
-
48448
+
48334
48449
  // VISIBILITY
48335
- // Instance or vertex attribute to hide objects
48336
- // Used as instance attribute for instanced mesh and as vertex attribute for merged meshes.
48450
+ // Determines if an object or vertex should be visible.
48451
+ // Used as an instance attribute for instanced meshes or as a vertex attribute for merged meshes.
48337
48452
  attribute float ignore;
48338
48453
 
48339
- // Passed to fragment to discard them
48340
- varying float vIgnore;
48454
+ // LIGHTING
48455
+ // Passes the vertex position to the fragment shader for lighting calculations.
48341
48456
  varying vec3 vPosition;
48342
48457
 
48343
-
48344
48458
  // COLORING
48459
+ // Passes the color of the vertex or instance to the fragment shader.
48345
48460
  varying vec3 vColor;
48346
48461
 
48347
- // attribute for color override
48348
- // merged meshes use it as vertex attribute
48349
- // instanced meshes use it as an instance attribute
48462
+ // Determines whether to use instance color (1.0) or vertex color (0.0).
48463
+ // For merged meshes, this is used as a vertex attribute.
48464
+ // For instanced meshes, this is used as an instance attribute.
48350
48465
  attribute float colored;
48351
48466
 
48352
- // There seems to be an issue where setting mehs.instanceColor
48353
- // doesn't properly set USE_INSTANCING_COLOR
48354
- // so we always use it as a fix
48467
+ // Fix for a known issue where setting mesh.instanceColor does not properly enable USE_INSTANCING_COLOR.
48468
+ // This ensures that instance colors are always used when required.
48355
48469
  #ifndef USE_INSTANCING_COLOR
48356
48470
  attribute vec3 instanceColor;
48357
48471
  #endif
@@ -48362,49 +48476,59 @@ void main() {
48362
48476
  #include <clipping_planes_vertex>
48363
48477
  #include <logdepthbuf_vertex>
48364
48478
 
48365
- // VISIBILITY
48366
- // Set frag ignore from instance or vertex attribute
48367
- vIgnore = ignore;
48479
+ // If ignore is greater than 0, hide the object by moving it far out of view.
48480
+ if (ignore > 0.0) {
48481
+ gl_Position = vec4(1e20, 1e20, 1e20, 1.0);
48482
+ return;
48483
+ }
48368
48484
 
48369
48485
  // COLORING
48486
+ // Default to the vertex color.
48370
48487
  vColor = color.xyz;
48371
48488
 
48372
- // colored == 1 -> instance color
48373
- // colored == 0 -> vertex color
48489
+ // Blend instance and vertex colors based on the colored attribute.
48490
+ // colored == 1.0 -> use instance color.
48491
+ // colored == 0.0 -> use vertex color.
48374
48492
  #ifdef USE_INSTANCING
48375
- vColor.xyz = colored * instanceColor.xyz + (1.0f - colored) * color.xyz;
48493
+ vColor.xyz = colored * instanceColor.xyz + (1.0 - colored) * color.xyz;
48376
48494
  #endif
48377
48495
 
48378
- gl_Position.z = -10.0f;
48379
-
48380
48496
  // LIGHTING
48381
- vPosition = vec3(mvPosition ) / mvPosition .w;
48497
+ // Pass the model-view position to the fragment shader for lighting calculations.
48498
+ vPosition = vec3(mvPosition) / mvPosition.w;
48382
48499
  }
48383
48500
  `
48384
48501
  ),
48385
48502
  fragmentShader: (
48386
48503
  /* glsl */
48387
48504
  `
48505
+ #include <common>
48506
+ #include <logdepthbuf_pars_fragment>
48388
48507
  #include <clipping_planes_pars_fragment>
48389
- varying float vIgnore;
48508
+
48509
+
48510
+ // Position and color data passed from the vertex shader.
48390
48511
  varying vec3 vPosition;
48391
48512
  varying vec3 vColor;
48392
48513
 
48393
48514
  void main() {
48394
48515
  #include <clipping_planes_fragment>
48516
+ #include <logdepthbuf_fragment>
48395
48517
 
48396
- if (vIgnore > 0.0f){
48397
- discard;
48398
- }
48399
- else{
48400
- gl_FragColor = vec4(vColor.x, vColor.y, vColor.z, 1.0f);
48518
+ // Set the fragment color to the interpolated vertex or instance color.
48519
+ gl_FragColor = vec4(vColor, 1.0);
48401
48520
 
48402
- // LIGHTING
48403
- vec3 normal = normalize( cross(dFdx(vPosition), dFdy(vPosition)) );
48404
- float light = dot(normal, normalize(vec3(1.4142f, 1.732f, 2.2360f)));
48405
- light = 0.5 + (light *0.5);
48406
- gl_FragColor.xyz *= light;
48407
- }
48521
+ // LIGHTING
48522
+ // Compute a pseudo-normal using screen-space derivatives of the vertex position.
48523
+ vec3 normal = normalize(cross(dFdx(vPosition), dFdy(vPosition)));
48524
+
48525
+ // Apply simple directional lighting.
48526
+ // Normalize the light direction for consistent shading.
48527
+ float light = dot(normal, normalize(vec3(1.4142, 1.732, 2.236)));
48528
+ light = 0.5 + (light * 0.5); // Adjust light intensity to range [0.5, 1.0].
48529
+
48530
+ // Modulate the fragment color by the lighting intensity.
48531
+ gl_FragColor.xyz *= light;
48408
48532
  }
48409
48533
  `
48410
48534
  )
@@ -48503,7 +48627,7 @@ void main() {
48503
48627
  }
48504
48628
  }
48505
48629
  const _ViewerMaterials = class _ViewerMaterials {
48506
- constructor(opaque, transparent, simple, wireframe, isolation, mask, outline, merge, skyBox) {
48630
+ constructor(opaque, transparent, simple, wireframe, ghost2, mask, outline, merge, skyBox) {
48507
48631
  /**
48508
48632
  * Material used for opaque model geometry.
48509
48633
  */
@@ -48523,7 +48647,7 @@ void main() {
48523
48647
  /**
48524
48648
  * Material used to show traces of hidden objects.
48525
48649
  */
48526
- __publicField(this, "isolation");
48650
+ __publicField(this, "ghost");
48527
48651
  /**
48528
48652
  * Material used to filter out what is not selected for selection outline effect.
48529
48653
  */
@@ -48551,7 +48675,7 @@ void main() {
48551
48675
  this.transparent = transparent ?? createTransparent();
48552
48676
  this.simple = simple ?? createSimpleMaterial();
48553
48677
  this.wireframe = wireframe ?? createWireframe();
48554
- this.isolation = isolation ?? createIsolationMaterial();
48678
+ this.ghost = ghost2 ?? createGhostMaterial();
48555
48679
  this.mask = mask ?? createMaskMaterial();
48556
48680
  this.outline = outline ?? new OutlineMaterial();
48557
48681
  this.merge = merge ?? new MergeMaterial();
@@ -48573,8 +48697,8 @@ void main() {
48573
48697
  applySettings(settings2) {
48574
48698
  this.opaque.color = settings2.materials.standard.color;
48575
48699
  this.transparent.color = settings2.materials.standard.color;
48576
- this.isolationOpacity = settings2.materials.isolation.opacity;
48577
- this.isolationColor = settings2.materials.isolation.color;
48700
+ this.ghostOpacity = settings2.materials.ghost.opacity;
48701
+ this.ghostColor = settings2.materials.ghost.color;
48578
48702
  this.wireframeColor = settings2.materials.highlight.color;
48579
48703
  this.wireframeOpacity = settings2.materials.highlight.opacity;
48580
48704
  this.sectionStrokeWitdh = settings2.materials.section.strokeWidth;
@@ -48603,26 +48727,27 @@ void main() {
48603
48727
  this._onUpdate.dispatch();
48604
48728
  }
48605
48729
  /**
48606
- * Determines the opacity of the isolation material.
48730
+ * Determines the opacity of the ghost material.
48607
48731
  */
48608
- get isolationOpacity() {
48609
- return this.isolation.opacity;
48732
+ get ghostOpacity() {
48733
+ const mat = this.ghost;
48734
+ return mat.uniforms.opacity.value;
48610
48735
  }
48611
- set isolationOpacity(opacity) {
48612
- const mat = this.isolation;
48736
+ set ghostOpacity(opacity) {
48737
+ const mat = this.ghost;
48613
48738
  mat.uniforms.opacity.value = opacity;
48614
48739
  mat.uniformsNeedUpdate = true;
48615
48740
  this._onUpdate.dispatch();
48616
48741
  }
48617
48742
  /**
48618
- * Determines the color of the isolation material.
48743
+ * Determines the color of the ghost material.
48619
48744
  */
48620
- get isolationColor() {
48621
- const mat = this.isolation;
48745
+ get ghostColor() {
48746
+ const mat = this.ghost;
48622
48747
  return mat.uniforms.fillColor.value;
48623
48748
  }
48624
- set isolationColor(color) {
48625
- const mat = this.isolation;
48749
+ set ghostColor(color) {
48750
+ const mat = this.ghost;
48626
48751
  mat.uniforms.fillColor.value = color;
48627
48752
  mat.uniformsNeedUpdate = true;
48628
48753
  this._onUpdate.dispatch();
@@ -48683,10 +48808,11 @@ void main() {
48683
48808
  }
48684
48809
  set clippingPlanes(value) {
48685
48810
  this._clippingPlanes = value;
48811
+ this.simple.clippingPlanes = value ?? null;
48686
48812
  this.opaque.clippingPlanes = value ?? null;
48687
48813
  this.transparent.clippingPlanes = value ?? null;
48688
48814
  this.wireframe.clippingPlanes = value ?? null;
48689
- this.isolation.clippingPlanes = value ?? null;
48815
+ this.ghost.clippingPlanes = value ?? null;
48690
48816
  this.mask.clippingPlanes = value ?? null;
48691
48817
  this._onUpdate.dispatch();
48692
48818
  }
@@ -48806,7 +48932,7 @@ void main() {
48806
48932
  this.opaque.dispose();
48807
48933
  this.transparent.dispose();
48808
48934
  this.wireframe.dispose();
48809
- this.isolation.dispose();
48935
+ this.ghost.dispose();
48810
48936
  this.mask.dispose();
48811
48937
  this.outline.dispose();
48812
48938
  }
@@ -48918,16 +49044,12 @@ void main() {
48918
49044
  setMaterial(value) {
48919
49045
  if (this._material === value) return;
48920
49046
  if (this.ignoreSceneMaterial) return;
48921
- if (value) {
48922
- if (!this._material) {
48923
- this._material = this.mesh.material;
48924
- }
48925
- this.mesh.material = value;
48926
- } else {
48927
- if (this._material) {
48928
- this.mesh.material = this._material;
48929
- this._material = void 0;
48930
- }
49047
+ this.mesh.material = value ?? this._material;
49048
+ this.mesh.geometry.clearGroups();
49049
+ if (value instanceof Array) {
49050
+ value.forEach((m, i2) => {
49051
+ this.mesh.geometry.addGroup(0, Infinity, i2);
49052
+ });
48931
49053
  }
48932
49054
  }
48933
49055
  }
@@ -48985,13 +49107,17 @@ void main() {
48985
49107
  // State
48986
49108
  __publicField(this, "ignoreSceneMaterial");
48987
49109
  __publicField(this, "_material");
49110
+ __publicField(this, "size", 0);
49111
+ var _a2;
48988
49112
  this.g3dMesh = g3d2;
48989
49113
  this.mesh = mesh;
48990
49114
  this.mesh.userData.vim = this;
48991
49115
  this.bimInstances = g3d2 instanceof distExports$2.G3dMesh ? instances.map((i2) => g3d2.scene.instanceNodes[i2]) : instances;
48992
49116
  this.meshInstances = instances;
48993
49117
  this.boxes = g3d2 instanceof distExports$2.G3dMesh ? this.importBoundingBoxes() : this.computeBoundingBoxes();
49118
+ this.size = ((_a2 = this.boxes[0]) == null ? void 0 : _a2.getSize(new Vector3$1()).length()) ?? 0;
48994
49119
  this.boundingBox = this.computeBoundingBox(this.boxes);
49120
+ this._material = this.mesh.material;
48995
49121
  }
48996
49122
  get merged() {
48997
49123
  return false;
@@ -49015,16 +49141,12 @@ void main() {
49015
49141
  setMaterial(value) {
49016
49142
  if (this._material === value) return;
49017
49143
  if (this.ignoreSceneMaterial) return;
49018
- if (value) {
49019
- if (!this._material) {
49020
- this._material = this.mesh.material;
49021
- }
49022
- this.mesh.material = value;
49023
- } else {
49024
- if (this._material) {
49025
- this.mesh.material = this._material;
49026
- this._material = void 0;
49027
- }
49144
+ this.mesh.material = value ?? this._material;
49145
+ this.mesh.geometry.clearGroups();
49146
+ if (value instanceof Array) {
49147
+ value.forEach((m, i2) => {
49148
+ this.mesh.geometry.addGroup(0, Infinity, i2);
49149
+ });
49028
49150
  }
49029
49151
  }
49030
49152
  computeBoundingBoxes() {
@@ -49963,7 +50085,7 @@ void main() {
49963
50085
  }
49964
50086
  return vim;
49965
50087
  }
49966
- let DeferredPromise$2 = class DeferredPromise extends Promise {
50088
+ let DeferredPromise$1 = class DeferredPromise extends Promise {
49967
50089
  constructor(executor = () => {
49968
50090
  }) {
49969
50091
  var _a2;
@@ -50026,8 +50148,8 @@ void main() {
50026
50148
  __publicField(this, "_error");
50027
50149
  // Promises to await progress updates and completion
50028
50150
  __publicField(this, "_progress", { loaded: 0, total: 0, all: /* @__PURE__ */ new Map() });
50029
- __publicField(this, "_progressPromise", new DeferredPromise$2());
50030
- __publicField(this, "_completionPromise", new DeferredPromise$2());
50151
+ __publicField(this, "_progressPromise", new DeferredPromise$1());
50152
+ __publicField(this, "_completionPromise", new DeferredPromise$1());
50031
50153
  this._source = source;
50032
50154
  this._settings = settings2;
50033
50155
  this.startRequest();
@@ -50041,7 +50163,7 @@ void main() {
50041
50163
  const vim = await open(this._bfast, this._settings, (progress) => {
50042
50164
  this._progress = progress;
50043
50165
  this._progressPromise.resolve(progress);
50044
- this._progressPromise = new DeferredPromise$2();
50166
+ this._progressPromise = new DeferredPromise$1();
50045
50167
  });
50046
50168
  this._vimResult = vim;
50047
50169
  } catch (err) {
@@ -50096,9 +50218,6 @@ void main() {
50096
50218
  }
50097
50219
  return true;
50098
50220
  }
50099
- const floor$1 = `
50100
- data:image/png;base64,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
50101
- `;
50102
50221
  class AxesSettings {
50103
50222
  constructor(init) {
50104
50223
  __publicField(this, "size", 84);
@@ -50149,7 +50268,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50149
50268
  fov: 50,
50150
50269
  zoom: 1,
50151
50270
  // 45 deg down looking down z.
50152
- forward: new Vector3$1(1, -1, 1),
50271
+ forward: new Vector3$1(1, -1, -1),
50153
50272
  controls: {
50154
50273
  orbit: true,
50155
50274
  rotateSpeed: 1,
@@ -50174,14 +50293,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50174
50293
  // less white
50175
50294
  sharpness: 2
50176
50295
  },
50177
- groundPlane: {
50178
- visible: false,
50179
- encoding: "base64",
50180
- texture: floor$1,
50181
- opacity: 1,
50182
- color: new Color(16777215),
50183
- size: 5
50184
- },
50185
50296
  skylight: {
50186
50297
  skyColor: new Color(16777215),
50187
50298
  groundColor: new Color(16777215),
@@ -50209,9 +50320,9 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50209
50320
  color: new Color(7000831),
50210
50321
  opacity: 0.5
50211
50322
  },
50212
- isolation: {
50323
+ ghost: {
50213
50324
  color: new Color(5132892),
50214
- opacity: 0.08
50325
+ opacity: 0.01
50215
50326
  },
50216
50327
  section: {
50217
50328
  strokeWidth: 0.01,
@@ -50481,18 +50592,18 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50481
50592
  orbitTowards(direction) {
50482
50593
  const forward = this._camera.forward;
50483
50594
  const _direction = direction.clone();
50484
- if (_direction.x === 0 && _direction.z === 0) {
50595
+ if (_direction.x === 0 && _direction.y === 0) {
50485
50596
  _direction.x = this._camera.forward.x * 1e-3;
50486
- _direction.z = this._camera.forward.z * 1e-3;
50597
+ _direction.y = this._camera.forward.y * 1e-3;
50487
50598
  _direction.normalize();
50488
50599
  }
50489
- const flatForward = forward.clone().setY(0);
50490
- const flatDirection = _direction.clone().setY(0);
50600
+ const flatForward = forward.clone().setZ(0);
50601
+ const flatDirection = _direction.clone().setZ(0);
50491
50602
  const cross = flatForward.clone().cross(flatDirection);
50492
- const clockwise = cross.y === 0 ? 1 : Math.sign(cross.y);
50603
+ const clockwise = cross.z === 0 ? 1 : Math.sign(cross.z);
50493
50604
  const azimuth = flatForward.angleTo(flatDirection) * clockwise;
50494
- const angleForward = flatForward.angleTo(forward) * Math.sign(forward.y);
50495
- const angleDirection = flatDirection.angleTo(_direction) * Math.sign(_direction.y);
50605
+ const angleForward = flatForward.angleTo(forward) * Math.sign(forward.z);
50606
+ const angleDirection = flatDirection.angleTo(_direction) * Math.sign(_direction.z);
50496
50607
  const declination = angleForward - angleDirection;
50497
50608
  const angle = new Vector2$1(-declination, azimuth);
50498
50609
  angle.multiplyScalar(180 / Math.PI);
@@ -50700,12 +50811,30 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50700
50811
  this.set(pos, target);
50701
50812
  }
50702
50813
  set(position, target) {
50703
- const locked = this.lockVector(position, this._camera.position);
50704
- this._camera.position.copy(locked);
50705
50814
  target = target ?? this._camera.target;
50815
+ const direction = new Vector3$1().subVectors(position, target);
50816
+ const dist2 = direction.length();
50817
+ if (dist2 > 1e-6) {
50818
+ const up = new Vector3$1(0, 0, 1);
50819
+ const angle = direction.angleTo(up);
50820
+ const minAngle = MathUtils.degToRad(5);
50821
+ const maxAngle = MathUtils.degToRad(175);
50822
+ if (angle < minAngle) {
50823
+ const axis = new Vector3$1().crossVectors(up, direction).normalize();
50824
+ const delta = minAngle - angle;
50825
+ direction.applyQuaternion(new Quaternion().setFromAxisAngle(axis, delta));
50826
+ } else if (angle > maxAngle) {
50827
+ const axis = new Vector3$1().crossVectors(up, direction).normalize();
50828
+ const delta = maxAngle - angle;
50829
+ direction.applyQuaternion(new Quaternion().setFromAxisAngle(axis, delta));
50830
+ }
50831
+ position.copy(target).add(direction);
50832
+ }
50833
+ const lockedPos = this.lockVector(position, this._camera.position);
50834
+ this._camera.position.copy(lockedPos);
50706
50835
  this._camera.target.copy(target);
50836
+ this._camera.camPerspective.camera.up.set(0, 0, 1);
50707
50837
  this._camera.camPerspective.camera.lookAt(target);
50708
- this._camera.camPerspective.camera.up.set(0, 1, 0);
50709
50838
  }
50710
50839
  lockVector(position, fallback) {
50711
50840
  const x = this._camera.allowedMovement.x === 0 ? fallback.x : position.x;
@@ -50716,17 +50845,14 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50716
50845
  predictOrbit(angle) {
50717
50846
  const rotation = this.predictRotate(angle);
50718
50847
  const delta = new Vector3$1(0, 0, 1).applyQuaternion(rotation).multiplyScalar(this._camera.orbitDistance);
50719
- return this._camera.target.clone().add(delta);
50848
+ const pos = this._camera.target.clone().add(delta);
50849
+ return pos;
50720
50850
  }
50721
50851
  predictRotate(angle) {
50722
- const euler = new Euler(0, 0, 0, "YXZ");
50723
- euler.setFromQuaternion(this._camera.quaternion);
50724
- euler.x += angle.x * Math.PI / 180;
50725
- euler.y += angle.y * Math.PI / 180;
50726
- euler.z = 0;
50727
- const max2 = Math.PI * 0.4999;
50728
- euler.x = Math.max(-max2, Math.min(max2, euler.x));
50729
- const rotation = new Quaternion().setFromEuler(euler);
50852
+ const xQuat = new Quaternion().setFromAxisAngle(new Vector3$1(1, 0, 0), angle.x * Math.PI / 180);
50853
+ const zQuat = new Quaternion().setFromAxisAngle(new Vector3$1(0, 1, 0), angle.y * Math.PI / 180);
50854
+ const rotation = this._camera.quaternion.clone();
50855
+ rotation.multiply(xQuat).multiply(zQuat);
50730
50856
  return rotation;
50731
50857
  }
50732
50858
  }
@@ -50775,6 +50901,8 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50775
50901
  __publicField(this, "_velocityBlendFactor", 1e-4);
50776
50902
  __publicField(this, "_moveSpeed", 1);
50777
50903
  this.camPerspective = new PerspectiveWrapper(new PerspectiveCamera());
50904
+ this.camPerspective.camera.up = new Vector3$1(0, 0, 1);
50905
+ this.camPerspective.camera.lookAt(new Vector3$1(0, 1, 0));
50778
50906
  this.camOrthographic = new OrthographicWrapper(
50779
50907
  new OrthographicCamera()
50780
50908
  );
@@ -50835,7 +50963,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
50835
50963
  }
50836
50964
  set defaultForward(value) {
50837
50965
  if (value.x === 0 && value.y === 0 && value.z === 0) {
50838
- this._defaultForward.set(1, -1, 1).normalize();
50966
+ this._defaultForward.set(1, -1, -1).normalize();
50839
50967
  } else {
50840
50968
  this._defaultForward.copy(value).normalize();
50841
50969
  }
@@ -52399,6 +52527,9 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52399
52527
  });
52400
52528
  this._onValueChanged.dispatch();
52401
52529
  }
52530
+ any() {
52531
+ return this._objects.size > 0;
52532
+ }
52402
52533
  /**
52403
52534
  * Returns true if the given object is currently selected.
52404
52535
  * @param {IObject} object The object to check for selection.
@@ -52508,92 +52639,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52508
52639
  this._materials.focusIntensity = focus / 2;
52509
52640
  }
52510
52641
  }
52511
- class GroundPlane {
52512
- constructor(settings2) {
52513
- __publicField(this, "mesh");
52514
- __publicField(this, "_source");
52515
- __publicField(this, "_size", 1);
52516
- // disposable
52517
- __publicField(this, "_geometry");
52518
- __publicField(this, "_material");
52519
- __publicField(this, "_texture");
52520
- this._geometry = new PlaneGeometry();
52521
- this._material = new MeshBasicMaterial({
52522
- transparent: true,
52523
- depthTest: true,
52524
- depthWrite: false
52525
- });
52526
- this.mesh = new Mesh(this._geometry, this._material);
52527
- this.mesh.renderOrder = -1;
52528
- this._size = settings2.groundPlane.size;
52529
- this.mesh.visible = settings2.groundPlane.visible;
52530
- this.applyTexture(
52531
- settings2.groundPlane.encoding,
52532
- settings2.groundPlane.texture
52533
- );
52534
- this._material.color.copy(settings2.groundPlane.color);
52535
- this._material.opacity = settings2.groundPlane.opacity;
52536
- }
52537
- /**
52538
- * Whether the ground plane is visible or not.
52539
- */
52540
- get visible() {
52541
- return this.mesh.visible;
52542
- }
52543
- set visible(value) {
52544
- this.mesh.visible = value;
52545
- }
52546
- adaptToContent(box) {
52547
- const center = box.getCenter(new Vector3$1());
52548
- const position = new Vector3$1(
52549
- center.x,
52550
- box.min.y - Math.abs(box.min.y) * 0.01,
52551
- center.z
52552
- );
52553
- this.mesh.position.copy(position);
52554
- this.mesh.quaternion.copy(
52555
- new Quaternion().setFromEuler(new Euler(1.5 * Math.PI, 0, 0))
52556
- );
52557
- const sphere = box == null ? void 0 : box.getBoundingSphere(new Sphere());
52558
- const size = ((sphere == null ? void 0 : sphere.radius) ?? 1) * this._size;
52559
- const scale = new Vector3$1(1, 1, 1).multiplyScalar(size);
52560
- this.mesh.scale.copy(scale);
52561
- }
52562
- applyTexture(encoding, source) {
52563
- var _a2;
52564
- if (source === this._source) return;
52565
- this._source = source;
52566
- (_a2 = this._texture) == null ? void 0 : _a2.dispose();
52567
- this._texture = void 0;
52568
- if (!source || !encoding) return;
52569
- if (encoding === "url") {
52570
- const loader = new TextureLoader();
52571
- this._texture = loader.load(source);
52572
- }
52573
- if (encoding === "base64") {
52574
- const image = new Image();
52575
- image.src = source;
52576
- const txt = new Texture();
52577
- this._texture = txt;
52578
- this._texture.image = image;
52579
- image.onload = () => {
52580
- txt.needsUpdate = true;
52581
- };
52582
- }
52583
- if (!this._texture) {
52584
- console.error("Failed to load texture: " + source);
52585
- return;
52586
- }
52587
- this._material.map = this._texture;
52588
- }
52589
- dispose() {
52590
- var _a2, _b2, _c;
52591
- (_a2 = this._geometry) == null ? void 0 : _a2.dispose();
52592
- (_b2 = this._material) == null ? void 0 : _b2.dispose();
52593
- (_c = this._texture) == null ? void 0 : _c.dispose();
52594
- this._texture = void 0;
52595
- }
52596
- }
52597
52642
  class Skybox {
52598
52643
  constructor(camera2, renderer, materials, settings2) {
52599
52644
  __publicField(this, "mesh");
@@ -52738,28 +52783,22 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52738
52783
  * The array of directional lights in the scene.
52739
52784
  */
52740
52785
  __publicField(this, "sunLights");
52741
- /**
52742
- * The ground plane under the model in the scene.
52743
- */
52744
- __publicField(this, "groundPlane");
52745
52786
  /*
52746
52787
  * The skybox in the scene.
52747
52788
  */
52748
52789
  __publicField(this, "skybox");
52749
52790
  this._camera = camera2;
52750
52791
  this._renderer = renderer;
52751
- this.groundPlane = new GroundPlane(settings2);
52752
52792
  this.skyLight = this.createSkyLight(settings2);
52753
52793
  this.skybox = new Skybox(camera2, renderer, viewerMaterials, settings2);
52754
52794
  this.sunLights = this.createSunLights(settings2);
52755
- this.setupRendererListeners();
52756
52795
  this.addObjectsToRenderer();
52757
52796
  }
52758
52797
  /**
52759
52798
  * Returns all three objects composing the environment
52760
52799
  */
52761
52800
  getObjects() {
52762
- return [this.groundPlane.mesh, this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52801
+ return [this.skyLight, ...this.sunLights.map((l) => l.light), this.skybox.mesh];
52763
52802
  }
52764
52803
  createSkyLight(settings2) {
52765
52804
  const { skyColor, groundColor, intensity } = settings2.skylight;
@@ -52773,12 +52812,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52773
52812
  addObjectsToRenderer() {
52774
52813
  this.getObjects().forEach((o) => this._renderer.add(o));
52775
52814
  }
52776
- setupRendererListeners() {
52777
- this._renderer.onBoxUpdated.subscribe(() => {
52778
- const box = this._renderer.getBoundingBox();
52779
- this.groundPlane.adaptToContent(box);
52780
- });
52781
- }
52782
52815
  /**
52783
52816
  * Dispose of all resources.
52784
52817
  */
@@ -52786,7 +52819,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52786
52819
  this.getObjects().forEach((o) => this._renderer.remove(o));
52787
52820
  this.sunLights.forEach((s) => s.dispose());
52788
52821
  this.skyLight.dispose();
52789
- this.groundPlane.dispose();
52790
52822
  this.skybox.dispose();
52791
52823
  }
52792
52824
  }
@@ -52919,14 +52951,16 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52919
52951
  __publicField(this, "scene");
52920
52952
  // state
52921
52953
  __publicField(this, "boxUpdated", false);
52954
+ // public value
52955
+ __publicField(this, "smallGhostThreshold", 10);
52922
52956
  __publicField(this, "_vimScenes", []);
52923
52957
  __publicField(this, "_boundingBox");
52924
52958
  __publicField(this, "_memory", 0);
52925
52959
  __publicField(this, "_2dCount", 0);
52926
- __publicField(this, "_material");
52960
+ __publicField(this, "_modelMaterial");
52927
52961
  this.scene = new Scene$1();
52928
52962
  }
52929
- get models() {
52963
+ get meshes() {
52930
52964
  return this._vimScenes.flatMap((s) => s.meshes);
52931
52965
  }
52932
52966
  get estimatedMemory() {
@@ -52973,6 +53007,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
52973
53007
  add(target) {
52974
53008
  if (target instanceof Scene) {
52975
53009
  this.addScene(target);
53010
+ target.material = this._modelMaterial;
52976
53011
  return;
52977
53012
  }
52978
53013
  this._2dCount += this.count2dObjects(target);
@@ -53022,16 +53057,31 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
53022
53057
  this._boundingBox = void 0;
53023
53058
  this._memory = 0;
53024
53059
  }
53025
- get material() {
53026
- return this._material;
53060
+ get modelMaterial() {
53061
+ return this._modelMaterial;
53027
53062
  }
53028
- set material(material) {
53029
- this._material = material;
53063
+ set modelMaterial(material) {
53064
+ this._modelMaterial = material;
53030
53065
  this._vimScenes.forEach((s) => {
53031
- s.meshes.forEach((m) => {
53032
- m.mesh.material = material;
53033
- });
53066
+ s.material = material;
53034
53067
  });
53068
+ this.updateInstanceMeshVisibility();
53069
+ }
53070
+ updateInstanceMeshVisibility() {
53071
+ var _a2, _b2;
53072
+ const hide = ((_b2 = (_a2 = this._modelMaterial) == null ? void 0 : _a2[1]) == null ? void 0 : _b2.userData.isGhost) === true;
53073
+ for (const mesh of this.meshes) {
53074
+ if (mesh instanceof InstancedMesh) {
53075
+ if (this.smallGhostThreshold <= 0) {
53076
+ mesh.mesh.visible = true;
53077
+ continue;
53078
+ }
53079
+ const visible2 = mesh.getSubmeshes().some(
53080
+ (m) => m.object.visible
53081
+ );
53082
+ mesh.mesh.visible = !(hide && !visible2 && mesh.size < this.smallGhostThreshold);
53083
+ }
53084
+ }
53035
53085
  }
53036
53086
  addScene(scene) {
53037
53087
  this._vimScenes.push(scene);
@@ -55000,93 +55050,279 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
55000
55050
  this._meshes = void 0;
55001
55051
  }
55002
55052
  }
55003
- class BoxOutline extends LineSegments {
55004
- constructor() {
55005
- const vertices = new Float32Array([
55006
- -0.5,
55007
- -0.5,
55008
- -0.5,
55009
- 0.5,
55010
- -0.5,
55011
- -0.5,
55012
- 0.5,
55013
- 0.5,
55014
- -0.5,
55015
- -0.5,
55016
- 0.5,
55017
- -0.5,
55018
- -0.5,
55019
- -0.5,
55020
- 0.5,
55021
- 0.5,
55022
- -0.5,
55023
- 0.5,
55024
- 0.5,
55025
- 0.5,
55026
- 0.5,
55027
- -0.5,
55028
- 0.5,
55029
- 0.5
55030
- ]);
55031
- const indices = [
55032
- 0.5,
55033
- 1,
55034
- 1,
55035
- 2,
55036
- 2,
55037
- 3,
55038
- 3,
55039
- 0,
55040
- 4,
55041
- 5,
55042
- 5,
55043
- 6,
55044
- 6,
55045
- 7,
55046
- 7,
55047
- 4,
55048
- 0,
55049
- 4,
55050
- 1,
55051
- 5,
55052
- 2,
55053
- 6,
55054
- 3,
55055
- 7
55056
- ];
55057
- const geo = new BufferGeometry();
55058
- const mat = new LineBasicMaterial({
55059
- opacity: 1,
55060
- color: new Color(0)
55061
- });
55062
- geo.setAttribute("position", new BufferAttribute(vertices, 3));
55063
- geo.setIndex(indices);
55064
- super(geo, mat);
55065
- }
55066
- /**
55067
- * Resize the outline to the given box.
55068
- */
55069
- fitBox(box) {
55070
- this.scale.set(
55071
- box.max.x - box.min.x,
55072
- box.max.y - box.min.y,
55073
- box.max.z - box.min.z
55074
- );
55075
- this.position.set(
55076
- (box.max.x + box.min.x) / 2,
55077
- (box.max.y + box.min.y) / 2,
55078
- (box.max.z + box.min.z) / 2
55079
- );
55053
+ const MIN_BOX_SIZE = 3;
55054
+ class BoxInputs {
55055
+ // -------------------------------------------------------------------------
55056
+ // Constructor
55057
+ // -------------------------------------------------------------------------
55058
+ /**
55059
+ * Creates a new BoxInputs instance for pointer-driven box resizing.
55060
+ *
55061
+ * @param viewer - The parent {@link Viewer} that renders the scene.
55062
+ * @param handles - A {@link SectionBoxHandles} instance containing the draggable mesh handles.
55063
+ * @param box - The shared bounding box (`Box3`) that will be updated by dragging.
55064
+ */
55065
+ constructor(viewer, handles, box) {
55066
+ // -------------------------------------------------------------------------
55067
+ // Dependencies and shared resources
55068
+ // -------------------------------------------------------------------------
55069
+ /** The parent Viewer controlling the scene. */
55070
+ __publicField(this, "_viewer");
55071
+ /** The handles mesh group containing the draggable cones/faces. */
55072
+ __publicField(this, "_handles");
55073
+ /** The main box that is being reshaped by dragging handles. */
55074
+ __publicField(this, "_sharedBox");
55075
+ // -------------------------------------------------------------------------
55076
+ // Internal state
55077
+ // -------------------------------------------------------------------------
55078
+ /** The currently hovered/dragged handle, if any. */
55079
+ __publicField(this, "_handle");
55080
+ /** The origin point for dragging, updated on pointer down. */
55081
+ __publicField(this, "_dragOrigin", new Vector3$1());
55082
+ /** The plane used for drag intersection (perpendicular to the camera direction). */
55083
+ __publicField(this, "_dragPlane", new Plane());
55084
+ /** Whether a pointer is currently down on a handle. */
55085
+ __publicField(this, "_mouseDown", false);
55086
+ /** A reusable Raycaster for picking and plane intersection. */
55087
+ __publicField(this, "_raycaster", new Raycaster$1());
55088
+ /** The box state before the current drag. */
55089
+ __publicField(this, "_lastBox", new Box3$1());
55090
+ /** A collection of unregister callbacks for event listeners. */
55091
+ __publicField(this, "_unregisters", []);
55092
+ /** The ID of the pointer that is captured, if any. */
55093
+ __publicField(this, "_capturedPointerId");
55094
+ // -------------------------------------------------------------------------
55095
+ // Callbacks
55096
+ // -------------------------------------------------------------------------
55097
+ /**
55098
+ * Called when the pointer enters or leaves a handle face.
55099
+ * @param normal - The normal (forward) vector of the hovered handle, or a zero vector if none.
55100
+ */
55101
+ __publicField(this, "onFaceEnter");
55102
+ /**
55103
+ * Called continuously as the box is reshaped by dragging.
55104
+ * @param box - The updated box after the latest drag move.
55105
+ */
55106
+ __publicField(this, "onBoxStretch");
55107
+ /**
55108
+ * Called when the user has finished reshaping the box (pointer up).
55109
+ * @param box - The final box after dragging ends.
55110
+ */
55111
+ __publicField(this, "onBoxConfirm");
55112
+ this._viewer = viewer;
55113
+ this._handles = handles;
55114
+ this._sharedBox = box;
55080
55115
  }
55116
+ // -------------------------------------------------------------------------
55117
+ // Public Methods
55118
+ // -------------------------------------------------------------------------
55081
55119
  /**
55082
- * Disposes of all resources.
55120
+ * Registers pointer event listeners on the viewer's canvas.
55121
+ * If already registered, it does nothing.
55083
55122
  */
55084
- dispose() {
55085
- this.geometry.dispose();
55086
- this.material.dispose();
55123
+ register() {
55124
+ if (this._unregisters.length > 0) return;
55125
+ const canvas = this._viewer.viewport.canvas;
55126
+ this.reg(canvas, "pointerdown", (e) => this.onMouseDown(e));
55127
+ this.reg(canvas, "pointermove", (e) => this.onMouseMove(e));
55128
+ this.reg(canvas, "pointerup", (e) => this.onMouseUp(e));
55129
+ this.reg(canvas, "pointerleave", (e) => this.onPointerLeave(e));
55130
+ }
55131
+ /**
55132
+ * Unregisters any previously set pointer event listeners, releasing pointer capture
55133
+ * and resetting drag state.
55134
+ */
55135
+ unregister() {
55136
+ var _a2;
55137
+ this._mouseDown = false;
55138
+ (_a2 = this._handle) == null ? void 0 : _a2.highlight(false);
55139
+ this._handle = void 0;
55140
+ this.releasePointer();
55141
+ this._viewer.inputs.registerAll();
55142
+ this._unregisters.forEach((unreg) => unreg());
55143
+ this._unregisters.length = 0;
55144
+ }
55145
+ /**
55146
+ * Indicates if a pointer is currently captured for dragging.
55147
+ */
55148
+ get pointerCaptured() {
55149
+ return this._capturedPointerId !== void 0;
55150
+ }
55151
+ // -------------------------------------------------------------------------
55152
+ // Private Methods
55153
+ // -------------------------------------------------------------------------
55154
+ /**
55155
+ * A helper method to attach an event listener and store its unregister callback.
55156
+ *
55157
+ * @param handler - The DOM element or Window to attach the listener to.
55158
+ * @param type - The pointer event type, e.g. 'pointerdown'.
55159
+ * @param listener - The event handler function.
55160
+ */
55161
+ reg(handler, type, listener2) {
55162
+ handler.addEventListener(type, listener2);
55163
+ this._unregisters.push(() => handler.removeEventListener(type, listener2));
55164
+ }
55165
+ /**
55166
+ * Called when the pointer leaves the canvas. If not dragging,
55167
+ * invokes {@link onFaceEnter} to indicate no active handle is hovered.
55168
+ *
55169
+ * @param event - The pointerleave event.
55170
+ */
55171
+ onPointerLeave(event) {
55172
+ var _a2, _b2;
55173
+ if (!this.pointerCaptured) {
55174
+ (_b2 = this.onFaceEnter) == null ? void 0 : _b2.call(this, ((_a2 = this._handle) == null ? void 0 : _a2.forward) ?? new Vector3$1());
55175
+ }
55176
+ }
55177
+ /**
55178
+ * Sets pointer capture on the canvas for a specific pointer (ID).
55179
+ *
55180
+ * @param pointerId - The pointer ID to capture.
55181
+ */
55182
+ capturePointer(pointerId) {
55183
+ this.releasePointer();
55184
+ this._viewer.viewport.canvas.setPointerCapture(pointerId);
55185
+ this._capturedPointerId = pointerId;
55186
+ }
55187
+ /**
55188
+ * Releases any captured pointer on the canvas, if present.
55189
+ */
55190
+ releasePointer() {
55191
+ if (this.pointerCaptured) {
55192
+ this._viewer.viewport.canvas.releasePointerCapture(this._capturedPointerId);
55193
+ this._capturedPointerId = void 0;
55194
+ }
55195
+ }
55196
+ /**
55197
+ * Handles pointer movement events.
55198
+ * - If dragging, calls {@link onDrag}.
55199
+ * - Otherwise, performs a raycast to detect which handle is under the pointer.
55200
+ *
55201
+ * @param event - The pointermove event.
55202
+ */
55203
+ onMouseMove(event) {
55204
+ var _a2, _b2, _c, _d;
55205
+ if (this._mouseDown) {
55206
+ this.onDrag(event);
55207
+ return;
55208
+ }
55209
+ const hits = this.raycast(new Vector2$1(event.offsetX, event.offsetY));
55210
+ const handle = (_b2 = (_a2 = hits == null ? void 0 : hits[0]) == null ? void 0 : _a2.object) == null ? void 0 : _b2.userData.handle;
55211
+ if (handle !== this._handle) {
55212
+ (_c = this._handle) == null ? void 0 : _c.highlight(false);
55213
+ handle == null ? void 0 : handle.highlight(true);
55214
+ this._handle = handle;
55215
+ (_d = this.onFaceEnter) == null ? void 0 : _d.call(this, (handle == null ? void 0 : handle.forward) ?? new Vector3$1());
55216
+ }
55217
+ }
55218
+ /**
55219
+ * Handles pointer up events. Ends dragging and triggers {@link onBoxConfirm}.
55220
+ *
55221
+ * @param event - The pointerup event.
55222
+ */
55223
+ onMouseUp(event) {
55224
+ var _a2, _b2;
55225
+ this.releasePointer();
55226
+ if (this._mouseDown) {
55227
+ this._mouseDown = false;
55228
+ this._viewer.inputs.registerAll();
55229
+ if (event.pointerType === "mouse") {
55230
+ this.onMouseMove(event);
55231
+ } else {
55232
+ this._handle = void 0;
55233
+ (_a2 = this.onFaceEnter) == null ? void 0 : _a2.call(this, new Vector3$1());
55234
+ }
55235
+ (_b2 = this.onBoxConfirm) == null ? void 0 : _b2.call(this, this._sharedBox);
55236
+ }
55237
+ }
55238
+ /**
55239
+ * Handles pointer down events. Begins drag if a handle is hit, capturing the pointer.
55240
+ *
55241
+ * @param event - The pointerdown event.
55242
+ */
55243
+ onMouseDown(event) {
55244
+ var _a2, _b2, _c, _d;
55245
+ const hits = this.raycast(new Vector2$1(event.offsetX, event.offsetY));
55246
+ const handle = (_c = (_b2 = (_a2 = hits == null ? void 0 : hits[0]) == null ? void 0 : _a2.object) == null ? void 0 : _b2.userData) == null ? void 0 : _c.handle;
55247
+ if (!handle) return;
55248
+ this._handle = handle;
55249
+ this.capturePointer(event.pointerId);
55250
+ this._lastBox.copy(this._sharedBox);
55251
+ this._dragOrigin.copy(handle.position);
55252
+ const dist2 = handle.position.clone().dot(this._viewer.camera.forward);
55253
+ this._dragPlane.set(this._viewer.camera.forward, -dist2);
55254
+ this._mouseDown = true;
55255
+ this._viewer.inputs.unregisterAll();
55256
+ (_d = this.onFaceEnter) == null ? void 0 : _d.call(this, this._handle.forward.clone());
55257
+ }
55258
+ /**
55259
+ * Continues the drag operation. Determines the new position on the drag plane
55260
+ * and computes how far we moved along the handle's forward axis.
55261
+ *
55262
+ * @param event - The pointermove event while dragging.
55263
+ */
55264
+ onDrag(event) {
55265
+ var _a2;
55266
+ if (!this._handle) return;
55267
+ const point = this.raycastPlane(new Vector2$1(event.offsetX, event.offsetY)) ?? this._dragOrigin.clone();
55268
+ const delta = point.sub(this._dragOrigin);
55269
+ const amount = delta.dot(this._handle.forward);
55270
+ const box = this.stretch(this._handle.axis, this._handle.sign, amount);
55271
+ (_a2 = this.onBoxStretch) == null ? void 0 : _a2.call(this, box);
55272
+ }
55273
+ /**
55274
+ * Expands or contracts the `_sharedBox` along one axis by a certain amount,
55275
+ * ensuring the box cannot shrink below the minimum size (`MIN_BOX_SIZE`).
55276
+ *
55277
+ * @param axis - The axis ('x', 'y', or 'z') to stretch.
55278
+ * @param sign - +1 if stretching the 'max' side, -1 if stretching the 'min' side.
55279
+ * @param amount - The numeric offset along that axis to add or subtract.
55280
+ * @returns A **new** `Box3` instance with updated min/max coordinates.
55281
+ */
55282
+ stretch(axis, sign2, amount) {
55283
+ const box = this._sharedBox.clone();
55284
+ const direction = sign2 > 0 ? "max" : "min";
55285
+ const opposite = sign2 > 0 ? "min" : "max";
55286
+ const target = this._lastBox[direction][axis] + amount * sign2;
55287
+ const minBoundary = this._lastBox[opposite][axis] + MIN_BOX_SIZE * sign2;
55288
+ box[direction][axis] = target;
55289
+ if (sign2 * (target - minBoundary) < 0) {
55290
+ box[opposite][axis] = target - MIN_BOX_SIZE * sign2;
55291
+ }
55292
+ return box;
55293
+ }
55294
+ /**
55295
+ * Prepares the internal raycaster for a given 2D pointer position.
55296
+ *
55297
+ * @param position - The pointer position in canvas coordinates.
55298
+ * @returns The updated raycaster pointing from the camera through this position.
55299
+ */
55300
+ getRaycaster(position) {
55301
+ return this._viewer.raycaster.fromPoint2(position, this._raycaster);
55302
+ }
55303
+ /**
55304
+ * Raycasts into the handle meshes from the given pointer position.
55305
+ *
55306
+ * @param position - The pointer position in canvas coordinates.
55307
+ * @returns An array of intersection results, if any.
55308
+ */
55309
+ raycast(position) {
55310
+ return this.getRaycaster(position).intersectObject(this._handles.meshes);
55311
+ }
55312
+ /**
55313
+ * Raycasts into the drag plane from the given pointer position.
55314
+ *
55315
+ * @param position - The pointer position in canvas coordinates.
55316
+ * @returns The intersection point in 3D space, or `null` if none.
55317
+ */
55318
+ raycastPlane(position) {
55319
+ return this.getRaycaster(position).ray.intersectPlane(
55320
+ this._dragPlane,
55321
+ new Vector3$1()
55322
+ );
55087
55323
  }
55088
55324
  }
55089
- class BoxMesh extends Mesh {
55325
+ class SectionBoxMesh extends Mesh {
55090
55326
  constructor() {
55091
55327
  const geo = new BoxGeometry();
55092
55328
  const mat = new MeshBasicMaterial({
@@ -55120,271 +55356,255 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
55120
55356
  this.material.dispose();
55121
55357
  }
55122
55358
  }
55123
- class BoxHighlight extends Mesh {
55124
- constructor() {
55359
+ class SectionBoxOutline extends LineSegments {
55360
+ constructor(color) {
55361
+ const vertices = new Float32Array([
55362
+ -0.5,
55363
+ -0.5,
55364
+ -0.5,
55365
+ 0.5,
55366
+ -0.5,
55367
+ -0.5,
55368
+ 0.5,
55369
+ 0.5,
55370
+ -0.5,
55371
+ -0.5,
55372
+ 0.5,
55373
+ -0.5,
55374
+ -0.5,
55375
+ -0.5,
55376
+ 0.5,
55377
+ 0.5,
55378
+ -0.5,
55379
+ 0.5,
55380
+ 0.5,
55381
+ 0.5,
55382
+ 0.5,
55383
+ -0.5,
55384
+ 0.5,
55385
+ 0.5
55386
+ ]);
55387
+ const indices = [
55388
+ 0.5,
55389
+ 1,
55390
+ 1,
55391
+ 2,
55392
+ 2,
55393
+ 3,
55394
+ 3,
55395
+ 0,
55396
+ 4,
55397
+ 5,
55398
+ 5,
55399
+ 6,
55400
+ 6,
55401
+ 7,
55402
+ 7,
55403
+ 4,
55404
+ 0,
55405
+ 4,
55406
+ 1,
55407
+ 5,
55408
+ 2,
55409
+ 6,
55410
+ 3,
55411
+ 7
55412
+ ];
55125
55413
  const geo = new BufferGeometry();
55126
- geo.setAttribute(
55127
- "position",
55128
- new BufferAttribute(new Float32Array(12), 3)
55129
- );
55130
- geo.setIndex([0, 1, 2, 0, 2, 3]);
55131
- const mat = new MeshBasicMaterial({
55132
- opacity: 0.7,
55133
- transparent: true,
55134
- depthTest: false,
55135
- side: DoubleSide
55414
+ const mat = new LineBasicMaterial({
55415
+ opacity: 1,
55416
+ color
55136
55417
  });
55418
+ geo.setAttribute("position", new BufferAttribute(vertices, 3));
55419
+ geo.setIndex(indices);
55137
55420
  super(geo, mat);
55138
- this.renderOrder = 1;
55139
- this.frustumCulled = false;
55140
55421
  }
55141
55422
  /**
55142
- * Sets the face to highlight
55143
- * @param normal a direction vector from theses options (X,-X, Y,-Y, Z,-Z)
55423
+ * Resize the outline to the given box.
55144
55424
  */
55145
- highlight(box, normal) {
55146
- this.visible = false;
55147
- const positions = this.geometry.getAttribute("position");
55148
- if (normal.x > 0.1) {
55149
- positions.setXYZ(0, box.max.x, box.max.y, box.max.z);
55150
- positions.setXYZ(1, box.max.x, box.min.y, box.max.z);
55151
- positions.setXYZ(2, box.max.x, box.min.y, box.min.z);
55152
- positions.setXYZ(3, box.max.x, box.max.y, box.min.z);
55153
- this.visible = true;
55154
- }
55155
- if (normal.x < -0.1) {
55156
- positions.setXYZ(0, box.min.x, box.max.y, box.max.z);
55157
- positions.setXYZ(1, box.min.x, box.min.y, box.max.z);
55158
- positions.setXYZ(2, box.min.x, box.min.y, box.min.z);
55159
- positions.setXYZ(3, box.min.x, box.max.y, box.min.z);
55160
- this.visible = true;
55161
- }
55162
- if (normal.y > 0.1) {
55163
- positions.setXYZ(0, box.max.x, box.max.y, box.max.z);
55164
- positions.setXYZ(1, box.min.x, box.max.y, box.max.z);
55165
- positions.setXYZ(2, box.min.x, box.max.y, box.min.z);
55166
- positions.setXYZ(3, box.max.x, box.max.y, box.min.z);
55167
- this.visible = true;
55168
- }
55169
- if (normal.y < -0.1) {
55170
- positions.setXYZ(0, box.max.x, box.min.y, box.max.z);
55171
- positions.setXYZ(1, box.min.x, box.min.y, box.max.z);
55172
- positions.setXYZ(2, box.min.x, box.min.y, box.min.z);
55173
- positions.setXYZ(3, box.max.x, box.min.y, box.min.z);
55174
- this.visible = true;
55175
- }
55176
- if (normal.z > 0.1) {
55177
- positions.setXYZ(0, box.max.x, box.max.y, box.max.z);
55178
- positions.setXYZ(1, box.min.x, box.max.y, box.max.z);
55179
- positions.setXYZ(2, box.min.x, box.min.y, box.max.z);
55180
- positions.setXYZ(3, box.max.x, box.min.y, box.max.z);
55181
- this.visible = true;
55182
- }
55183
- if (normal.z < -0.1) {
55184
- positions.setXYZ(0, box.max.x, box.max.y, box.min.z);
55185
- positions.setXYZ(1, box.min.x, box.max.y, box.min.z);
55186
- positions.setXYZ(2, box.min.x, box.min.y, box.min.z);
55187
- positions.setXYZ(3, box.max.x, box.min.y, box.min.z);
55188
- this.visible = true;
55189
- }
55190
- positions.needsUpdate = true;
55425
+ fitBox(box) {
55426
+ this.scale.set(
55427
+ box.max.x - box.min.x,
55428
+ box.max.y - box.min.y,
55429
+ box.max.z - box.min.z
55430
+ );
55431
+ this.position.set(
55432
+ (box.max.x + box.min.x) / 2,
55433
+ (box.max.y + box.min.y) / 2,
55434
+ (box.max.z + box.min.z) / 2
55435
+ );
55191
55436
  }
55192
55437
  /**
55193
- * Disposes all resources.
55438
+ * Disposes of all resources.
55194
55439
  */
55195
55440
  dispose() {
55196
55441
  this.geometry.dispose();
55197
55442
  this.material.dispose();
55198
55443
  }
55199
55444
  }
55200
- class BoxInputs {
55201
- constructor(viewer, cube, box) {
55202
- // dependencies
55203
- __publicField(this, "viewer");
55204
- __publicField(this, "cube");
55205
- __publicField(this, "sharedBox");
55206
- // state
55207
- __publicField(this, "faceNormal", new Vector3$1());
55208
- __publicField(this, "dragOrigin", new Vector3$1());
55209
- __publicField(this, "dragpPlane", new Plane());
55210
- __publicField(this, "mouseDown");
55211
- __publicField(this, "raycaster", new Raycaster$1());
55212
- __publicField(this, "lastBox", new Box3$1());
55213
- __publicField(this, "unregisters", []);
55214
- __publicField(this, "lastMouse");
55215
- __publicField(this, "ctrlDown", false);
55216
- __publicField(this, "capturedId");
55217
- // Called when mouse enters or leave a face
55218
- __publicField(this, "onFaceEnter");
55219
- // Called the box is reshaped
55220
- __publicField(this, "onBoxStretch");
55221
- // Called when the user is done reshaping the box
55222
- __publicField(this, "onBoxConfirm");
55223
- __publicField(this, "reg", (handler, type, listener2) => {
55224
- handler.addEventListener(type, listener2);
55225
- this.unregisters.push(() => handler.removeEventListener(type, listener2));
55445
+ class SectionBoxHandle extends Mesh {
55446
+ constructor(axes, sign2, size, color) {
55447
+ const geo = createDoubleCone(size);
55448
+ geo.clearGroups();
55449
+ geo.addGroup(0, Infinity, 0);
55450
+ geo.addGroup(0, Infinity, 1);
55451
+ const matBehind = new MeshBasicMaterial({
55452
+ transparent: true,
55453
+ opacity: 0.5,
55454
+ color: color ?? new Color(0),
55455
+ depthTest: false,
55456
+ side: FrontSide
55226
55457
  });
55227
- this.viewer = viewer;
55228
- this.cube = cube;
55229
- this.sharedBox = box;
55458
+ const matAlways = new MeshBasicMaterial({
55459
+ color: color ?? new Color(0),
55460
+ side: FrontSide
55461
+ });
55462
+ super(geo, [matAlways, matBehind]);
55463
+ __publicField(this, "axis");
55464
+ __publicField(this, "sign");
55465
+ __publicField(this, "_forward");
55466
+ __publicField(this, "_color");
55467
+ __publicField(this, "_highlightColor");
55468
+ __publicField(this, "_materials");
55469
+ this._materials = [matAlways, matBehind];
55470
+ this._forward = new Vector3$1();
55471
+ this.forward[axes] = sign2;
55472
+ this.axis = axes;
55473
+ this.sign = sign2;
55474
+ this._color = color ?? new Color(0);
55475
+ this._highlightColor = this._color.clone().lerp(new Color(13421772), 0.8);
55476
+ this.userData.handle = this;
55477
+ this.quaternion.setFromUnitVectors(new Vector3$1(0, -1, 0), this._forward);
55230
55478
  }
55231
- register() {
55232
- if (this.unregister.length > 0) return;
55233
- const canvas = this.viewer.viewport.canvas;
55234
- this.reg(window, "keydown", this.onKey.bind(this));
55235
- this.reg(window, "keyup", this.onKey.bind(this));
55236
- this.reg(canvas, "pointerdown", this.onMouseDown.bind(this));
55237
- this.reg(canvas, "pointermove", this.onMouseMove.bind(this));
55238
- this.reg(canvas, "pointerup", this.onMouseUp.bind(this));
55239
- this.reg(canvas, "pointerleave", this.onPointerLeave.bind(this));
55479
+ setPosition(position) {
55480
+ this.position.copy(position);
55240
55481
  }
55241
- onPointerLeave(event) {
55242
- var _a2;
55243
- if (this.capturedId !== void 0) {
55244
- return;
55245
- }
55246
- this.faceNormal.set(0, 0, 0);
55247
- (_a2 = this.onFaceEnter) == null ? void 0 : _a2.call(this, this.faceNormal);
55482
+ get forward() {
55483
+ return this._forward;
55248
55484
  }
55249
- capturePointer(pointerId) {
55250
- this.releasePointer();
55251
- this.viewer.viewport.canvas.setPointerCapture(pointerId);
55252
- this.capturedId = pointerId;
55485
+ highlight(value) {
55486
+ this.material[0].color.set(value ? this._highlightColor : this._color);
55487
+ this.material[1].color.set(value ? this._highlightColor : this._color);
55253
55488
  }
55254
- releasePointer() {
55255
- if (this.capturedId === void 0) return;
55256
- this.viewer.viewport.canvas.releasePointerCapture(this.capturedId);
55257
- this.capturedId = void 0;
55489
+ dispose() {
55490
+ this.geometry.dispose();
55491
+ this._materials.forEach((m) => m.dispose());
55492
+ }
55493
+ }
55494
+ function createDoubleCone(size) {
55495
+ const coneHeight = 2 * size;
55496
+ const cone1 = new ConeGeometry(size, coneHeight, 12);
55497
+ cone1.translate(0, coneHeight * 0.75, 0);
55498
+ const cone2 = new ConeGeometry(size, coneHeight, 12);
55499
+ cone2.rotateZ(Math.PI);
55500
+ cone2.translate(0, -coneHeight * 0.75, 0);
55501
+ const mergedGeo = mergeGeometries([cone1, cone2]);
55502
+ cone1.dispose();
55503
+ cone2.dispose();
55504
+ return mergedGeo;
55505
+ }
55506
+ class SectionBoxHandles {
55507
+ constructor() {
55508
+ __publicField(this, "up");
55509
+ __publicField(this, "down");
55510
+ __publicField(this, "left");
55511
+ __publicField(this, "right");
55512
+ __publicField(this, "front");
55513
+ __publicField(this, "back");
55514
+ __publicField(this, "meshes");
55515
+ const size = 2;
55516
+ this.up = new SectionBoxHandle("y", 1, size, new Color(65280));
55517
+ this.down = new SectionBoxHandle("y", -1, size, new Color(65280));
55518
+ this.left = new SectionBoxHandle("x", -1, size, new Color(16711680));
55519
+ this.right = new SectionBoxHandle("x", 1, size, new Color(16711680));
55520
+ this.front = new SectionBoxHandle("z", 1, size, new Color(255));
55521
+ this.back = new SectionBoxHandle("z", -1, size, new Color(255));
55522
+ this.meshes = new Group();
55523
+ this.meshes.add(this.up);
55524
+ this.meshes.add(this.down);
55525
+ this.meshes.add(this.left);
55526
+ this.meshes.add(this.right);
55527
+ this.meshes.add(this.front);
55528
+ this.meshes.add(this.back);
55258
55529
  }
55259
- unregister() {
55260
- this.ctrlDown = false;
55261
- this.mouseDown = false;
55262
- this.releasePointer();
55263
- this.viewer.inputs.registerAll();
55264
- this.unregisters.forEach((unreg) => unreg());
55265
- this.unregisters.length = 0;
55530
+ get visible() {
55531
+ return this.meshes.visible;
55266
55532
  }
55267
- onKey(event) {
55268
- if (this.ctrlDown !== event.ctrlKey) {
55269
- this.ctrlDown = event.ctrlKey;
55270
- this.onMouseMove(this.lastMouse);
55271
- }
55533
+ set visible(value) {
55534
+ this.meshes.visible = value;
55272
55535
  }
55273
- onMouseMove(event) {
55274
- var _a2, _b2, _c;
55275
- this.lastMouse = event;
55276
- if (this.mouseDown) {
55277
- this.onDrag(event);
55278
- return;
55279
- }
55280
- const hits = this.raycast(
55281
- new Vector2$1(event.offsetX, event.offsetY),
55282
- this.ctrlDown
55283
- );
55284
- const hit = hits == null ? void 0 : hits[0];
55285
- const norm = (_a2 = hit == null ? void 0 : hit.face) == null ? void 0 : _a2.normal;
55286
- if (!norm) {
55287
- if (this.faceNormal.x !== 0 || this.faceNormal.y !== 0 || this.faceNormal.z !== 0) {
55288
- this.faceNormal.set(0, 0, 0);
55289
- (_b2 = this.onFaceEnter) == null ? void 0 : _b2.call(this, this.faceNormal);
55290
- }
55291
- return;
55292
- }
55293
- if (this.faceNormal.equals(norm)) {
55294
- return;
55295
- }
55296
- this.faceNormal = norm;
55297
- (_c = this.onFaceEnter) == null ? void 0 : _c.call(this, this.faceNormal);
55536
+ fitBox(box) {
55537
+ const center = box.getCenter(new Vector3$1());
55538
+ this.up.setPosition(new Vector3$1(center.x, box.max.y, center.z));
55539
+ this.down.setPosition(new Vector3$1(center.x, box.min.y, center.z));
55540
+ this.left.setPosition(new Vector3$1(box.min.x, center.y, center.z));
55541
+ this.right.setPosition(new Vector3$1(box.max.x, center.y, center.z));
55542
+ this.front.setPosition(new Vector3$1(center.x, center.y, box.max.z));
55543
+ this.back.setPosition(new Vector3$1(center.x, center.y, box.min.z));
55298
55544
  }
55299
- onMouseUp(event) {
55300
- var _a2, _b2;
55301
- this.releasePointer();
55302
- if (this.mouseDown) {
55303
- this.mouseDown = false;
55304
- this.viewer.inputs.registerAll();
55305
- if (event.pointerType === "mouse") {
55306
- this.onMouseMove(event);
55307
- } else {
55308
- this.faceNormal = new Vector3$1();
55309
- (_a2 = this.onFaceEnter) == null ? void 0 : _a2.call(this, this.faceNormal);
55310
- }
55311
- (_b2 = this.onBoxConfirm) == null ? void 0 : _b2.call(this, this.sharedBox);
55312
- }
55545
+ dispose() {
55546
+ this.up.dispose();
55547
+ this.down.dispose();
55548
+ this.left.dispose();
55549
+ this.right.dispose();
55550
+ this.front.dispose();
55551
+ this.back.dispose();
55313
55552
  }
55314
- onMouseDown(event) {
55315
- var _a2, _b2;
55316
- const hits = this.raycast(
55317
- new Vector2$1(event.offsetX, event.offsetY),
55318
- this.ctrlDown
55319
- );
55320
- const hit = hits == null ? void 0 : hits[0];
55321
- if (!((_a2 = hit == null ? void 0 : hit.face) == null ? void 0 : _a2.normal)) return;
55322
- this.capturePointer(event.pointerId);
55323
- this.lastBox.copy(this.sharedBox);
55324
- this.faceNormal = hit.face.normal;
55325
- this.dragOrigin.copy(hit.point);
55326
- const dist2 = hit.point.clone().dot(this.viewer.camera.forward);
55327
- this.dragpPlane.set(this.viewer.camera.forward, -dist2);
55328
- this.mouseDown = true;
55329
- this.viewer.inputs.unregisterAll();
55330
- (_b2 = this.onFaceEnter) == null ? void 0 : _b2.call(this, this.faceNormal);
55553
+ }
55554
+ class SectionBoxGizmo {
55555
+ constructor(renderer) {
55556
+ __publicField(this, "_renderer");
55557
+ __publicField(this, "cube");
55558
+ __publicField(this, "outline");
55559
+ __publicField(this, "handles");
55560
+ __publicField(this, "_visible", false);
55561
+ this._renderer = renderer;
55562
+ this.cube = new SectionBoxMesh();
55563
+ this.outline = new SectionBoxOutline(new Color(8882833));
55564
+ this.handles = new SectionBoxHandles();
55565
+ this._renderer.add(this.outline);
55566
+ this._renderer.add(this.handles.meshes);
55567
+ this.visible = false;
55331
55568
  }
55332
- onDrag(event) {
55333
- var _a2;
55334
- this.raycaster = this.viewer.raycaster.fromPoint2(
55335
- new Vector2$1(event.offsetX, event.offsetY),
55336
- this.raycaster
55337
- );
55338
- const point = this.raycaster.ray.intersectPlane(this.dragpPlane, new Vector3$1()) ?? this.dragOrigin.clone();
55339
- const delta = point.sub(this.dragOrigin);
55340
- const amount = delta.dot(this.faceNormal);
55341
- const box = this.stretch(this.faceNormal, amount);
55342
- (_a2 = this.onBoxStretch) == null ? void 0 : _a2.call(this, box);
55569
+ get visible() {
55570
+ return this._visible;
55343
55571
  }
55344
- stretch(normal, amount) {
55345
- const result = this.sharedBox.clone();
55346
- if (normal.x > 0.1) {
55347
- result.max.setX(Math.max(this.lastBox.max.x + amount, result.min.x - 1));
55348
- }
55349
- if (normal.x < -0.1) {
55350
- result.min.setX(Math.min(this.lastBox.min.x - amount, result.max.x + 1));
55351
- }
55352
- if (normal.y > 0.1) {
55353
- result.max.setY(Math.max(this.lastBox.max.y + amount, result.min.y - 1));
55354
- }
55355
- if (normal.y < -0.1) {
55356
- result.min.setY(Math.min(this.lastBox.min.y - amount, result.max.y + 1));
55357
- }
55358
- if (normal.z > 0.1) {
55359
- result.max.setZ(Math.max(this.lastBox.max.z + amount, result.min.z - 1));
55360
- }
55361
- if (normal.z < -0.1) {
55362
- result.min.setZ(Math.min(this.lastBox.min.z - amount, result.max.z + 1));
55363
- }
55364
- return result;
55572
+ set visible(value) {
55573
+ this._visible = value;
55574
+ this.cube.visible = value;
55575
+ this.outline.visible = value;
55576
+ this.handles.visible = value;
55365
55577
  }
55366
- raycast(position, reverse) {
55367
- this.raycaster = this.viewer.raycaster.fromPoint2(position, this.raycaster);
55368
- if (reverse) {
55369
- this.raycaster.ray.set(
55370
- this.raycaster.ray.origin.clone().add(this.raycaster.ray.direction.clone().multiplyScalar(this.viewer.settings.camera.far)),
55371
- this.raycaster.ray.direction.negate()
55372
- );
55373
- }
55374
- return this.raycaster.intersectObject(this.cube);
55578
+ fitBox(box) {
55579
+ this.cube.fitBox(box);
55580
+ this.outline.fitBox(box);
55581
+ this.handles.fitBox(box);
55582
+ }
55583
+ dispose() {
55584
+ this._renderer.remove(this.cube);
55585
+ this._renderer.remove(this.outline);
55586
+ this._renderer.remove(this.handles.meshes);
55587
+ this.cube.dispose();
55588
+ this.outline.dispose();
55589
+ this.handles.dispose();
55375
55590
  }
55376
55591
  }
55377
- class SectionBox {
55592
+ let SectionBox$1 = class SectionBox {
55593
+ // -------------------------------------------------------------------------
55594
+ // Constructor
55595
+ // -------------------------------------------------------------------------
55596
+ /**
55597
+ * Creates a new SectionBox gizmo controller.
55598
+ *
55599
+ * @param viewer - The parent {@link Viewer} in which the section box is rendered.
55600
+ */
55378
55601
  constructor(viewer) {
55379
- // dependencies
55602
+ // -------------------------------------------------------------------------
55603
+ // Private fields
55604
+ // -------------------------------------------------------------------------
55380
55605
  __publicField(this, "_viewer");
55381
- // resources
55606
+ __publicField(this, "_gizmos");
55382
55607
  __publicField(this, "_inputs");
55383
- __publicField(this, "_cube");
55384
- __publicField(this, "_outline");
55385
- __publicField(this, "_highlight");
55386
- // State
55387
- __publicField(this, "_normal");
55388
55608
  __publicField(this, "_clip");
55389
55609
  __publicField(this, "_visible");
55390
55610
  __publicField(this, "_interactive");
@@ -55392,21 +55612,13 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
55392
55612
  __publicField(this, "_onBoxConfirm", new distExports.SimpleEventDispatcher());
55393
55613
  __publicField(this, "_onHover", new distExports.SimpleEventDispatcher());
55394
55614
  this._viewer = viewer;
55395
- this._normal = new Vector3$1();
55396
- this._cube = new BoxMesh();
55397
- this._outline = new BoxOutline();
55398
- this._highlight = new BoxHighlight();
55399
- this.renderer.add(this._cube);
55400
- this.renderer.add(this._outline);
55401
- this.renderer.add(this._highlight);
55615
+ this._gizmos = new SectionBoxGizmo(viewer.renderer);
55402
55616
  this._inputs = new BoxInputs(
55403
55617
  viewer,
55404
- this._cube,
55618
+ this._gizmos.handles,
55405
55619
  this._viewer.renderer.section.box
55406
55620
  );
55407
55621
  this._inputs.onFaceEnter = (normal) => {
55408
- this._normal = normal;
55409
- if (this.visible) this._highlight.highlight(this.section.box, normal);
55410
55622
  this._onHover.dispatch(normal.x !== 0 || normal.y !== 0 || normal.z !== 0);
55411
55623
  this.renderer.needsUpdate = true;
55412
55624
  };
@@ -55421,37 +55633,61 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
55421
55633
  this.update();
55422
55634
  }
55423
55635
  /**
55424
- * Signal dispatched when clip, show, or interactive are updated.
55636
+ * @internal
55637
+ * A convenience getter to the viewer's renderer.
55638
+ */
55639
+ get renderer() {
55640
+ return this._viewer.renderer;
55641
+ }
55642
+ /**
55643
+ * @internal
55644
+ * A convenience getter to the `Section` module in the renderer.
55645
+ */
55646
+ get section() {
55647
+ return this._viewer.renderer.section;
55648
+ }
55649
+ // -------------------------------------------------------------------------
55650
+ // Public Signals
55651
+ // -------------------------------------------------------------------------
55652
+ /**
55653
+ * Dispatches when any of the following properties change:
55654
+ * - {@link clip} (clipping planes active)
55655
+ * - {@link visible} (gizmo visibility)
55656
+ * - {@link interactive} (pointer inputs active)
55425
55657
  */
55426
55658
  get onStateChanged() {
55427
55659
  return this._onStateChanged.asEvent();
55428
55660
  }
55429
55661
  /**
55430
- * Signal dispatched when user is done manipulating the box.
55662
+ * Dispatches when the user finishes manipulating (dragging) the box.
55663
+ * The payload is the final {@link THREE.Box3} used for clipping.
55431
55664
  */
55432
55665
  get onBoxConfirm() {
55433
55666
  return this._onBoxConfirm.asEvent();
55434
55667
  }
55435
55668
  /**
55436
- * Signal dispatched with true when pointer enters box and false when pointer leaves.
55669
+ * Dispatches a boolean indicating pointer hover state on the box handles:
55670
+ * - `true` if the pointer has entered a handle
55671
+ * - `false` if it has left or no handle is hovered
55437
55672
  */
55438
55673
  get onHover() {
55439
55674
  return this._onHover.asEvent();
55440
55675
  }
55441
- get renderer() {
55442
- return this._viewer.renderer;
55443
- }
55444
- get section() {
55445
- return this._viewer.renderer.section;
55446
- }
55676
+ // -------------------------------------------------------------------------
55677
+ // Public Properties
55678
+ // -------------------------------------------------------------------------
55447
55679
  /**
55448
- * Section bounding box, to update the box use fitBox.
55680
+ * The shared bounding box that defines the section region.
55681
+ *
55682
+ * To programmatically update the box, see {@link fitBox}.
55449
55683
  */
55450
55684
  get box() {
55451
55685
  return this.section.box;
55452
55686
  }
55453
55687
  /**
55454
- * Determines whether the section gizmo will section the model with clipping planes.
55688
+ * Determines whether the section gizmo applies clipping planes to the model.
55689
+ *
55690
+ * When `true`, `renderer.section.active` is enabled.
55455
55691
  */
55456
55692
  get clip() {
55457
55693
  return this._clip ?? false;
@@ -55463,71 +55699,79 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
55463
55699
  this._onStateChanged.dispatch();
55464
55700
  }
55465
55701
  /**
55466
- * Determines whether the gizmo reacts to user inputs.
55702
+ * Determines whether the gizmo is interactive (i.e. responds to pointer events).
55703
+ *
55704
+ * When `true`, pointer events are registered and box handles can be dragged.
55467
55705
  */
55468
55706
  get interactive() {
55469
55707
  return this._interactive ?? false;
55470
55708
  }
55471
55709
  set interactive(value) {
55472
55710
  if (value === this._interactive) return;
55473
- if (!this._interactive && value) this._inputs.register();
55474
- if (this._interactive && !value) this._inputs.unregister();
55711
+ if (!this._interactive && value) {
55712
+ this._inputs.register();
55713
+ }
55714
+ if (this._interactive && !value) {
55715
+ this._inputs.unregister();
55716
+ }
55475
55717
  this._interactive = value;
55476
- this._highlight.visible = false;
55477
55718
  this.renderer.needsUpdate = true;
55478
55719
  this._onStateChanged.dispatch();
55479
55720
  }
55480
55721
  /**
55481
- * Determines whether the gizmo will be rendered.
55722
+ * Determines whether the section box gizmo is visible in the scene.
55482
55723
  */
55483
55724
  get visible() {
55484
55725
  return this._visible ?? false;
55485
55726
  }
55486
55727
  set visible(value) {
55487
55728
  if (value === this._visible) return;
55488
- this._visible = value;
55489
- this._cube.visible = value;
55490
- this._outline.visible = value;
55491
- this._highlight.visible = value;
55492
- if (value) this.update();
55729
+ this._gizmos.visible = value;
55730
+ if (value) {
55731
+ this.update();
55732
+ }
55493
55733
  this.renderer.needsUpdate = true;
55494
55734
  this._onStateChanged.dispatch();
55495
55735
  }
55736
+ // -------------------------------------------------------------------------
55737
+ // Public Methods
55738
+ // -------------------------------------------------------------------------
55496
55739
  /**
55497
- * Sets the section gizmo size to match the given box.
55498
- * @param {THREE.Box3} box - The box to match the section gizmo size to.
55499
- * @param {number} [padding=1] - The padding to apply to the box.
55740
+ * Resizes the section gizmo to match the given box, optionally expanded by a padding.
55741
+ * After resizing, this method also updates the renderer's clipping box.
55742
+ *
55743
+ * @param box - The bounding box to match (required).
55744
+ * @param padding - The scalar amount by which to expand the bounding box. Default is `1`.
55500
55745
  */
55501
55746
  fitBox(box, padding = 1) {
55502
55747
  if (!box) return;
55503
55748
  const b = box.expandByScalar(padding);
55504
- this._cube.fitBox(b);
55505
- this._outline.fitBox(b);
55749
+ this._gizmos.fitBox(b);
55506
55750
  this.renderer.section.fitBox(b);
55507
55751
  this._onBoxConfirm.dispatch(this.box);
55508
55752
  this.renderer.needsUpdate = true;
55509
55753
  }
55510
55754
  /**
55511
- * Call this if there were direct changes to renderer.section
55755
+ * Updates the section box to match the current size of `this.section.box`.
55756
+ *
55757
+ * Call this if the renderer's section box is changed by code outside this class.
55512
55758
  */
55513
55759
  update() {
55514
55760
  this.fitBox(this.section.box, 0);
55515
- this._highlight.highlight(this.section.box, this._normal);
55516
55761
  this.renderer.needsUpdate = true;
55517
55762
  }
55518
55763
  /**
55519
- * Removes gizmo from rendering and inputs and dispose all resources.
55764
+ * Disposes of the gizmo and input event listeners, cleaning up related resources.
55765
+ *
55766
+ * After disposal, this `SectionBox` instance should no longer be used.
55520
55767
  */
55521
55768
  dispose() {
55522
- this.renderer.remove(this._cube);
55523
- this.renderer.remove(this._outline);
55524
- this.renderer.remove(this._highlight);
55769
+ this._onBoxConfirm.clear();
55770
+ this._onHover.clear();
55771
+ this._gizmos.dispose();
55525
55772
  this._inputs.unregister();
55526
- this._cube.dispose();
55527
- this._outline.dispose();
55528
- this._highlight.dispose();
55529
55773
  }
55530
- }
55774
+ };
55531
55775
  class Gizmos {
55532
55776
  constructor(viewer, camera2) {
55533
55777
  __publicField(this, "viewer");
@@ -55559,7 +55803,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
55559
55803
  var _a2;
55560
55804
  this.viewer = viewer;
55561
55805
  this._measure = new Measure(viewer);
55562
- this.section = new SectionBox(viewer);
55806
+ this.section = new SectionBox$1(viewer);
55563
55807
  this.loading = new GizmoLoading(viewer);
55564
55808
  this.orbit = new GizmoOrbit(
55565
55809
  viewer.renderer,
@@ -55637,7 +55881,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
55637
55881
  this.minZ.constant = -box.min.z;
55638
55882
  this.box.copy(box);
55639
55883
  this._renderer.needsUpdate = true;
55640
- this._renderer.skipAntialias = true;
55641
55884
  }
55642
55885
  /**
55643
55886
  * Determines whether objecets outside the section box will be culled or not.
@@ -56596,7 +56839,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
56596
56839
  __publicField(this, "_composer");
56597
56840
  __publicField(this, "_materials");
56598
56841
  __publicField(this, "_renderText");
56599
- __publicField(this, "_skipAntialias");
56600
56842
  __publicField(this, "_needsUpdate");
56601
56843
  __publicField(this, "_onSceneUpdate", new distExports$1.SignalDispatcher());
56602
56844
  __publicField(this, "_onBoxUpdated", new distExports$1.SignalDispatcher());
@@ -56658,17 +56900,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
56658
56900
  set needsUpdate(value) {
56659
56901
  this._needsUpdate = this._needsUpdate || value;
56660
56902
  }
56661
- /**
56662
- * Indicates whether the next render should skip antialiasing.
56663
- * Useful for expensive operations such as the section box.
56664
- * Can only be set to true. Cleared on each render.
56665
- */
56666
- get skipAntialias() {
56667
- return this._skipAntialias;
56668
- }
56669
- set skipAntialias(value) {
56670
- this._skipAntialias = this._skipAntialias || value;
56671
- }
56672
56903
  /**
56673
56904
  * Removes all objects from rendering and disposes the WebGL context.
56674
56905
  */
@@ -56689,6 +56920,12 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
56689
56920
  this._scene.scene.background = color;
56690
56921
  this.needsUpdate = true;
56691
56922
  }
56923
+ get modelMaterial() {
56924
+ return this._scene.modelMaterial;
56925
+ }
56926
+ set modelMaterial(material) {
56927
+ this._scene.modelMaterial = material;
56928
+ }
56692
56929
  /**
56693
56930
  * Signal dispatched at the end of each frame if the scene was updated, such as visibility changes.
56694
56931
  */
@@ -56713,6 +56950,12 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
56713
56950
  this._renderText = value;
56714
56951
  this.textRenderer.domElement.style.display = value ? "block" : "none";
56715
56952
  }
56953
+ get smallGhostThreshold() {
56954
+ return this._scene.smallGhostThreshold;
56955
+ }
56956
+ set smallGhostThreshold(value) {
56957
+ this._scene.smallGhostThreshold = value;
56958
+ }
56716
56959
  /**
56717
56960
  * Returns the bounding box encompassing all rendered objects.
56718
56961
  * @param target - Box in which to copy the result. A new instance is created if undefined.
@@ -56752,7 +56995,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
56752
56995
  this._composer.render();
56753
56996
  }
56754
56997
  this._needsUpdate = false;
56755
- this.skipAntialias = false;
56756
56998
  if (this.textEnabled && this._scene.has2dObjects()) {
56757
56999
  this.textRenderer.render(this._scene.scene, this._camera.three);
56758
57000
  }
@@ -57018,14 +57260,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57018
57260
  groundColor: get2("skybox.groundColor", strToColor),
57019
57261
  sharpness: get2("skybox.sharpness", Number.parseFloat)
57020
57262
  },
57021
- groundPlane: {
57022
- visible: get2("groundPlane.visible", strToBool),
57023
- encoding: get2("groundPlane.encoding"),
57024
- texture: get2("groundPlane.texture"),
57025
- opacity: get2("groundPlane.opacity", Number.parseFloat),
57026
- color: get2("groundPlane.color", strToColor),
57027
- size: get2("groundPlane.size", Number.parseFloat)
57028
- },
57029
57263
  skylight: {
57030
57264
  skyColor: get2("skylight.skyColor", strToColor),
57031
57265
  groundColor: get2("skylight.groundColor", strToColor),
@@ -57053,9 +57287,9 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57053
57287
  color: get2("materials.highlight.color", strToColor),
57054
57288
  opacity: get2("materials.highlight.opacity", Number.parseFloat)
57055
57289
  },
57056
- isolation: {
57057
- color: get2("materials.isolation.color", strToColor),
57058
- opacity: get2("materials.isolation.opacity", Number.parseFloat)
57290
+ ghost: {
57291
+ color: get2("materials.ghost.color", strToColor),
57292
+ opacity: get2("materials.ghost.opacity", Number.parseFloat)
57059
57293
  },
57060
57294
  section: {
57061
57295
  strokeWidth: get2("materials.section.strokeWidth", Number.parseFloat),
@@ -57802,17 +58036,16 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57802
58036
  class Marshal {
57803
58037
  constructor(initialSize = 1024) {
57804
58038
  __publicField(this, "buffer");
57805
- __publicField(this, "dataView");
57806
- __publicField(this, "readOffset", 0);
57807
- __publicField(this, "writeOffset", 0);
58039
+ __publicField(this, "_dataView");
58040
+ __publicField(this, "_offset", 0);
57808
58041
  this.buffer = new ArrayBuffer(initialSize);
57809
- this.dataView = new DataView(this.buffer);
58042
+ this._dataView = new DataView(this.buffer);
57810
58043
  }
57811
58044
  getBuffer() {
57812
- return this.buffer.slice(0, this.writeOffset);
58045
+ return this.buffer.slice(0, this._offset);
57813
58046
  }
57814
58047
  ensureCapacity(additionalSize) {
57815
- const requiredSize = this.writeOffset + additionalSize;
58048
+ const requiredSize = this._offset + additionalSize;
57816
58049
  if (requiredSize > this.buffer.byteLength) {
57817
58050
  let newLength = this.buffer.byteLength;
57818
58051
  while (newLength < requiredSize) {
@@ -57821,21 +58054,162 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57821
58054
  const newBuffer = new ArrayBuffer(newLength);
57822
58055
  new Uint8Array(newBuffer).set(new Uint8Array(this.buffer));
57823
58056
  this.buffer = newBuffer;
57824
- this.dataView = new DataView(this.buffer);
58057
+ this._dataView = new DataView(this.buffer);
57825
58058
  }
57826
58059
  }
57827
58060
  writeData(data2) {
57828
58061
  this.ensureCapacity(data2.byteLength);
57829
- new Uint8Array(this.buffer, this.writeOffset).set(new Uint8Array(data2));
57830
- this.writeOffset += data2.byteLength;
58062
+ new Uint8Array(this.buffer, this._offset).set(new Uint8Array(data2));
58063
+ this._offset += data2.byteLength;
57831
58064
  }
57832
- // -------------------- Matrix44 Methods --------------------
58065
+ // -------------------- Matrix44 -------------------
57833
58066
  writeMatrix44(data2) {
57834
58067
  this.ensureCapacity(4 * 4 * 4);
57835
58068
  this.writeArray(data2.toArray(), 4, (element) => {
57836
58069
  this.writeFloat(element);
57837
58070
  });
57838
58071
  }
58072
+ // -------------------- Boolean -------------------
58073
+ writeBoolean(value) {
58074
+ this.ensureCapacity(4);
58075
+ this._dataView.setUint32(this._offset, value ? 1 : 0, true);
58076
+ this._offset += 4;
58077
+ }
58078
+ // -------------------- Int -------------------
58079
+ writeInt(value) {
58080
+ this.ensureCapacity(4);
58081
+ this._dataView.setInt32(this._offset, value, true);
58082
+ this._offset += 4;
58083
+ }
58084
+ // -------------------- UInt -------------------
58085
+ writeUInt(value) {
58086
+ this.ensureCapacity(4);
58087
+ this._dataView.setUint32(this._offset, value, true);
58088
+ this._offset += 4;
58089
+ }
58090
+ // -------------------- Float -------------------
58091
+ writeFloat(value) {
58092
+ this.ensureCapacity(4);
58093
+ this._dataView.setFloat32(this._offset, value, true);
58094
+ this._offset += 4;
58095
+ }
58096
+ // -------------------- String -------------------
58097
+ writeString(value) {
58098
+ const textEncoder = new TextEncoder();
58099
+ const encodedString = textEncoder.encode(value + "\0");
58100
+ this.ensureCapacity(4 + encodedString.byteLength);
58101
+ this.writeUInt(encodedString.length);
58102
+ new Uint8Array(this.buffer, this._offset).set(encodedString);
58103
+ this._offset += encodedString.length;
58104
+ }
58105
+ // -------------------- HitCheckResult -------------------
58106
+ writeHitCheckResult(data2) {
58107
+ this.ensureCapacity(4 + 4 + 4 * 3 + 4 * 3);
58108
+ this.writeUInt(data2.vimHandle);
58109
+ this.writeUInt(data2.nodeIndex);
58110
+ this.writeVector3(data2.worldPosition);
58111
+ this.writeVector3(data2.worldNormal);
58112
+ }
58113
+ // -------------------- VimStatus -------------------
58114
+ writeVimStatus(data2) {
58115
+ this.ensureCapacity(4 + 4);
58116
+ this.writeUInt(data2.status);
58117
+ this.writeFloat(data2.progress);
58118
+ }
58119
+ // -------------------- Vector2 -------------------
58120
+ writeVector2(data2) {
58121
+ this.ensureCapacity(4 + 4);
58122
+ this.writeFloat(data2.x);
58123
+ this.writeFloat(data2.y);
58124
+ }
58125
+ // -------------------- Vector3 -------------------
58126
+ writeVector3(data2) {
58127
+ this.ensureCapacity(4 + 4 + 4);
58128
+ this.writeFloat(data2.x);
58129
+ this.writeFloat(data2.y);
58130
+ this.writeFloat(data2.z);
58131
+ }
58132
+ // -------------------- Vector4 -------------------
58133
+ writeVector4(data2) {
58134
+ this.ensureCapacity(4 + 4 + 4 + 4);
58135
+ this.writeFloat(data2.x);
58136
+ this.writeFloat(data2.y);
58137
+ this.writeFloat(data2.z);
58138
+ this.writeFloat(data2.w);
58139
+ }
58140
+ // -------------------- RGBA -------------------
58141
+ writeRGBA(color) {
58142
+ this.ensureCapacity(4 + 4 + 4 + 4);
58143
+ this.writeFloat(color.r);
58144
+ this.writeFloat(color.g);
58145
+ this.writeFloat(color.b);
58146
+ this.writeFloat(color.a);
58147
+ }
58148
+ // -------------------- RGB -------------------
58149
+ writeRGB(color) {
58150
+ this.ensureCapacity(4 + 4 + 4 + 4);
58151
+ this.writeFloat(color.r);
58152
+ this.writeFloat(color.g);
58153
+ this.writeFloat(color.b);
58154
+ }
58155
+ // -------------------- RGBA32 -------------------
58156
+ writeRGBA32(color) {
58157
+ this.ensureCapacity(4);
58158
+ this.writeUInt(color.hex);
58159
+ }
58160
+ // -------------------- CameraPositionAndTarget -------------------
58161
+ writeSegment(segment) {
58162
+ this.ensureCapacity(4 * 3 * 2);
58163
+ this.writeVector3(segment.origin);
58164
+ this.writeVector3(segment.target);
58165
+ }
58166
+ // -------------------- Box3 -------------------
58167
+ writeBox3(data2) {
58168
+ this.ensureCapacity(4 * 3 * 2);
58169
+ this.writeVector3(data2.min);
58170
+ this.writeVector3(data2.max);
58171
+ }
58172
+ // -------------------- SectionBox -------------------
58173
+ writeSectionBoxState(data2) {
58174
+ this.writeBoolean(data2.enabled);
58175
+ this.writeBoolean(data2.visible);
58176
+ this.writeBoolean(data2.interactible);
58177
+ this.writeBoolean(data2.clip);
58178
+ this.writeBox3(data2.box);
58179
+ }
58180
+ // -------------------- Array of Int -------------------
58181
+ writeArrayOfInt(values) {
58182
+ this.writeArray(values, 4, (v) => this.writeInt(v));
58183
+ }
58184
+ // -------------------- Array of UInt -------------------
58185
+ writeArrayOfUInt(values) {
58186
+ this.writeArray(values, 4, (v) => this.writeUInt(v));
58187
+ }
58188
+ // -------------------- Array of Float -------------------
58189
+ writeArrayOfFloat(values) {
58190
+ this.writeArray(values, 4, (v) => this.writeFloat(v));
58191
+ }
58192
+ // -------------------- Array of Bool -------------------
58193
+ writeArrayOfBool(values) {
58194
+ this.writeArray(values, 4, (v) => this.writeBoolean(v));
58195
+ }
58196
+ // -------------------- Array of RGBA32 -------------------
58197
+ writeArrayOfRGBA32(values) {
58198
+ this.writeArray(values, 4, (v) => this.writeRGBA32(v));
58199
+ }
58200
+ // -------------------- Helpers --------------------
58201
+ writeArray(data2, sizeT, write) {
58202
+ this.ensureCapacity(4 + data2.length * sizeT);
58203
+ this.writeUInt(data2.length);
58204
+ data2.forEach((value) => write(value));
58205
+ }
58206
+ }
58207
+ class ReadMarshal {
58208
+ constructor(buffer) {
58209
+ __publicField(this, "_dataView");
58210
+ __publicField(this, "_offset", 0);
58211
+ this._dataView = new DataView(buffer);
58212
+ }
57839
58213
  readMatrix44() {
57840
58214
  const m00 = this.readFloat();
57841
58215
  const m01 = this.readFloat();
@@ -57855,74 +58229,33 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57855
58229
  const m33 = this.readFloat();
57856
58230
  return new Matrix4(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);
57857
58231
  }
57858
- // -------------------- Boolean Methods --------------------
57859
- writeBoolean(value) {
57860
- this.ensureCapacity(4);
57861
- this.dataView.setUint32(this.writeOffset, value ? 1 : 0, true);
57862
- this.writeOffset += 4;
57863
- }
57864
- readBoolean() {
57865
- const value = this.dataView.getUint32(this.readOffset, true);
57866
- this.readOffset += 4;
57867
- return value !== 0;
57868
- }
57869
- // -------------------- Int Methods --------------------
57870
- writeInt(value) {
57871
- this.ensureCapacity(4);
57872
- this.dataView.setInt32(this.writeOffset, value, true);
57873
- this.writeOffset += 4;
57874
- }
57875
58232
  readInt() {
57876
- const value = this.dataView.getInt32(this.readOffset, true);
57877
- this.readOffset += 4;
58233
+ const value = this._dataView.getInt32(this._offset, true);
58234
+ this._offset += 4;
57878
58235
  return value;
57879
58236
  }
57880
- // -------------------- UInt Methods --------------------
57881
- writeUInt(value) {
57882
- this.ensureCapacity(4);
57883
- this.dataView.setUint32(this.writeOffset, value, true);
57884
- this.writeOffset += 4;
57885
- }
57886
58237
  readUInt() {
57887
- const value = this.dataView.getUint32(this.readOffset, true);
57888
- this.readOffset += 4;
58238
+ const value = this._dataView.getUint32(this._offset, true);
58239
+ this._offset += 4;
57889
58240
  return value;
57890
58241
  }
57891
- // -------------------- Float Methods --------------------
57892
- writeFloat(value) {
57893
- this.ensureCapacity(4);
57894
- this.dataView.setFloat32(this.writeOffset, value, true);
57895
- this.writeOffset += 4;
57896
- }
57897
58242
  readFloat() {
57898
- const value = this.dataView.getFloat32(this.readOffset, true);
57899
- this.readOffset += 4;
58243
+ const value = this._dataView.getFloat32(this._offset, true);
58244
+ this._offset += 4;
57900
58245
  return value;
57901
58246
  }
57902
- // -------------------- String Methods --------------------
57903
- writeString(value) {
57904
- const textEncoder = new TextEncoder();
57905
- const encodedString = textEncoder.encode(value + "\0");
57906
- this.ensureCapacity(4 + encodedString.byteLength);
57907
- this.writeUInt(encodedString.length);
57908
- new Uint8Array(this.buffer, this.writeOffset).set(encodedString);
57909
- this.writeOffset += encodedString.length;
58247
+ readBoolean() {
58248
+ const value = this._dataView.getUint32(this._offset, true);
58249
+ this._offset += 4;
58250
+ return value !== 0;
57910
58251
  }
57911
58252
  readString() {
57912
58253
  const length = this.readUInt();
57913
58254
  const textDecoder = new TextDecoder();
57914
- const stringData = new Uint8Array(this.buffer, this.readOffset, length - 1);
57915
- this.readOffset += length;
58255
+ const stringData = new Uint8Array(this._dataView.buffer, this._offset, length - 1);
58256
+ this._offset += length;
57916
58257
  return textDecoder.decode(stringData);
57917
58258
  }
57918
- // -------------------- HitCheckResult Methods --------------------
57919
- writeHitCheckResult(data2) {
57920
- this.ensureCapacity(4 + 4 + 4 * 3 + 4 * 3);
57921
- this.writeUInt(data2.vimHandle);
57922
- this.writeUInt(data2.nodeIndex);
57923
- this.writeVector3(data2.worldPosition);
57924
- this.writeVector3(data2.worldNormal);
57925
- }
57926
58259
  readHitCheckResult() {
57927
58260
  const vimHandle = this.readUInt();
57928
58261
  const nodeIndex = this.readUInt();
@@ -57935,12 +58268,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57935
58268
  worldNormal
57936
58269
  };
57937
58270
  }
57938
- // -------------------- VimStatus Methods --------------------
57939
- writeVimStatus(data2) {
57940
- this.ensureCapacity(4 + 4);
57941
- this.writeUInt(data2.status);
57942
- this.writeFloat(data2.progress);
57943
- }
57944
58271
  readVimStatus() {
57945
58272
  const status = this.readUInt();
57946
58273
  const progress = this.readFloat();
@@ -57949,38 +58276,17 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57949
58276
  progress
57950
58277
  };
57951
58278
  }
57952
- // -------------------- Vector2 Methods --------------------
57953
- writeVector2(data2) {
57954
- this.ensureCapacity(4 + 4);
57955
- this.writeFloat(data2.x);
57956
- this.writeFloat(data2.y);
57957
- }
57958
58279
  readVector2() {
57959
58280
  const x = this.readFloat();
57960
58281
  const y = this.readFloat();
57961
58282
  return new Vector2(x, y);
57962
58283
  }
57963
- // -------------------- Vector3 Methods --------------------
57964
- writeVector3(data2) {
57965
- this.ensureCapacity(4 + 4 + 4);
57966
- this.writeFloat(data2.x);
57967
- this.writeFloat(data2.y);
57968
- this.writeFloat(data2.z);
57969
- }
57970
58284
  readVector3() {
57971
58285
  const x = this.readFloat();
57972
58286
  const y = this.readFloat();
57973
58287
  const z = this.readFloat();
57974
58288
  return new Vector3(x, y, z);
57975
58289
  }
57976
- // -------------------- Vector4 Methods --------------------
57977
- writeVector4(data2) {
57978
- this.ensureCapacity(4 + 4 + 4 + 4);
57979
- this.writeFloat(data2.x);
57980
- this.writeFloat(data2.y);
57981
- this.writeFloat(data2.z);
57982
- this.writeFloat(data2.w);
57983
- }
57984
58290
  readVector4() {
57985
58291
  const x = this.readFloat();
57986
58292
  const y = this.readFloat();
@@ -57993,14 +58299,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
57993
58299
  w
57994
58300
  };
57995
58301
  }
57996
- // -------------------- RGBA Methods --------------------
57997
- writeRGBA(color) {
57998
- this.ensureCapacity(4 + 4 + 4 + 4);
57999
- this.writeFloat(color.r);
58000
- this.writeFloat(color.g);
58001
- this.writeFloat(color.b);
58002
- this.writeFloat(color.a);
58003
- }
58004
58302
  readRGBA() {
58005
58303
  const r = this.readFloat();
58006
58304
  const g = this.readFloat();
@@ -58008,91 +58306,55 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58008
58306
  const a = this.readFloat();
58009
58307
  return new RGBA(r, g, b, a);
58010
58308
  }
58011
- // -------------------- RGB Methods --------------------
58012
- writeRGB(color) {
58013
- this.ensureCapacity(4 + 4 + 4 + 4);
58014
- this.writeFloat(color.r);
58015
- this.writeFloat(color.g);
58016
- this.writeFloat(color.b);
58017
- }
58018
- readRGB() {
58019
- const r = this.readFloat();
58020
- const g = this.readFloat();
58021
- const b = this.readFloat();
58022
- return new RGB(r, g, b);
58023
- }
58024
- // -------------------- RGBA32 Methods --------------------
58025
- writeRGBA32(color) {
58026
- this.ensureCapacity(4);
58027
- this.writeUInt(color.hex);
58028
- }
58029
- readRGBA32() {
58030
- const hex = this.readUInt();
58031
- return new RGBA32(hex);
58032
- }
58033
- // -------------------- CameraPositionAndTarget Methods --------------------
58034
- writeSegment(segment) {
58035
- this.ensureCapacity(4 * 3 * 2);
58036
- this.writeVector3(segment.origin);
58037
- this.writeVector3(segment.target);
58038
- }
58039
- readSegment() {
58040
- const position = this.readVector3();
58041
- const target = this.readVector3();
58042
- return new Segment(position, target);
58309
+ readRGB() {
58310
+ const r = this.readFloat();
58311
+ const g = this.readFloat();
58312
+ const b = this.readFloat();
58313
+ return new RGB(r, g, b);
58043
58314
  }
58044
- // -------------------- Box3 Methods --------------------
58045
- writeBox3(data2) {
58046
- this.ensureCapacity(4 * 3 * 2);
58047
- this.writeVector3(data2.min);
58048
- this.writeVector3(data2.max);
58315
+ readRGBA32() {
58316
+ const hex = this.readUInt();
58317
+ return new RGBA32(hex);
58049
58318
  }
58050
58319
  readBox3() {
58051
58320
  const min2 = this.readVector3();
58052
58321
  const max2 = this.readVector3();
58053
58322
  return new Box3(min2, max2);
58054
58323
  }
58055
- // -------------------- Array of Int Methods --------------------
58056
- writeArrayOfInt(values) {
58057
- this.writeArray(values, 4, (v) => this.writeInt(v));
58324
+ readSegment() {
58325
+ const position = this.readVector3();
58326
+ const target = this.readVector3();
58327
+ return new Segment(position, target);
58328
+ }
58329
+ readSectionBoxState() {
58330
+ const enabled = this.readBoolean();
58331
+ const visible2 = this.readBoolean();
58332
+ const interactible = this.readBoolean();
58333
+ const clip = this.readBoolean();
58334
+ const box = this.readBox3();
58335
+ return {
58336
+ enabled,
58337
+ visible: visible2,
58338
+ interactible,
58339
+ clip,
58340
+ box
58341
+ };
58058
58342
  }
58059
58343
  readArrayOfInt() {
58060
58344
  return this.readArray(() => this.readInt());
58061
58345
  }
58062
- // -------------------- Array of UInt Methods --------------------
58063
- writeArrayOfUInt(values) {
58064
- this.writeArray(values, 4, (v) => this.writeUInt(v));
58065
- }
58066
58346
  readArrayOfUInt() {
58067
58347
  return this.readArray(() => this.readUInt());
58068
58348
  }
58069
- // -------------------- Array of Float Methods --------------------
58070
- writeArrayOfFloat(values) {
58071
- this.writeArray(values, 4, (v) => this.writeFloat(v));
58072
- }
58073
58349
  readArrayOfFloat() {
58074
58350
  return this.readArray(() => this.readFloat());
58075
58351
  }
58076
- // -------------------- Array of Bool Methods --------------------
58077
- writeArrayOfBool(values) {
58078
- this.writeArray(values, 4, (v) => this.writeBoolean(v));
58079
- }
58080
58352
  readArrayOfBool() {
58081
58353
  return this.readArray(() => this.readBoolean());
58082
58354
  }
58083
- // -------------------- Array of RGBA32 Methods --------------------
58084
- writeArrayOfRGBA32(values) {
58085
- this.writeArray(values, 4, (v) => this.writeRGBA32(v));
58086
- }
58087
58355
  readArrayOfRGBA32() {
58088
58356
  return this.readArray(() => this.readRGBA32());
58089
58357
  }
58090
- // -------------------- Helpers --------------------
58091
- writeArray(data2, sizeT, write) {
58092
- this.ensureCapacity(4 + data2.length * sizeT);
58093
- this.writeUInt(data2.length);
58094
- data2.forEach((value) => write(value));
58095
- }
58096
58358
  readArray(read) {
58097
58359
  const length = this.readUInt();
58098
58360
  const array = [];
@@ -58127,17 +58389,17 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58127
58389
  MaterialHandles.Invisible
58128
58390
  ];
58129
58391
  class RpcClient {
58130
- constructor(_messenger) {
58131
- __publicField(this, "_messenger");
58392
+ constructor(_socket) {
58393
+ __publicField(this, "_socket");
58132
58394
  // RPC Generated Code
58133
- __publicField(this, "API_VERSION", "5.0.0");
58134
- this._messenger = _messenger;
58135
- }
58136
- get url() {
58137
- return this._messenger.url;
58395
+ __publicField(this, "API_VERSION", "5.1.0");
58396
+ this._socket = _socket;
58138
58397
  }
58139
58398
  get connected() {
58140
- return this._messenger.state.status === "connected";
58399
+ return this._socket.state.status === "connected";
58400
+ }
58401
+ get url() {
58402
+ return this._socket.url;
58141
58403
  }
58142
58404
  RPCAddNodeFlags(componentHandle, nodes, flags) {
58143
58405
  const marshal = new Marshal();
@@ -58145,18 +58407,18 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58145
58407
  marshal.writeUInt(componentHandle);
58146
58408
  marshal.writeArrayOfUInt(nodes);
58147
58409
  marshal.writeUInt(flags);
58148
- this._messenger.sendRPC(marshal);
58410
+ this._socket.sendRPC(marshal);
58149
58411
  }
58150
58412
  RPCClearMaterialOverrides(componentHandle) {
58151
58413
  const marshal = new Marshal();
58152
58414
  marshal.writeString("RPCClearMaterialOverrides");
58153
58415
  marshal.writeUInt(componentHandle);
58154
- this._messenger.sendRPC(marshal);
58416
+ this._socket.sendRPC(marshal);
58155
58417
  }
58156
58418
  RPCClearScene() {
58157
58419
  const marshal = new Marshal();
58158
58420
  marshal.writeString("RPCClearScene");
58159
- this._messenger.sendRPC(marshal);
58421
+ this._socket.sendRPC(marshal);
58160
58422
  }
58161
58423
  async RPCCreateMaterialInstances(materialHandle, smoothness, colors) {
58162
58424
  const marshal = new Marshal();
@@ -58164,7 +58426,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58164
58426
  marshal.writeUInt(materialHandle);
58165
58427
  marshal.writeUInt(smoothness);
58166
58428
  marshal.writeArrayOfRGBA32(colors);
58167
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58429
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58168
58430
  const ret = returnMarshal.readUInt();
58169
58431
  return ret;
58170
58432
  }
@@ -58174,7 +58436,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58174
58436
  marshal.writeVector3(position);
58175
58437
  marshal.writeRGBA32(color);
58176
58438
  marshal.writeString(text);
58177
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58439
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58178
58440
  const ret = returnMarshal.readUInt();
58179
58441
  return ret;
58180
58442
  }
@@ -58182,25 +58444,19 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58182
58444
  const marshal = new Marshal();
58183
58445
  marshal.writeString("RPCDestroyMaterialInstances");
58184
58446
  marshal.writeArrayOfUInt(materialInstanceHandle);
58185
- this._messenger.sendRPC(marshal);
58447
+ this._socket.sendRPC(marshal);
58186
58448
  }
58187
58449
  RPCDestroyText(componentHandle) {
58188
58450
  const marshal = new Marshal();
58189
58451
  marshal.writeString("RPCDestroyText");
58190
58452
  marshal.writeUInt(componentHandle);
58191
- this._messenger.sendRPC(marshal);
58192
- }
58193
- RPCEnableSectionBox(enable) {
58194
- const marshal = new Marshal();
58195
- marshal.writeString("RPCEnableSectionBox");
58196
- marshal.writeBoolean(enable);
58197
- this._messenger.sendRPC(marshal);
58453
+ this._socket.sendRPC(marshal);
58198
58454
  }
58199
58455
  async RPCFrameAll(blendTime) {
58200
58456
  const marshal = new Marshal();
58201
58457
  marshal.writeString("RPCFrameAll");
58202
58458
  marshal.writeFloat(blendTime);
58203
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58459
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58204
58460
  const ret = returnMarshal.readSegment();
58205
58461
  return ret;
58206
58462
  }
@@ -58209,7 +58465,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58209
58465
  marshal.writeString("RPCFrameBox");
58210
58466
  marshal.writeBox3(box);
58211
58467
  marshal.writeFloat(blendTime);
58212
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58468
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58213
58469
  const ret = returnMarshal.readSegment();
58214
58470
  return ret;
58215
58471
  }
@@ -58219,7 +58475,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58219
58475
  marshal.writeUInt(componentHandle);
58220
58476
  marshal.writeArrayOfUInt(nodes);
58221
58477
  marshal.writeFloat(blendTime);
58222
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58478
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58223
58479
  const ret = returnMarshal.readSegment();
58224
58480
  return ret;
58225
58481
  }
@@ -58228,14 +58484,14 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58228
58484
  marshal.writeString("RPCFrameVim");
58229
58485
  marshal.writeUInt(componentHandle);
58230
58486
  marshal.writeFloat(blendTime);
58231
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58487
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58232
58488
  const ret = returnMarshal.readSegment();
58233
58489
  return ret;
58234
58490
  }
58235
58491
  async RPCGetAPIVersion() {
58236
58492
  const marshal = new Marshal();
58237
58493
  marshal.writeString("RPCGetAPIVersion");
58238
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58494
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58239
58495
  const ret = returnMarshal.readString();
58240
58496
  return ret;
58241
58497
  }
@@ -58244,36 +58500,58 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58244
58500
  marshal.writeString("RPCGetBoundingBox");
58245
58501
  marshal.writeUInt(componentHandle);
58246
58502
  marshal.writeArrayOfUInt(nodes);
58247
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58503
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58504
+ const ret = returnMarshal.readBox3();
58505
+ return ret;
58506
+ }
58507
+ async RPCGetBoundingBoxAll(componentHandle) {
58508
+ const marshal = new Marshal();
58509
+ marshal.writeString("RPCGetBoundingBoxAll");
58510
+ marshal.writeUInt(componentHandle);
58511
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58248
58512
  const ret = returnMarshal.readBox3();
58249
58513
  return ret;
58250
58514
  }
58251
58515
  async RPCGetCameraPosition() {
58252
58516
  const marshal = new Marshal();
58253
58517
  marshal.writeString("RPCGetCameraPosition");
58254
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58518
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58255
58519
  const ret = returnMarshal.readSegment();
58256
58520
  return ret;
58257
58521
  }
58258
58522
  async RPCGetIblRotation() {
58259
58523
  const marshal = new Marshal();
58260
58524
  marshal.writeString("RPCGetIblRotation");
58261
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58525
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58262
58526
  const ret = returnMarshal.readMatrix44();
58263
58527
  return ret;
58264
58528
  }
58265
58529
  async RPCGetLastError() {
58266
58530
  const marshal = new Marshal();
58267
58531
  marshal.writeString("RPCGetLastError");
58268
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58532
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58269
58533
  const ret = returnMarshal.readString();
58270
58534
  return ret;
58271
58535
  }
58536
+ async RPCGetSceneAABB() {
58537
+ const marshal = new Marshal();
58538
+ marshal.writeString("RPCGetSceneAABB");
58539
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58540
+ const ret = returnMarshal.readBox3();
58541
+ return ret;
58542
+ }
58543
+ async RPCGetSectionBox() {
58544
+ const marshal = new Marshal();
58545
+ marshal.writeString("RPCGetSectionBox");
58546
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58547
+ const ret = returnMarshal.readSectionBoxState();
58548
+ return ret;
58549
+ }
58272
58550
  async RPCGetVimLoadingState(componentHandle) {
58273
58551
  const marshal = new Marshal();
58274
58552
  marshal.writeString("RPCGetVimLoadingState");
58275
58553
  marshal.writeUInt(componentHandle);
58276
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58554
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58277
58555
  const ret = returnMarshal.readVimStatus();
58278
58556
  return ret;
58279
58557
  }
@@ -58282,65 +58560,65 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58282
58560
  marshal.writeString("RPCGhost");
58283
58561
  marshal.writeUInt(componentHandle);
58284
58562
  marshal.writeArrayOfUInt(nodes);
58285
- this._messenger.sendRPC(marshal);
58563
+ this._socket.sendRPC(marshal);
58286
58564
  }
58287
58565
  RPCGhostAll(componentHandle) {
58288
58566
  const marshal = new Marshal();
58289
58567
  marshal.writeString("RPCGhostAll");
58290
58568
  marshal.writeUInt(componentHandle);
58291
- this._messenger.sendRPC(marshal);
58569
+ this._socket.sendRPC(marshal);
58292
58570
  }
58293
58571
  RPCHide(componentHandle, nodes) {
58294
58572
  const marshal = new Marshal();
58295
58573
  marshal.writeString("RPCHide");
58296
58574
  marshal.writeUInt(componentHandle);
58297
58575
  marshal.writeArrayOfUInt(nodes);
58298
- this._messenger.sendRPC(marshal);
58576
+ this._socket.sendRPC(marshal);
58299
58577
  }
58300
58578
  RPCHideAABBs(componentHandle, nodes) {
58301
58579
  const marshal = new Marshal();
58302
58580
  marshal.writeString("RPCHideAABBs");
58303
58581
  marshal.writeUInt(componentHandle);
58304
58582
  marshal.writeArrayOfUInt(nodes);
58305
- this._messenger.sendRPC(marshal);
58583
+ this._socket.sendRPC(marshal);
58306
58584
  }
58307
58585
  RPCHideAll(componentHandle) {
58308
58586
  const marshal = new Marshal();
58309
58587
  marshal.writeString("RPCHideAll");
58310
58588
  marshal.writeUInt(componentHandle);
58311
- this._messenger.sendRPC(marshal);
58589
+ this._socket.sendRPC(marshal);
58312
58590
  }
58313
58591
  RPCHideAllAABBs(componentHandle) {
58314
58592
  const marshal = new Marshal();
58315
58593
  marshal.writeString("RPCHideAllAABBs");
58316
58594
  marshal.writeUInt(componentHandle);
58317
- this._messenger.sendRPC(marshal);
58595
+ this._socket.sendRPC(marshal);
58318
58596
  }
58319
58597
  RPCHighlight(componentHandle, nodes) {
58320
58598
  const marshal = new Marshal();
58321
58599
  marshal.writeString("RPCHighlight");
58322
58600
  marshal.writeUInt(componentHandle);
58323
58601
  marshal.writeArrayOfUInt(nodes);
58324
- this._messenger.sendRPC(marshal);
58602
+ this._socket.sendRPC(marshal);
58325
58603
  }
58326
58604
  RPCHighlightAll(componentHandle) {
58327
58605
  const marshal = new Marshal();
58328
58606
  marshal.writeString("RPCHighlightAll");
58329
58607
  marshal.writeUInt(componentHandle);
58330
- this._messenger.sendRPC(marshal);
58608
+ this._socket.sendRPC(marshal);
58331
58609
  }
58332
58610
  RPCKeyEvent(keyCode, down) {
58333
58611
  const marshal = new Marshal();
58334
58612
  marshal.writeString("RPCKeyEvent");
58335
58613
  marshal.writeInt(keyCode);
58336
58614
  marshal.writeBoolean(down);
58337
- this._messenger.sendRPC(marshal);
58615
+ this._socket.sendRPC(marshal);
58338
58616
  }
58339
58617
  async RPCLoadVim(fileName) {
58340
58618
  const marshal = new Marshal();
58341
58619
  marshal.writeString("RPCLoadVim");
58342
58620
  marshal.writeString(fileName);
58343
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58621
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58344
58622
  const ret = returnMarshal.readUInt();
58345
58623
  return ret;
58346
58624
  }
@@ -58349,7 +58627,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58349
58627
  marshal.writeString("RPCLoadVimURL");
58350
58628
  marshal.writeString(url);
58351
58629
  marshal.writeString(authToken);
58352
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58630
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58353
58631
  const ret = returnMarshal.readUInt();
58354
58632
  return ret;
58355
58633
  }
@@ -58357,7 +58635,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58357
58635
  const marshal = new Marshal();
58358
58636
  marshal.writeString("RPCLockIblRotation");
58359
58637
  marshal.writeBoolean(lock);
58360
- this._messenger.sendRPC(marshal);
58638
+ this._socket.sendRPC(marshal);
58361
58639
  }
58362
58640
  RPCMouseButtonEvent(mousePos, mouseButton, down) {
58363
58641
  const marshal = new Marshal();
@@ -58365,33 +58643,33 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58365
58643
  marshal.writeVector2(mousePos);
58366
58644
  marshal.writeInt(mouseButton);
58367
58645
  marshal.writeBoolean(down);
58368
- this._messenger.sendRPC(marshal);
58646
+ this._socket.sendRPC(marshal);
58369
58647
  }
58370
58648
  RPCMouseDoubleClickEvent(mousePos, mouseButton) {
58371
58649
  const marshal = new Marshal();
58372
58650
  marshal.writeString("RPCMouseDoubleClickEvent");
58373
58651
  marshal.writeVector2(mousePos);
58374
58652
  marshal.writeInt(mouseButton);
58375
- this._messenger.sendRPC(marshal);
58653
+ this._socket.sendRPC(marshal);
58376
58654
  }
58377
58655
  RPCMouseMoveEvent(mousePos) {
58378
58656
  const marshal = new Marshal();
58379
58657
  marshal.writeString("RPCMouseMoveEvent");
58380
58658
  marshal.writeVector2(mousePos);
58381
- this._messenger.sendRPC(marshal);
58659
+ this._socket.sendRPC(marshal);
58382
58660
  }
58383
58661
  RPCMouseScrollEvent(scrollValue) {
58384
58662
  const marshal = new Marshal();
58385
58663
  marshal.writeString("RPCMouseScrollEvent");
58386
58664
  marshal.writeInt(scrollValue);
58387
- this._messenger.sendRPC(marshal);
58665
+ this._socket.sendRPC(marshal);
58388
58666
  }
58389
58667
  RPCMouseSelectEvent(mousePos, mouseButton) {
58390
58668
  const marshal = new Marshal();
58391
58669
  marshal.writeString("RPCMouseSelectEvent");
58392
58670
  marshal.writeVector2(mousePos);
58393
58671
  marshal.writeInt(mouseButton);
58394
- this._messenger.sendRPC(marshal);
58672
+ this._socket.sendRPC(marshal);
58395
58673
  }
58396
58674
  RPCMoveCameraTo(usePosition, useTarget, position, target, blendTime) {
58397
58675
  const marshal = new Marshal();
@@ -58401,19 +58679,19 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58401
58679
  marshal.writeVector3(position);
58402
58680
  marshal.writeVector3(target);
58403
58681
  marshal.writeFloat(blendTime);
58404
- this._messenger.sendRPC(marshal);
58682
+ this._socket.sendRPC(marshal);
58405
58683
  }
58406
58684
  RPCPauseRendering(pause) {
58407
58685
  const marshal = new Marshal();
58408
58686
  marshal.writeString("RPCPauseRendering");
58409
58687
  marshal.writeBoolean(pause);
58410
- this._messenger.sendRPC(marshal);
58688
+ this._socket.sendRPC(marshal);
58411
58689
  }
58412
58690
  async RPCPerformHitTest(pos) {
58413
58691
  const marshal = new Marshal();
58414
58692
  marshal.writeString("RPCPerformHitTest");
58415
58693
  marshal.writeVector2(pos);
58416
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58694
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58417
58695
  const ret = returnMarshal.readHitCheckResult();
58418
58696
  return ret;
58419
58697
  }
@@ -58423,39 +58701,39 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58423
58701
  marshal.writeUInt(componentHandle);
58424
58702
  marshal.writeArrayOfUInt(nodes);
58425
58703
  marshal.writeUInt(flags);
58426
- this._messenger.sendRPC(marshal);
58704
+ this._socket.sendRPC(marshal);
58427
58705
  }
58428
58706
  RPCSetAspectRatio(width, height) {
58429
58707
  const marshal = new Marshal();
58430
58708
  marshal.writeString("RPCSetAspectRatio");
58431
58709
  marshal.writeUInt(width);
58432
58710
  marshal.writeUInt(height);
58433
- this._messenger.sendRPC(marshal);
58711
+ this._socket.sendRPC(marshal);
58434
58712
  }
58435
58713
  RPCSetCameraMode(orbit2) {
58436
58714
  const marshal = new Marshal();
58437
58715
  marshal.writeString("RPCSetCameraMode");
58438
58716
  marshal.writeBoolean(orbit2);
58439
- this._messenger.sendRPC(marshal);
58717
+ this._socket.sendRPC(marshal);
58440
58718
  }
58441
58719
  RPCSetCameraPosition(state, blendTime) {
58442
58720
  const marshal = new Marshal();
58443
58721
  marshal.writeString("RPCSetCameraPosition");
58444
58722
  marshal.writeSegment(state);
58445
58723
  marshal.writeFloat(blendTime);
58446
- this._messenger.sendRPC(marshal);
58724
+ this._socket.sendRPC(marshal);
58447
58725
  }
58448
58726
  RPCSetGhostColor(ghostColor) {
58449
58727
  const marshal = new Marshal();
58450
58728
  marshal.writeString("RPCSetGhostColor");
58451
58729
  marshal.writeRGBA(ghostColor);
58452
- this._messenger.sendRPC(marshal);
58730
+ this._socket.sendRPC(marshal);
58453
58731
  }
58454
58732
  RPCSetIblRotation(transform) {
58455
58733
  const marshal = new Marshal();
58456
58734
  marshal.writeString("RPCSetIblRotation");
58457
58735
  marshal.writeMatrix44(transform);
58458
- this._messenger.sendRPC(marshal);
58736
+ this._socket.sendRPC(marshal);
58459
58737
  }
58460
58738
  RPCSetLighting(toneMappingWhitePoint, hdrScale, hdrBackgroundScale, hdrBackgroundSaturation, backgroundBlur, backgroundColor) {
58461
58739
  const marshal = new Marshal();
@@ -58466,7 +58744,7 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58466
58744
  marshal.writeFloat(hdrBackgroundSaturation);
58467
58745
  marshal.writeFloat(backgroundBlur);
58468
58746
  marshal.writeRGBA(backgroundColor);
58469
- this._messenger.sendRPC(marshal);
58747
+ this._socket.sendRPC(marshal);
58470
58748
  }
58471
58749
  RPCSetMaterialOverrides(componentHandle, nodes, materialInstanceHandles) {
58472
58750
  const marshal = new Marshal();
@@ -58474,26 +58752,26 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58474
58752
  marshal.writeUInt(componentHandle);
58475
58753
  marshal.writeArrayOfUInt(nodes);
58476
58754
  marshal.writeArrayOfUInt(materialInstanceHandles);
58477
- this._messenger.sendRPC(marshal);
58755
+ this._socket.sendRPC(marshal);
58478
58756
  }
58479
58757
  RPCSetMoveSpeed(speed) {
58480
58758
  const marshal = new Marshal();
58481
58759
  marshal.writeString("RPCSetMoveSpeed");
58482
58760
  marshal.writeFloat(speed);
58483
- this._messenger.sendRPC(marshal);
58761
+ this._socket.sendRPC(marshal);
58484
58762
  }
58485
- RPCSetSectionBox(aabb) {
58763
+ RPCSetSectionBox(state) {
58486
58764
  const marshal = new Marshal();
58487
58765
  marshal.writeString("RPCSetSectionBox");
58488
- marshal.writeBox3(aabb);
58489
- this._messenger.sendRPC(marshal);
58766
+ marshal.writeSectionBoxState(state);
58767
+ this._socket.sendRPC(marshal);
58490
58768
  }
58491
58769
  RPCShow(componentHandle, nodes) {
58492
58770
  const marshal = new Marshal();
58493
58771
  marshal.writeString("RPCShow");
58494
58772
  marshal.writeUInt(componentHandle);
58495
58773
  marshal.writeArrayOfUInt(nodes);
58496
- this._messenger.sendRPC(marshal);
58774
+ this._socket.sendRPC(marshal);
58497
58775
  }
58498
58776
  RPCShowAABBs(componentHandle, nodes, colors) {
58499
58777
  const marshal = new Marshal();
@@ -58501,13 +58779,13 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58501
58779
  marshal.writeUInt(componentHandle);
58502
58780
  marshal.writeArrayOfUInt(nodes);
58503
58781
  marshal.writeArrayOfRGBA32(colors);
58504
- this._messenger.sendRPC(marshal);
58782
+ this._socket.sendRPC(marshal);
58505
58783
  }
58506
58784
  RPCShowAll(componentHandle) {
58507
58785
  const marshal = new Marshal();
58508
58786
  marshal.writeString("RPCShowAll");
58509
58787
  marshal.writeUInt(componentHandle);
58510
- this._messenger.sendRPC(marshal);
58788
+ this._socket.sendRPC(marshal);
58511
58789
  }
58512
58790
  async RPCStartScene(toneMappingWhitePoint, hdrScale, hdrBackgroundScale, hdrBackgroundSaturation, backgroundBlur, backgroundColor) {
58513
58791
  const marshal = new Marshal();
@@ -58518,20 +58796,20 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
58518
58796
  marshal.writeFloat(hdrBackgroundSaturation);
58519
58797
  marshal.writeFloat(backgroundBlur);
58520
58798
  marshal.writeRGBA(backgroundColor);
58521
- const returnMarshal = await this._messenger.sendRPCWithReturn(marshal);
58799
+ const returnMarshal = await this._socket.sendRPCWithReturn(marshal);
58522
58800
  const ret = returnMarshal.readBoolean();
58523
58801
  return ret;
58524
58802
  }
58525
58803
  RPCTriggerRenderDocCapture() {
58526
58804
  const marshal = new Marshal();
58527
58805
  marshal.writeString("RPCTriggerRenderDocCapture");
58528
- this._messenger.sendRPC(marshal);
58806
+ this._socket.sendRPC(marshal);
58529
58807
  }
58530
58808
  RPCUnloadVim(componentHandle) {
58531
58809
  const marshal = new Marshal();
58532
58810
  marshal.writeString("RPCUnloadVim");
58533
58811
  marshal.writeUInt(componentHandle);
58534
- this._messenger.sendRPC(marshal);
58812
+ this._socket.sendRPC(marshal);
58535
58813
  }
58536
58814
  }
58537
58815
  class Validation {
@@ -59010,6 +59288,19 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
59010
59288
  if (!Validation.isComponentHandle(componentHandle)) return;
59011
59289
  this.rpc.RPCDestroyText(componentHandle);
59012
59290
  }
59291
+ /*******************************************************************************
59292
+ * SECTION BOX METHODS
59293
+ * Methods for controlling section box visibility and position.
59294
+ ******************************************************************************/
59295
+ RPCSetSectionBox(state) {
59296
+ this.rpc.RPCSetSectionBox(state);
59297
+ }
59298
+ async RPCGetSectionBox() {
59299
+ return await this.safeCall(
59300
+ () => this.rpc.RPCGetSectionBox(),
59301
+ void 0
59302
+ );
59303
+ }
59013
59304
  /*******************************************************************************
59014
59305
  * CAMERA AND VIEW METHODS
59015
59306
  * Methods for controlling camera position, movement, framing, and view settings.
@@ -59035,6 +59326,12 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
59035
59326
  blendTime = Validation.clamp01(blendTime);
59036
59327
  this.rpc.RPCSetCameraPosition(segment, blendTime);
59037
59328
  }
59329
+ async RPCGetBoundingBoxAll(componentHandle) {
59330
+ return await this.safeCall(
59331
+ () => this.rpc.RPCGetBoundingBoxAll(componentHandle),
59332
+ void 0
59333
+ );
59334
+ }
59038
59335
  /**
59039
59336
  * Calculates the bounding box for specified nodes in a component.
59040
59337
  * Large node arrays are automatically processed in batches for better performance.
@@ -59628,9 +59925,6 @@ data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAYAAACAvzbMAAAAAXNSR0IArs
59628
59925
  * Starts logging the stream metrics.
59629
59926
  */
59630
59927
  startLoggging() {
59631
- this._id = setInterval(() => {
59632
- this.logMetrics();
59633
- }, 5e3);
59634
59928
  }
59635
59929
  /**
59636
59930
  * Stops logging the stream metrics.
@@ -59720,6 +60014,7 @@ Averrage Date/Second ${avgDataRatePS} kb
59720
60014
  ControllablePromise,
59721
60015
  ResolvedPromise
59722
60016
  }, Symbol.toStringTag, { value: "Module" }));
60017
+ const DEFAULT_LOCAL_ULTRA_SERVER_URL = "ws://localhost:8123";
59723
60018
  class SocketClient {
59724
60019
  /**
59725
60020
  * Constructs a new Messenger instance.
@@ -59741,10 +60036,12 @@ Averrage Date/Second ${avgDataRatePS} kb
59741
60036
  */
59742
60037
  __publicField(this, "onVideoFrame", () => {
59743
60038
  });
60039
+ __publicField(this, "onCameraPose", () => {
60040
+ });
59744
60041
  __publicField(this, "_state", { status: "disconnected" });
59745
60042
  __publicField(this, "_onStatusUpdate", new distExports.SimpleEventDispatcher());
59746
60043
  __publicField(this, "_connectPromise", new ResolvedPromise(void 0));
59747
- __publicField(this, "_connectingUrl");
60044
+ __publicField(this, "_connectionSettings");
59748
60045
  this._logger = logger;
59749
60046
  this._rpcCallId = 0;
59750
60047
  this._streamLogger = new StreamLogger(logger);
@@ -59777,34 +60074,43 @@ Averrage Date/Second ${avgDataRatePS} kb
59777
60074
  * @returns The WebSocket URL as a string, or undefined if not set.
59778
60075
  */
59779
60076
  get url() {
59780
- return this._connectingUrl;
60077
+ var _a2;
60078
+ return (_a2 = this._connectionSettings) == null ? void 0 : _a2.url;
59781
60079
  }
59782
60080
  /**
59783
60081
  * Connects to a WebSocket server at the specified URL.
59784
60082
  * @param url - The WebSocket URL to connect to.
59785
60083
  * @returns A promise that resolves when the connection is established.
59786
60084
  */
59787
- connect(url) {
60085
+ connect(settings2) {
60086
+ settings2 = {
60087
+ url: (settings2 == null ? void 0 : settings2.url) ?? DEFAULT_LOCAL_ULTRA_SERVER_URL,
60088
+ retries: (settings2 == null ? void 0 : settings2.retries) ?? -1,
60089
+ timeout: (settings2 == null ? void 0 : settings2.timeout) ?? 5e3,
60090
+ retryDelay: (settings2 == null ? void 0 : settings2.retryDelay) ?? 5e3
60091
+ };
60092
+ const url = settings2.url;
59788
60093
  if (!isWebSocketUrl(url)) {
59789
60094
  this._disconnect({ status: "error", error: "connection", serverUrl: url });
59790
60095
  return Promise.reject(new Error(`Invalid WebSocket URL: ${url}`));
59791
60096
  }
59792
60097
  if (this._socket) {
59793
- if (this._socket.url === url) {
60098
+ if (this._connectionSettings.url === url) {
59794
60099
  return this._connectPromise.promise;
59795
60100
  } else {
59796
60101
  this._clearSocket();
60102
+ this._connectionSettings = void 0;
59797
60103
  this._connectPromise.reject("Connection to a different server");
59798
- this._connectPromise = new ControllablePromise();
59799
60104
  }
59800
- } else if (this._connectingUrl !== url) {
60105
+ }
60106
+ if (this.url !== url) {
59801
60107
  this._connectPromise = new ControllablePromise();
59802
- this._connectingUrl = url;
60108
+ this._connectionSettings = settings2;
59803
60109
  }
59804
60110
  this.updateState({ status: "connecting" });
59805
60111
  try {
59806
60112
  this._socket = new WebSocket(url);
59807
- this._connectionTimeout = setTimeout(() => this._onClose(), 5e3);
60113
+ this._connectionTimeout = setTimeout(() => this._onClose(), settings2.timeout);
59808
60114
  this._socket.onopen = (e) => {
59809
60115
  this._onOpen(e);
59810
60116
  };
@@ -59827,15 +60133,15 @@ Averrage Date/Second ${avgDataRatePS} kb
59827
60133
  * Disconnects from the current WebSocket server.
59828
60134
  */
59829
60135
  disconnect(error) {
59830
- this._logger.log("Disconnecting from: ", this._connectingUrl);
59831
- this._connectingUrl = void 0;
60136
+ this._logger.log("Disconnecting from: ", this.url);
60137
+ this._connectionSettings = void 0;
59832
60138
  this._disconnect(error);
59833
60139
  }
59834
60140
  /**
59835
60141
  * Handles the disconnection logic, stopping logging and clearing the socket.
59836
60142
  */
59837
60143
  _disconnect(error) {
59838
- console.log("disconnect", error);
60144
+ this._logger.log("disconnect", error);
59839
60145
  clearTimeout(this._reconnectTimeout);
59840
60146
  clearTimeout(this._connectionTimeout);
59841
60147
  this._streamLogger.stopLogging();
@@ -59876,6 +60182,10 @@ Averrage Date/Second ${avgDataRatePS} kb
59876
60182
  this.handleRPCResponse(msg.dataBuffer);
59877
60183
  return;
59878
60184
  case 254:
60185
+ const m = new ReadMarshal(msg.dataBuffer);
60186
+ if (this.onCameraPose) {
60187
+ this.onCameraPose(m.readSegment());
60188
+ }
59879
60189
  return;
59880
60190
  case 0:
59881
60191
  case 1:
@@ -59889,8 +60199,7 @@ Averrage Date/Second ${avgDataRatePS} kb
59889
60199
  * @param buffer - The ArrayBuffer containing the response data.
59890
60200
  */
59891
60201
  handleRPCResponse(buffer) {
59892
- const m = new Marshal();
59893
- m.writeData(buffer);
60202
+ const m = new ReadMarshal(buffer);
59894
60203
  const callId = m.readUInt();
59895
60204
  const pendingRPC = this._pendingRPCs.get(callId);
59896
60205
  if (pendingRPC !== void 0) {
@@ -59916,21 +60225,30 @@ Averrage Date/Second ${avgDataRatePS} kb
59916
60225
  this._logger.log("Connected to: ", (_a2 = this._socket) == null ? void 0 : _a2.url);
59917
60226
  this.updateState({ status: "connected" });
59918
60227
  this._streamLogger.startLoggging();
59919
- this._connectPromise.resolve();
60228
+ this._connectPromise.resolve(true);
59920
60229
  }
59921
60230
  /**
59922
60231
  * Handler for WebSocket 'close' event.
59923
60232
  * @param _event - The event object.
59924
60233
  */
59925
60234
  _onClose(_event) {
59926
- clearTimeout(this._connectionTimeout);
59927
- this._disconnect({ status: "error", error: "connection", serverUrl: this._connectingUrl });
60235
+ const connecting = this.state.status === "connecting" || this.state.status === "validating";
59928
60236
  this._logger.log("WebSocket closed.");
60237
+ clearTimeout(this._connectionTimeout);
60238
+ this._disconnect({ status: "error", error: "connection", serverUrl: this.url });
60239
+ if (connecting && this._connectionSettings.retries === 0) {
60240
+ this._logger.log("No more retries left");
60241
+ this._connectPromise.resolve(false);
60242
+ return;
60243
+ }
59929
60244
  this._logger.log("Attempting to reconnect in 5 seconds");
59930
60245
  this._reconnectTimeout = setTimeout(() => {
59931
60246
  this.updateState({ status: "connecting" });
59932
- this.connect(this._connectingUrl);
59933
- }, 5e3);
60247
+ if (connecting) {
60248
+ this._connectionSettings.retries--;
60249
+ }
60250
+ this.connect(this._connectionSettings);
60251
+ }, this._connectionSettings.retryDelay);
59934
60252
  }
59935
60253
  /**
59936
60254
  * Sends binary data over the WebSocket connection.
@@ -60303,31 +60621,6 @@ Averrage Date/Second ${avgDataRatePS} kb
60303
60621
  this._pendingFrame = frame;
60304
60622
  }
60305
60623
  }
60306
- let DeferredPromise$1 = class DeferredPromise extends Promise {
60307
- constructor(executor = () => {
60308
- }) {
60309
- var _a2;
60310
- let resolver;
60311
- let rejector;
60312
- super((resolve, reject) => {
60313
- resolver = resolve;
60314
- rejector = reject;
60315
- return executor(resolve, reject);
60316
- });
60317
- __publicField(this, "resolve");
60318
- __publicField(this, "reject");
60319
- __publicField(this, "initialCallStack");
60320
- this.resolve = resolver;
60321
- this.reject = rejector;
60322
- this.initialCallStack = (_a2 = Error().stack) == null ? void 0 : _a2.split("\n").slice(2).join("\n");
60323
- }
60324
- /** @throws error with amended call stack */
60325
- rejectWithError(error) {
60326
- var _a2;
60327
- error.stack = [(_a2 = error.stack) == null ? void 0 : _a2.split("\n")[0], this.initialCallStack].join("\n");
60328
- this.reject(error);
60329
- }
60330
- };
60331
60624
  class LoadSuccess {
60332
60625
  constructor(vim) {
60333
60626
  __publicField(this, "isError", false);
@@ -60350,8 +60643,8 @@ Averrage Date/Second ${avgDataRatePS} kb
60350
60643
  let LoadRequest$1 = class LoadRequest {
60351
60644
  constructor() {
60352
60645
  __publicField(this, "_progress", 0);
60353
- __publicField(this, "_progressPromise", new DeferredPromise$1());
60354
- __publicField(this, "_completionPromise", new DeferredPromise$1());
60646
+ __publicField(this, "_progressPromise", new ControllablePromise());
60647
+ __publicField(this, "_completionPromise", new ControllablePromise());
60355
60648
  __publicField(this, "_result");
60356
60649
  }
60357
60650
  get isCompleted() {
@@ -60364,18 +60657,18 @@ Averrage Date/Second ${avgDataRatePS} kb
60364
60657
  return;
60365
60658
  }
60366
60659
  while (this._result === void 0) {
60367
- await this._progressPromise;
60660
+ await this._progressPromise.promise;
60368
60661
  yield this._progress;
60369
60662
  }
60370
60663
  }
60371
60664
  async getResult() {
60372
- await this._completionPromise;
60665
+ await this._completionPromise.promise;
60373
60666
  return this._result;
60374
60667
  }
60375
60668
  onProgress(progress) {
60376
60669
  this._progress = progress;
60377
60670
  this._progressPromise.resolve();
60378
- this._progressPromise = new DeferredPromise$1();
60671
+ this._progressPromise = new ControllablePromise();
60379
60672
  }
60380
60673
  success(vim) {
60381
60674
  this._result = new LoadSuccess(vim);
@@ -60609,12 +60902,12 @@ Averrage Date/Second ${avgDataRatePS} kb
60609
60902
  * @throws Error if 'all' is passed, as this feature is not supported yet.
60610
60903
  */
60611
60904
  async getBoundingBox(nodes) {
60612
- if (nodes === "all") {
60613
- throw new Error("Feature not supported yet.");
60614
- }
60615
60905
  if (!this.connected || nodes.length === 0) {
60616
60906
  return Promise.resolve(void 0);
60617
60907
  }
60908
+ if (nodes === "all") {
60909
+ return await this._rpc.RPCGetBoundingBoxAll(this._handle);
60910
+ }
60618
60911
  return await this._rpc.RPCGetBoundingBox(this._handle, nodes);
60619
60912
  }
60620
60913
  /**
@@ -61076,7 +61369,7 @@ Averrage Date/Second ${avgDataRatePS} kb
61076
61369
  }
61077
61370
  /**
61078
61371
  * Restores the camera to its last tracked position
61079
- * @param blendTime - Duration of the camera animation in seconds
61372
+ * @param blendTime - Duration of the camera animation in seconds
61080
61373
  */
61081
61374
  restoreLastPosition(blendTime = this._defaultBlendTime) {
61082
61375
  var _a2;
@@ -61089,29 +61382,10 @@ Averrage Date/Second ${avgDataRatePS} kb
61089
61382
  * Handles camera initialization when connection is established
61090
61383
  */
61091
61384
  onConnect() {
61092
- this.startTracking();
61093
61385
  this.restoreLastPosition();
61094
61386
  }
61095
- /**
61096
- * Starts tracking camera position at regular intervals
61097
- */
61098
- startTracking() {
61099
- clearInterval(this._interval);
61100
- this._interval = setInterval(() => this.update(), 1e3);
61101
- }
61102
- /**
61103
- * Stops tracking camera position
61104
- */
61105
- stopTracking() {
61106
- clearInterval(this._interval);
61107
- this._interval = void 0;
61108
- }
61109
- /**
61110
- * Updates the stored camera position
61111
- * @private
61112
- */
61113
- async update() {
61114
- this._lastPosition = await this._rpc.RPCGetCameraPosition();
61387
+ onCameraPose(pose) {
61388
+ this._lastPosition = pose;
61115
61389
  }
61116
61390
  /**
61117
61391
  * Pauses or resumes rendering
@@ -61583,7 +61857,103 @@ Averrage Date/Second ${avgDataRatePS} kb
61583
61857
  }
61584
61858
  }
61585
61859
  }
61586
- const DEFAULT_LOCAL_ULTRA_SERVER_URL = "ws://localhost:8123";
61860
+ class SectionBox {
61861
+ constructor(rpc) {
61862
+ __publicField(this, "_enabled", false);
61863
+ __publicField(this, "_visible", true);
61864
+ __publicField(this, "_interactible", true);
61865
+ __publicField(this, "_clip", true);
61866
+ __publicField(this, "_box", new Box3());
61867
+ __publicField(this, "_rpc");
61868
+ __publicField(this, "_interval");
61869
+ __publicField(this, "_animationFrame");
61870
+ // Signals
61871
+ __publicField(this, "_onUpdate", new distExports$1.SignalDispatcher());
61872
+ this._rpc = rpc;
61873
+ }
61874
+ get onUpdate() {
61875
+ return this._onUpdate.asEvent();
61876
+ }
61877
+ get needUpdate() {
61878
+ return this._animationFrame > 0;
61879
+ }
61880
+ async onConnect() {
61881
+ this.push();
61882
+ this._interval = setInterval(() => this.pull(), 1e3);
61883
+ }
61884
+ scheduleUpdate() {
61885
+ if (this._animationFrame) return;
61886
+ this._animationFrame = requestAnimationFrame(() => {
61887
+ this._animationFrame = void 0;
61888
+ this.push();
61889
+ });
61890
+ }
61891
+ async pull() {
61892
+ if (this.needUpdate) return;
61893
+ const state = await this._rpc.RPCGetSectionBox();
61894
+ let changed = false;
61895
+ if (state.enabled !== this._enabled || state.visible !== this._visible || state.interactible !== this._interactible || state.clip !== this._clip || state.box !== this._box) {
61896
+ changed = true;
61897
+ }
61898
+ this._enabled = state.enabled;
61899
+ this._visible = state.visible;
61900
+ this._interactible = state.interactible;
61901
+ this._clip = state.clip;
61902
+ this._box = state.box;
61903
+ if (changed) {
61904
+ this._onUpdate.dispatch();
61905
+ }
61906
+ }
61907
+ async push() {
61908
+ await this._rpc.RPCSetSectionBox({
61909
+ enabled: this._enabled,
61910
+ visible: this._visible,
61911
+ interactible: this._interactible,
61912
+ clip: this._clip,
61913
+ box: this._box
61914
+ });
61915
+ }
61916
+ get enabled() {
61917
+ return this._enabled;
61918
+ }
61919
+ set enabled(value) {
61920
+ this._enabled = value;
61921
+ this.scheduleUpdate();
61922
+ }
61923
+ get visible() {
61924
+ return this._visible;
61925
+ }
61926
+ set visible(value) {
61927
+ this._visible = value;
61928
+ this.scheduleUpdate();
61929
+ }
61930
+ get interactible() {
61931
+ return this._interactible;
61932
+ }
61933
+ set interactible(value) {
61934
+ this._interactible = value;
61935
+ this.scheduleUpdate();
61936
+ }
61937
+ get clip() {
61938
+ return this._clip;
61939
+ }
61940
+ set clip(value) {
61941
+ this._clip = value;
61942
+ this.scheduleUpdate();
61943
+ }
61944
+ fitBox(box) {
61945
+ this._box = box;
61946
+ this.scheduleUpdate();
61947
+ }
61948
+ getBox() {
61949
+ return this._box;
61950
+ }
61951
+ dispose() {
61952
+ clearInterval(this._interval);
61953
+ cancelAnimationFrame(this._animationFrame);
61954
+ this._onUpdate.clear();
61955
+ }
61956
+ }
61587
61957
  const INVALID_HANDLE = 4294967295;
61588
61958
  class Viewer {
61589
61959
  /**
@@ -61611,6 +61981,10 @@ Averrage Date/Second ${avgDataRatePS} kb
61611
61981
  * API to create, manage, and destroy colors.
61612
61982
  */
61613
61983
  __publicField(this, "colors");
61984
+ /**
61985
+ * The section box API for controlling the section box.
61986
+ */
61987
+ __publicField(this, "sectionBox");
61614
61988
  this._logger = logger ?? defaultLogger;
61615
61989
  this._socketClient = new SocketClient(this._logger, () => this.validateConnection());
61616
61990
  this.rpc = new RpcSafeClient(new RpcClient(this._socketClient));
@@ -61623,7 +61997,9 @@ Averrage Date/Second ${avgDataRatePS} kb
61623
61997
  this.colors = new ColorManager(this.rpc);
61624
61998
  this._camera = new Camera(this.rpc);
61625
61999
  this._input = new Inputs(canvas, this.rpc, this._selection, this._camera, this._renderer);
62000
+ this.sectionBox = new SectionBox(this.rpc);
61626
62001
  this._socketClient.onVideoFrame = (msg) => this._decoder.enqueue(msg);
62002
+ this._socketClient.onCameraPose = (pose) => this._camera.onCameraPose(pose);
61627
62003
  this._socketClient.onStatusUpdate.subscribe((state) => {
61628
62004
  if (state.status === "disconnected") {
61629
62005
  this.onDisconnect();
@@ -61708,6 +62084,7 @@ Averrage Date/Second ${avgDataRatePS} kb
61708
62084
  this._input.onConnect();
61709
62085
  this._camera.onConnect();
61710
62086
  this._vims.getAll().forEach((vim) => vim.connect());
62087
+ this.sectionBox.onConnect();
61711
62088
  this._viewport.update();
61712
62089
  this._decoder.start();
61713
62090
  }
@@ -61745,7 +62122,6 @@ Averrage Date/Second ${avgDataRatePS} kb
61745
62122
  * Cleans up resources and stops tracking.
61746
62123
  */
61747
62124
  onDisconnect() {
61748
- this._camera.stopTracking();
61749
62125
  this._decoder.stop();
61750
62126
  this._decoder.clear();
61751
62127
  this.colors.clear();
@@ -61756,8 +62132,8 @@ Averrage Date/Second ${avgDataRatePS} kb
61756
62132
  * @param url - The server URL to connect to. Defaults to 'ws://localhost:8123'.
61757
62133
  * @returns A promise that resolves when the connection is established.
61758
62134
  */
61759
- async connect(url = DEFAULT_LOCAL_ULTRA_SERVER_URL) {
61760
- await this._socketClient.connect(url);
62135
+ async connect(settings2) {
62136
+ return this._socketClient.connect(settings2);
61761
62137
  }
61762
62138
  /**
61763
62139
  * Disconnects from the current VIM Ultra server.
@@ -61812,6 +62188,7 @@ Averrage Date/Second ${avgDataRatePS} kb
61812
62188
  this._viewport.dispose();
61813
62189
  this._decoder.dispose();
61814
62190
  this._input.dispose();
62191
+ this.sectionBox.dispose();
61815
62192
  this._canvas.remove();
61816
62193
  window.onbeforeunload = null;
61817
62194
  }
@@ -61820,7 +62197,6 @@ Averrage Date/Second ${avgDataRatePS} kb
61820
62197
  __proto__: null,
61821
62198
  Box3,
61822
62199
  ColorHandle,
61823
- DEFAULT_LOCAL_ULTRA_SERVER_URL,
61824
62200
  INVALID_HANDLE,
61825
62201
  Matrix44: Matrix4,
61826
62202
  RGB,
@@ -67016,12 +67392,13 @@ Averrage Date/Second ${avgDataRatePS} kb
67016
67392
  return isTrue(settings2.ui.projectInspector) || isTrue(settings2.ui.settings) || isTrue(settings2.ui.help) || isTrue(settings2.ui.maximise);
67017
67393
  }
67018
67394
  const defaultSettings = {
67019
- peformance: {
67020
- useFastMaterial: false
67395
+ materials: {
67396
+ useFastMaterial: false,
67397
+ useGhostMaterial: true,
67398
+ smallGhostThreshold: 10
67021
67399
  },
67022
67400
  isolation: {
67023
- enable: true,
67024
- useIsolationMaterial: true
67401
+ enable: true
67025
67402
  },
67026
67403
  capacity: {
67027
67404
  canFollowUrl: true,
@@ -67101,7 +67478,7 @@ Averrage Date/Second ${avgDataRatePS} kb
67101
67478
  }, []);
67102
67479
  const onIsolationBtn = () => {
67103
67480
  props.settings.update(
67104
- (s) => s.isolation.useIsolationMaterial = !s.isolation.useIsolationMaterial
67481
+ (s) => s.materials.useGhostMaterial = !s.materials.useGhostMaterial
67105
67482
  );
67106
67483
  };
67107
67484
  const onHomeBtn = () => {
@@ -67111,11 +67488,11 @@ Averrage Date/Second ${avgDataRatePS} kb
67111
67488
  const btnIsolation = /* @__PURE__ */ jsxRuntimeExports.jsx(
67112
67489
  "button",
67113
67490
  {
67114
- "data-tip": props.settings.value.isolation.useIsolationMaterial ? "Disable Ghosting" : "Enable Ghosting",
67491
+ "data-tip": props.settings.value.materials.useGhostMaterial ? "Disable Ghosting" : "Enable Ghosting",
67115
67492
  onClick: onIsolationBtn,
67116
67493
  className: "vim-isolation-btn " + btnStyle2,
67117
67494
  type: "button",
67118
- children: props.settings.value.isolation.useIsolationMaterial ? /* @__PURE__ */ jsxRuntimeExports.jsx(ghost, { height: 20, width: 20, fill: "currentColor" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ghostDead, { height: 20, width: 20, fill: "currentColor" })
67495
+ children: props.settings.value.materials.useGhostMaterial ? /* @__PURE__ */ jsxRuntimeExports.jsx(ghost, { height: 20, width: 20, fill: "currentColor" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ghostDead, { height: 20, width: 20, fill: "currentColor" })
67119
67496
  }
67120
67497
  );
67121
67498
  const btnHome = /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -67645,7 +68022,7 @@ Averrage Date/Second ${avgDataRatePS} kb
67645
68022
  id: elementIds.buttonToggleIsolation,
67646
68023
  enabled: () => isTrue(props.settings.ui.toggleIsolation),
67647
68024
  tip: "Toggle Isolation",
67648
- action: () => props.isolation.toggleIsolation("controlBar"),
68025
+ action: () => props.isolation.toggle("controlBar"),
67649
68026
  icon: toggleIsolation,
67650
68027
  style: buttonDefaultStyle
67651
68028
  }
@@ -71666,7 +72043,7 @@ Averrage Date/Second ${avgDataRatePS} kb
71666
72043
  };
71667
72044
  const [clipping, setClipping] = React2.useState(isClipping());
71668
72045
  const [, setVersion] = React2.useState(0);
71669
- const hidden2 = props.isolation.any();
72046
+ const hidden2 = props.isolation.isActive();
71670
72047
  React2.useEffect(() => {
71671
72048
  const subState = viewer.gizmos.section.onStateChanged.subscribe(() => {
71672
72049
  setSection({
@@ -74049,31 +74426,17 @@ Averrage Date/Second ${avgDataRatePS} kb
74049
74426
  ),
74050
74427
  settingsSubtitle("Materials"),
74051
74428
  settingsToggle(
74052
- "Use Isolation Material",
74053
- (settings2) => settings2.isolation.useIsolationMaterial,
74429
+ "Use Ghost Material",
74430
+ (settings2) => settings2.materials.useGhostMaterial,
74054
74431
  (settings2, value) => {
74055
- settings2.isolation.useIsolationMaterial = value;
74056
- if (settings2.peformance.useFastMaterial && value) {
74057
- settings2.peformance.useFastMaterial = false;
74058
- }
74432
+ settings2.materials.useGhostMaterial = value;
74059
74433
  }
74060
74434
  ),
74061
74435
  settingsToggle(
74062
74436
  "Use Performance Material",
74063
- (settings2) => settings2.peformance.useFastMaterial,
74437
+ (settings2) => settings2.materials.useFastMaterial,
74064
74438
  (settings2, value) => {
74065
- settings2.peformance.useFastMaterial = value;
74066
- if (settings2.isolation.useIsolationMaterial && value) {
74067
- settings2.isolation.useIsolationMaterial = false;
74068
- }
74069
- }
74070
- ),
74071
- settingsSubtitle("Scene"),
74072
- settingsToggle(
74073
- "Show Ground Plane",
74074
- (_) => props.viewer.environment.groundPlane.visible,
74075
- (_, value) => {
74076
- props.viewer.environment.groundPlane.visible = value;
74439
+ settings2.materials.useFastMaterial = value;
74077
74440
  }
74078
74441
  ),
74079
74442
  settingsSubtitle("Panels"),
@@ -74347,7 +74710,6 @@ Averrage Date/Second ${avgDataRatePS} kb
74347
74710
  __publicField(this, "_default");
74348
74711
  __publicField(this, "_isolation");
74349
74712
  __publicField(this, "_sideState");
74350
- __publicField(this, "_help");
74351
74713
  __publicField(this, "_getSelection", () => {
74352
74714
  return [...this._viewer.selection.objects].filter(
74353
74715
  (o) => o.type === "Object3D"
@@ -74377,7 +74739,7 @@ Averrage Date/Second ${avgDataRatePS} kb
74377
74739
  return true;
74378
74740
  }
74379
74741
  case KEYS.KEY_I: {
74380
- this._isolation.toggleIsolation("keyboard");
74742
+ this._isolation.toggle("keyboard");
74381
74743
  return true;
74382
74744
  }
74383
74745
  case KEYS.KEY_ESCAPE: {
@@ -74385,7 +74747,7 @@ Averrage Date/Second ${avgDataRatePS} kb
74385
74747
  this._viewer.selection.clear();
74386
74748
  return true;
74387
74749
  }
74388
- if (this._isolation.any()) {
74750
+ if (this._isolation.isActive()) {
74389
74751
  this._isolation.clear("keyboard");
74390
74752
  return true;
74391
74753
  }
@@ -74467,7 +74829,6 @@ Averrage Date/Second ${avgDataRatePS} kb
74467
74829
  var _a2;
74468
74830
  const next = { ...settings2 };
74469
74831
  updater(next);
74470
- validateSettings(next);
74471
74832
  saveSettingsToLocal(next);
74472
74833
  setSettings(next);
74473
74834
  (_a2 = onUpdate.current) == null ? void 0 : _a2.call(onUpdate, next);
@@ -74487,11 +74848,6 @@ Averrage Date/Second ${avgDataRatePS} kb
74487
74848
  [settings2]
74488
74849
  );
74489
74850
  }
74490
- function validateSettings(settings2) {
74491
- if (settings2.peformance.useFastMaterial && settings2.isolation.useIsolationMaterial) {
74492
- settings2.peformance.useFastMaterial = false;
74493
- }
74494
- }
74495
74851
  function applySettings(viewer, settings2) {
74496
74852
  const performance2 = document.getElementsByClassName("vim-performance-div")[0];
74497
74853
  if (performance2) {
@@ -74501,240 +74857,192 @@ Averrage Date/Second ${avgDataRatePS} kb
74501
74857
  performance2.classList.add("vc-hidden");
74502
74858
  }
74503
74859
  }
74504
- viewer.vims.forEach((v) => {
74505
- if (settings2.peformance.useFastMaterial && v.scene.material === void 0) {
74506
- v.scene.material = viewer.materials.simple;
74507
- }
74508
- if (!settings2.peformance.useFastMaterial && v.scene.material === viewer.materials.simple) {
74509
- v.scene.material = void 0;
74510
- }
74511
- });
74860
+ viewer.renderer.smallGhostThreshold = settings2.materials.smallGhostThreshold;
74512
74861
  }
74513
74862
  class Isolation {
74863
+ /**
74864
+ * Constructs an IsolationManager.
74865
+ *
74866
+ * @param viewer - The VIM Viewer responsible for managing the 3D scene and objects.
74867
+ * @param camera - A component that handles camera control and framing.
74868
+ * @param settings - The settings that control isolation and material usage.
74869
+ */
74514
74870
  constructor(viewer, camera2, settings2) {
74515
74871
  __publicField(this, "_viewer");
74516
74872
  __publicField(this, "_settings");
74517
- __publicField(this, "_isolation");
74518
- __publicField(this, "_lastIsolation");
74873
+ __publicField(this, "_isolation", []);
74519
74874
  __publicField(this, "_camera");
74520
- __publicField(this, "_references", /* @__PURE__ */ new Map());
74521
74875
  __publicField(this, "_onChanged", new distExports.SimpleEventDispatcher());
74522
74876
  this._viewer = viewer;
74523
74877
  this._camera = camera2;
74524
74878
  this.applySettings(settings2);
74525
74879
  }
74526
- /** Signal dispatched when the isolation set changes. */
74880
+ /**
74881
+ * An event that is dispatched whenever the isolation set changes.
74882
+ *
74883
+ * @remarks
74884
+ * This can be used by other parts of the application to react to isolation
74885
+ * updates (for example, updating UI or triggering additional viewport actions).
74886
+ *
74887
+ * @returns {ISimpleEvent<string>} Event interface for subscribing to isolation changes.
74888
+ */
74527
74889
  get onChanged() {
74528
74890
  return this._onChanged.asEvent();
74529
74891
  }
74530
74892
  /**
74531
- * Applies relevant settings to isolation.
74532
- * @param settings The settings to be applied to isolation.
74893
+ * Applies relevant settings to the isolation behavior.
74894
+ *
74895
+ * @param settings - The new settings to apply.
74896
+ *
74897
+ * @remarks
74898
+ * This updates the internal reference to settings and immediately sets
74899
+ * the material based on whether isolation is currently active.
74533
74900
  */
74534
74901
  applySettings(settings2) {
74535
- var _a2;
74536
74902
  this._settings = settings2;
74537
74903
  if (!this._settings.isolation.enable) return;
74538
- const set2 = new Set((_a2 = this._isolation) == null ? void 0 : _a2.map((o) => o.vim));
74539
- this._viewer.vims.forEach((v) => {
74540
- v.scene.material = this.getMaterial(this._settings, set2.has(v));
74541
- });
74542
- }
74543
- /**
74544
- * Sets the reference objects for a given VIM.
74545
- * @param vim The VIM for which reference objects are being set.
74546
- * @param reference An array of reference objects or the string 'always' to indicate permanent reference.
74547
- */
74548
- setReference(vim, reference) {
74549
- const value = reference === "always" ? reference : new Set(reference);
74550
- this._references.set(vim, value);
74551
- }
74552
- /**
74553
- * Retrieves the reference objects set for a given VIM.
74554
- * @param vim The VIM for which reference objects are being retrieved.
74555
- * @returns The reference objects set for the specified VIM.
74556
- */
74557
- getReference(vim) {
74558
- return this._references.get(vim);
74559
- }
74560
- /**
74561
- * Clears all reference objects set for VIMs.
74562
- */
74563
- clearReferences() {
74564
- this._references.clear();
74904
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, this.isActive());
74565
74905
  }
74566
74906
  /**
74567
- * Returns true if there are currently objects isolated.
74568
- * @returns True if there are currently objects isolated; otherwise, false.
74907
+ * Checks if isolation is currently active (i.e., any objects are isolated).
74908
+ *
74909
+ * @returns True if isolation is active; otherwise, false.
74569
74910
  */
74570
- any() {
74571
- return this._isolation !== void 0;
74911
+ isActive() {
74912
+ return this._isolation.length > 0;
74572
74913
  }
74573
74914
  /**
74574
- * Returns the current array of isolated objects.
74575
- * @returns The array of objects currently isolated, or undefined if no objects are isolated.
74915
+ * Retrieves the current array of isolated objects.
74916
+ *
74917
+ * @returns An array of isolated objects, or undefined if isolation is not active.
74576
74918
  */
74577
74919
  current() {
74578
74920
  return this._isolation;
74579
74921
  }
74580
74922
  /**
74581
- * Isolates the objects in the given array and shows the rest as ghost.
74582
- * @param objects An array of objects to isolate.
74583
- * @param source The source of isolation.
74584
- * @returns True if isolation occurs; otherwise, false.
74923
+ * Sets the specified objects as isolated, hiding or ghosting the rest.
74924
+ *
74925
+ * @param objects - The objects to isolate.
74926
+ * @param source - A label or identifier indicating the source of this action (e.g., "user").
74585
74927
  */
74586
74928
  isolate(objects, source) {
74587
74929
  if (!this._settings.isolation.enable) return;
74588
- if (this._isolation) {
74589
- this._lastIsolation = this._isolation;
74590
- }
74591
- const isolated = this._isolate(this._viewer, this._settings, objects);
74592
- this._isolation = isolated ? objects : void 0;
74930
+ this._isolation = objects ?? [];
74931
+ this._apply(source);
74593
74932
  this._camera.frameVisibleObjects();
74594
- this._onChanged.dispatch(source);
74595
- return isolated;
74596
74933
  }
74597
74934
  /**
74598
- * Toggles current isolation based on selection.
74599
- * @param source The source of isolation.
74935
+ * Toggles isolation by using the current selection.
74936
+ *
74937
+ * @param source - A label or identifier for the isolation action.
74938
+ *
74939
+ * @remarks
74940
+ * This method replaces the current isolation set with whatever objects are
74941
+ * currently selected. If selection is empty, it effectively clears isolation.
74600
74942
  */
74601
- toggleIsolation(source) {
74943
+ toggle(source) {
74602
74944
  if (!this._settings.isolation.enable) return;
74603
- const selection = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74604
- if (this._isolation) {
74605
- this._lastIsolation = this._isolation;
74606
- }
74607
- if (this._isolation) {
74608
- if (selection.length === 0 || ArrayEquals(this._isolation, selection)) {
74609
- this._showAll();
74610
- this._isolation = void 0;
74611
- } else {
74612
- const isolated = this._isolate(this._viewer, this._settings, selection);
74613
- this._isolation = isolated ? selection : void 0;
74614
- this._camera.frameVisibleObjects();
74615
- this._viewer.selection.clear();
74616
- }
74617
- } else {
74618
- if (selection.length > 0) {
74619
- const isolated = this._isolate(this._viewer, this._settings, selection);
74620
- this._isolation = isolated ? selection : void 0;
74621
- this._camera.frameVisibleObjects();
74622
- this._viewer.selection.clear();
74623
- } else if (this._lastIsolation) {
74624
- const isolated = this._isolate(
74625
- this._viewer,
74626
- this._settings,
74627
- this._lastIsolation
74628
- );
74629
- this._isolation = isolated ? [...this._lastIsolation] : void 0;
74630
- }
74631
- }
74632
- this._onChanged.dispatch(source);
74945
+ this._isolation = [...this._viewer.selection.objects].filter((o) => o.type === "Object3D");
74946
+ this._apply(source);
74947
+ this._camera.frameVisibleObjects();
74948
+ this._viewer.selection.clear();
74633
74949
  }
74634
74950
  /**
74635
- * Removes the given objects from the isolation set.
74636
- * @param objects An array of objects to be removed from isolation.
74637
- * @param source The source of the removal operation.
74951
+ * Hides the specified objects from the isolation set.
74952
+ *
74953
+ * @param objects - The objects to hide.
74954
+ * @param source - A label or identifier for the isolation action.
74955
+ *
74956
+ * @remarks
74957
+ * If there is no active isolation set (i.e., all objects are visible),
74958
+ * the method first treats all objects in the scene as isolated,
74959
+ * and then removes the specified objects. This ensures the specified
74960
+ * objects become hidden.
74638
74961
  */
74639
74962
  hide(objects, source) {
74640
74963
  if (!this._settings.isolation.enable) return;
74641
- const selection = new Set(objects);
74642
- const initial = this._isolation ?? this._viewer.vims[0].getObjects();
74643
- const result = [];
74644
- for (const obj of initial) {
74645
- if (!selection.has(obj)) result.push(obj);
74646
- }
74647
- const isolated = this._isolate(this._viewer, this._settings, result);
74648
- this._isolation = isolated ? result : void 0;
74649
- this._onChanged.dispatch(source);
74964
+ this._isolation = this._isolation.length === 0 ? this.getAllObjects() : this._isolation;
74965
+ this._isolation = this._isolation.filter((o) => !objects.includes(o));
74966
+ this._apply(source);
74650
74967
  objects.forEach((o) => this._viewer.selection.remove(o));
74651
74968
  }
74652
74969
  /**
74653
- * Adds the given objects to the isolation set.
74654
- * @param objects An array of objects to be added to isolation.
74655
- * @param source The source of the addition operation.
74970
+ * Adds the specified objects to the current isolation set (making them visible).
74971
+ *
74972
+ * @param objects - The objects to show.
74973
+ * @param source - A label or identifier for the isolation action.
74656
74974
  */
74657
74975
  show(objects, source) {
74658
74976
  if (!this._settings.isolation.enable) return;
74659
- const isolation = this._isolation ?? [];
74660
- objects.forEach((o) => isolation.push(o));
74661
- const result = [...new Set(isolation)];
74662
- const isolated = this._isolate(this._viewer, this._settings, result);
74663
- this._isolation = isolated ? result : void 0;
74664
- this._onChanged.dispatch(source);
74977
+ objects.forEach((o) => this._isolation.push(o));
74978
+ this._apply(source);
74665
74979
  }
74666
74980
  /**
74667
- * Clears the current isolation.
74668
- * @param source The source of the isolation clearing operation.
74981
+ * Clears the current isolation set, making all objects visible.
74982
+ *
74983
+ * @param source - A label or identifier for the isolation action.
74669
74984
  */
74670
74985
  clear(source) {
74671
74986
  if (!this._settings.isolation.enable) return;
74672
- this._showAll();
74673
- this._lastIsolation = this._isolation;
74674
- this._isolation = void 0;
74675
- this._onChanged.dispatch(source);
74987
+ this._isolation.length = 0;
74988
+ this._apply(source);
74676
74989
  }
74677
74990
  /**
74678
- * Show all objects and quit isolation mode.
74991
+ * Constructs the correct material (or array of materials) based on the given settings.
74992
+ *
74993
+ * @param settings - The current component settings, including isolation rules.
74994
+ * @param isolate - Whether or not isolation is active.
74995
+ * @returns The material(s) to assign to the renderer, or undefined if default materials should be used.
74996
+ *
74997
+ * @remarks
74998
+ * - If isolation is active and `useGhostMaterial` is true, an array containing
74999
+ * the simple and ghost materials is returned.
75000
+ * - If fast materials are enabled, the simple material is returned.
75001
+ * - Otherwise, defaults to undefined, allowing the system to pick a standard material.
74679
75002
  */
74680
- _showAll() {
74681
- this._viewer.vims.forEach((v) => {
74682
- for (const obj of v.getObjects()) {
74683
- obj.visible = true;
74684
- }
74685
- v.scene.material = this.getMaterial(this._settings, false);
74686
- });
74687
- }
74688
75003
  getMaterial(settings2, isolate) {
74689
- if (settings2.peformance.useFastMaterial) {
74690
- return this._viewer.materials.simple;
74691
- }
74692
- if (!settings2.isolation.useIsolationMaterial) {
74693
- return void 0;
75004
+ if (isolate && settings2.materials.useGhostMaterial) {
75005
+ return [this._viewer.materials.simple, this._viewer.materials.ghost];
74694
75006
  }
74695
- if (!isolate) {
74696
- return void 0;
75007
+ if (settings2.materials.useFastMaterial) {
75008
+ return this._viewer.materials.simple;
74697
75009
  }
74698
- return this._viewer.materials.isolation;
75010
+ return void 0;
74699
75011
  }
74700
- _isolate(viewer, settings2, objects) {
74701
- let useIsolation = false;
74702
- if (!objects) {
74703
- this._showAll();
74704
- } else {
74705
- const set2 = new Set(objects);
74706
- let all = true;
74707
- viewer.vims.forEach((vim) => {
74708
- for (const obj of vim.getObjects()) {
74709
- if (obj.hasMesh) {
74710
- obj.visible = set2.has(obj);
74711
- all = all && obj.visible;
74712
- }
74713
- }
74714
- const reference = this._references.get(vim);
74715
- if (reference === void 0) {
74716
- useIsolation = !all;
74717
- } else if (reference === "always") {
74718
- useIsolation = true;
74719
- } else {
74720
- useIsolation = !setsEqual(reference, set2);
75012
+ /**
75013
+ * Applies the current isolation state: sets visibility for objects, updates materials,
75014
+ * and dispatches the changed event.
75015
+ *
75016
+ * @param source - A label or identifier for the isolation action.
75017
+ */
75018
+ _apply(source) {
75019
+ let all = true;
75020
+ let any = false;
75021
+ const set2 = this._isolation.length > 0 ? new Set(this._isolation) : void 0;
75022
+ this._viewer.vims.forEach((vim) => {
75023
+ for (const obj of vim.getObjects()) {
75024
+ if (obj.hasMesh) {
75025
+ obj.visible = (set2 == null ? void 0 : set2.has(obj)) ?? true;
75026
+ all = all && obj.visible;
75027
+ any = any || obj.visible;
74721
75028
  }
74722
- vim.scene.material = this.getMaterial(this._settings, useIsolation);
74723
- });
74724
- }
74725
- return useIsolation;
74726
- }
74727
- }
74728
- function setsEqual(set1, set2) {
74729
- if (set1.size !== set2.size) {
74730
- return false;
75029
+ }
75030
+ });
75031
+ this._viewer.renderer.modelMaterial = this.getMaterial(this._settings, any && !all);
75032
+ this._onChanged.dispatch(source);
74731
75033
  }
74732
- for (const item of set1) {
74733
- if (!set2.has(item)) {
74734
- return false;
74735
- }
75034
+ /**
75035
+ * Gathers all objects from all loaded VIM instances.
75036
+ *
75037
+ * @returns An array of all objects within the loaded VIM scenes.
75038
+ */
75039
+ getAllObjects() {
75040
+ let objects = [];
75041
+ this._viewer.vims.forEach((vim) => {
75042
+ objects = objects.concat(vim.getObjects());
75043
+ });
75044
+ return objects;
74736
75045
  }
74737
- return true;
74738
75046
  }
74739
75047
  class ComponentCamera {
74740
75048
  constructor(viewer) {