@inweb/viewer-three 26.6.0 → 26.6.2

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 (36) hide show
  1. package/dist/plugins/components/LightHelperComponent.js +9 -3
  2. package/dist/plugins/components/LightHelperComponent.js.map +1 -1
  3. package/dist/plugins/components/LightHelperComponent.min.js +1 -1
  4. package/dist/plugins/components/LightHelperComponent.module.js +5 -4
  5. package/dist/plugins/components/LightHelperComponent.module.js.map +1 -1
  6. package/dist/plugins/components/RoomEnvironmentComponent.js +178 -0
  7. package/dist/plugins/components/RoomEnvironmentComponent.js.map +1 -0
  8. package/dist/plugins/components/RoomEnvironmentComponent.min.js +1 -0
  9. package/dist/plugins/components/RoomEnvironmentComponent.module.js +21 -0
  10. package/dist/plugins/components/RoomEnvironmentComponent.module.js.map +1 -0
  11. package/dist/plugins/loaders/IFCXLoader.js +21 -27
  12. package/dist/plugins/loaders/IFCXLoader.js.map +1 -1
  13. package/dist/plugins/loaders/IFCXLoader.min.js +1 -1
  14. package/dist/plugins/loaders/IFCXLoader.module.js +7 -18
  15. package/dist/plugins/loaders/IFCXLoader.module.js.map +1 -1
  16. package/dist/viewer-three.js +1162 -231
  17. package/dist/viewer-three.js.map +1 -1
  18. package/dist/viewer-three.min.js +2 -2
  19. package/dist/viewer-three.module.js +180 -39
  20. package/dist/viewer-three.module.js.map +1 -1
  21. package/lib/Viewer/Viewer.d.ts +1 -1
  22. package/lib/Viewer/components/HighlighterComponent.d.ts +18 -0
  23. package/lib/Viewer/components/HighlighterUtils.d.ts +6 -0
  24. package/lib/Viewer/components/LightComponent.d.ts +3 -1
  25. package/lib/Viewer/components/SelectionComponent.d.ts +5 -4
  26. package/package.json +5 -5
  27. package/plugins/components/LightHelperComponent.ts +10 -5
  28. package/{src/Viewer → plugins}/components/RoomEnvironmentComponent.ts +4 -4
  29. package/plugins/loaders/IFCX/render.js +26 -21
  30. package/src/Viewer/Viewer.ts +4 -4
  31. package/src/Viewer/components/HighlighterComponent.ts +159 -0
  32. package/src/Viewer/components/HighlighterUtils.ts +116 -0
  33. package/src/Viewer/components/LightComponent.ts +33 -4
  34. package/src/Viewer/components/SelectionComponent.ts +10 -22
  35. package/src/Viewer/components/index.ts +2 -2
  36. package/lib/Viewer/components/RoomEnvironmentComponent.d.ts +0 -7
@@ -18058,8 +18058,8 @@
18058
18058
 
18059
18059
  }
18060
18060
 
18061
- const _start = /*@__PURE__*/ new Vector3();
18062
- const _end = /*@__PURE__*/ new Vector3();
18061
+ const _start$1 = /*@__PURE__*/ new Vector3();
18062
+ const _end$1 = /*@__PURE__*/ new Vector3();
18063
18063
 
18064
18064
  class LineSegments extends Line$1 {
18065
18065
 
@@ -18086,11 +18086,11 @@
18086
18086
 
18087
18087
  for ( let i = 0, l = positionAttribute.count; i < l; i += 2 ) {
18088
18088
 
18089
- _start.fromBufferAttribute( positionAttribute, i );
18090
- _end.fromBufferAttribute( positionAttribute, i + 1 );
18089
+ _start$1.fromBufferAttribute( positionAttribute, i );
18090
+ _end$1.fromBufferAttribute( positionAttribute, i + 1 );
18091
18091
 
18092
18092
  lineDistances[ i ] = ( i === 0 ) ? 0 : lineDistances[ i - 1 ];
18093
- lineDistances[ i + 1 ] = lineDistances[ i ] + _start.distanceTo( _end );
18093
+ lineDistances[ i + 1 ] = lineDistances[ i ] + _start$1.distanceTo( _end$1 );
18094
18094
 
18095
18095
  }
18096
18096
 
@@ -36457,7 +36457,7 @@
36457
36457
 
36458
36458
  }
36459
36459
 
36460
- const _vector$1 = /*@__PURE__*/ new Vector3();
36460
+ const _vector$1$1 = /*@__PURE__*/ new Vector3();
36461
36461
  const _color1 = /*@__PURE__*/ new Color();
36462
36462
  const _color2 = /*@__PURE__*/ new Color();
36463
36463
 
@@ -36529,7 +36529,7 @@
36529
36529
 
36530
36530
  this.light.updateWorldMatrix( true, false );
36531
36531
 
36532
- mesh.lookAt( _vector$1.setFromMatrixPosition( this.light.matrixWorld ).negate() );
36532
+ mesh.lookAt( _vector$1$1.setFromMatrixPosition( this.light.matrixWorld ).negate() );
36533
36533
 
36534
36534
  }
36535
36535
 
@@ -37017,7 +37017,7 @@
37017
37017
 
37018
37018
  }
37019
37019
 
37020
- const _box = /*@__PURE__*/ new Box3();
37020
+ const _box$5 = /*@__PURE__*/ new Box3();
37021
37021
 
37022
37022
  class BoxHelper extends LineSegments {
37023
37023
 
@@ -37051,14 +37051,14 @@
37051
37051
 
37052
37052
  if ( this.object !== undefined ) {
37053
37053
 
37054
- _box.setFromObject( this.object );
37054
+ _box$5.setFromObject( this.object );
37055
37055
 
37056
37056
  }
37057
37057
 
37058
- if ( _box.isEmpty() ) return;
37058
+ if ( _box$5.isEmpty() ) return;
37059
37059
 
37060
- const min = _box.min;
37061
- const max = _box.max;
37060
+ const min = _box$5.min;
37061
+ const max = _box$5.max;
37062
37062
 
37063
37063
  /*
37064
37064
  5____4
@@ -58881,7 +58881,7 @@ void main() {
58881
58881
  let _heightHalf;
58882
58882
  const _viewMatrix = new Matrix4();
58883
58883
  const _viewProjectionMatrix = new Matrix4();
58884
- const _vector = new Vector3();
58884
+ const _vector$1 = new Vector3();
58885
58885
  const _vector1 = new Vector4();
58886
58886
  const _vector2 = new Vector4();
58887
58887
  const point = new Vector2();
@@ -58900,10 +58900,10 @@ void main() {
58900
58900
  _viewProjectionMatrix.multiplyMatrices(this.camera.projectionMatrix, _viewMatrix);
58901
58901
  }
58902
58902
  projectPoint(p) {
58903
- _vector.copy(p).applyMatrix4(_viewProjectionMatrix);
58904
- const visible = _vector.z >= -1 && _vector.z <= 1;
58905
- point.x = (_vector.x + 1) * _widthHalf;
58906
- point.y = (-_vector.y + 1) * _heightHalf;
58903
+ _vector$1.copy(p).applyMatrix4(_viewProjectionMatrix);
58904
+ const visible = _vector$1.z >= -1 && _vector$1.z <= 1;
58905
+ point.x = (_vector$1.x + 1) * _widthHalf;
58906
+ point.y = (-_vector$1.y + 1) * _heightHalf;
58907
58907
  return { point, visible };
58908
58908
  }
58909
58909
  projectLine(p1, p2) {
@@ -59740,31 +59740,22 @@ void main() {
59740
59740
  return;
59741
59741
  this.viewer.executeCommand("zoomToSelected");
59742
59742
  };
59743
- this.optionsChange = () => {
59744
- const { facesColor, facesTransparancy } = this.viewer.options;
59745
- this.facesMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
59746
- this.facesMaterial.opacity = (255 - facesTransparancy) / 255;
59747
- this.viewer.update();
59743
+ this.initHighlighter = () => {
59744
+ this.highlighter = this.viewer.getComponent("HighlighterComponent");
59748
59745
  };
59749
59746
  this.viewer = viewer;
59750
59747
  this.raycaster = new Raycaster();
59751
59748
  this.downPosition = new Vector2();
59752
- const { facesColor, facesTransparancy } = this.viewer.options;
59753
- this.facesMaterial = new MeshBasicMaterial();
59754
- this.facesMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
59755
- this.facesMaterial.opacity = (255 - facesTransparancy) / 255;
59756
- this.facesMaterial.transparent = true;
59757
59749
  this.viewer.addEventListener("pointerdown", this.onPointerDown);
59758
59750
  this.viewer.addEventListener("pointerup", this.onPointerUp);
59759
59751
  this.viewer.addEventListener("dblclick", this.onDoubleClick);
59760
- this.viewer.addEventListener("optionschange", this.optionsChange);
59752
+ this.viewer.addEventListener("initialize", this.initHighlighter);
59761
59753
  }
59762
59754
  dispose() {
59763
- this.facesMaterial.dispose();
59764
59755
  this.viewer.removeEventListener("pointerdown", this.onPointerDown);
59765
59756
  this.viewer.removeEventListener("pointerup", this.onPointerUp);
59766
59757
  this.viewer.removeEventListener("dblclick", this.onDoubleClick);
59767
- this.viewer.removeEventListener("optionschange", this.optionsChange);
59758
+ this.viewer.removeEventListener("initialize", this.initHighlighter);
59768
59759
  }
59769
59760
  getMousePosition(event, target) {
59770
59761
  return target.set(event.clientX, event.clientY);
@@ -59791,14 +59782,13 @@ void main() {
59791
59782
  if (object.isSelected)
59792
59783
  return;
59793
59784
  object.isSelected = true;
59794
- object.originalMaterial = object.material;
59795
- object.material = this.facesMaterial;
59785
+ this.highlighter.highlight(object);
59796
59786
  this.viewer.selected.push(object);
59797
59787
  }
59798
59788
  clearSelection() {
59799
59789
  this.viewer.selected.forEach((object) => {
59800
59790
  object.isSelected = false;
59801
- object.material = object.originalMaterial;
59791
+ this.highlighter.unhighlight(object);
59802
59792
  });
59803
59793
  this.viewer.selected.length = 0;
59804
59794
  }
@@ -60303,175 +60293,6 @@ void main() {
60303
60293
  }
60304
60294
  }
60305
60295
 
60306
- /**
60307
- * https://github.com/google/model-viewer/blob/master/packages/model-viewer/src/three-components/EnvironmentScene.ts
60308
- */
60309
-
60310
-
60311
- class RoomEnvironment extends Scene {
60312
-
60313
- constructor() {
60314
-
60315
- super();
60316
-
60317
- const geometry = new BoxGeometry();
60318
- geometry.deleteAttribute( 'uv' );
60319
-
60320
- const roomMaterial = new MeshStandardMaterial( { side: BackSide } );
60321
- const boxMaterial = new MeshStandardMaterial();
60322
-
60323
- const mainLight = new PointLight( 0xffffff, 900, 28, 2 );
60324
- mainLight.position.set( 0.418, 16.199, 0.300 );
60325
- this.add( mainLight );
60326
-
60327
- const room = new Mesh( geometry, roomMaterial );
60328
- room.position.set( -0.757, 13.219, 0.717 );
60329
- room.scale.set( 31.713, 28.305, 28.591 );
60330
- this.add( room );
60331
-
60332
- const box1 = new Mesh( geometry, boxMaterial );
60333
- box1.position.set( -10.906, 2.009, 1.846 );
60334
- box1.rotation.set( 0, -0.195, 0 );
60335
- box1.scale.set( 2.328, 7.905, 4.651 );
60336
- this.add( box1 );
60337
-
60338
- const box2 = new Mesh( geometry, boxMaterial );
60339
- box2.position.set( -5.607, -0.754, -0.758 );
60340
- box2.rotation.set( 0, 0.994, 0 );
60341
- box2.scale.set( 1.970, 1.534, 3.955 );
60342
- this.add( box2 );
60343
-
60344
- const box3 = new Mesh( geometry, boxMaterial );
60345
- box3.position.set( 6.167, 0.857, 7.803 );
60346
- box3.rotation.set( 0, 0.561, 0 );
60347
- box3.scale.set( 3.927, 6.285, 3.687 );
60348
- this.add( box3 );
60349
-
60350
- const box4 = new Mesh( geometry, boxMaterial );
60351
- box4.position.set( -2.017, 0.018, 6.124 );
60352
- box4.rotation.set( 0, 0.333, 0 );
60353
- box4.scale.set( 2.002, 4.566, 2.064 );
60354
- this.add( box4 );
60355
-
60356
- const box5 = new Mesh( geometry, boxMaterial );
60357
- box5.position.set( 2.291, -0.756, -2.621 );
60358
- box5.rotation.set( 0, -0.286, 0 );
60359
- box5.scale.set( 1.546, 1.552, 1.496 );
60360
- this.add( box5 );
60361
-
60362
- const box6 = new Mesh( geometry, boxMaterial );
60363
- box6.position.set( -2.193, -0.369, -5.547 );
60364
- box6.rotation.set( 0, 0.516, 0 );
60365
- box6.scale.set( 3.875, 3.487, 2.986 );
60366
- this.add( box6 );
60367
-
60368
-
60369
- // -x right
60370
- const light1 = new Mesh( geometry, createAreaLightMaterial( 50 ) );
60371
- light1.position.set( -16.116, 14.37, 8.208 );
60372
- light1.scale.set( 0.1, 2.428, 2.739 );
60373
- this.add( light1 );
60374
-
60375
- // -x left
60376
- const light2 = new Mesh( geometry, createAreaLightMaterial( 50 ) );
60377
- light2.position.set( -16.109, 18.021, -8.207 );
60378
- light2.scale.set( 0.1, 2.425, 2.751 );
60379
- this.add( light2 );
60380
-
60381
- // +x
60382
- const light3 = new Mesh( geometry, createAreaLightMaterial( 17 ) );
60383
- light3.position.set( 14.904, 12.198, -1.832 );
60384
- light3.scale.set( 0.15, 4.265, 6.331 );
60385
- this.add( light3 );
60386
-
60387
- // +z
60388
- const light4 = new Mesh( geometry, createAreaLightMaterial( 43 ) );
60389
- light4.position.set( -0.462, 8.89, 14.520 );
60390
- light4.scale.set( 4.38, 5.441, 0.088 );
60391
- this.add( light4 );
60392
-
60393
- // -z
60394
- const light5 = new Mesh( geometry, createAreaLightMaterial( 20 ) );
60395
- light5.position.set( 3.235, 11.486, -12.541 );
60396
- light5.scale.set( 2.5, 2.0, 0.1 );
60397
- this.add( light5 );
60398
-
60399
- // +y
60400
- const light6 = new Mesh( geometry, createAreaLightMaterial( 100 ) );
60401
- light6.position.set( 0.0, 20.0, 0.0 );
60402
- light6.scale.set( 1.0, 0.1, 1.0 );
60403
- this.add( light6 );
60404
-
60405
- }
60406
-
60407
- dispose() {
60408
-
60409
- const resources = new Set();
60410
-
60411
- this.traverse( ( object ) => {
60412
-
60413
- if ( object.isMesh ) {
60414
-
60415
- resources.add( object.geometry );
60416
- resources.add( object.material );
60417
-
60418
- }
60419
-
60420
- } );
60421
-
60422
- for ( const resource of resources ) {
60423
-
60424
- resource.dispose();
60425
-
60426
- }
60427
-
60428
- }
60429
-
60430
- }
60431
-
60432
- function createAreaLightMaterial( intensity ) {
60433
-
60434
- const material = new MeshBasicMaterial();
60435
- material.color.setScalar( intensity );
60436
- return material;
60437
-
60438
- }
60439
-
60440
- ///////////////////////////////////////////////////////////////////////////////
60441
- // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
60442
- // All rights reserved.
60443
- //
60444
- // This software and its documentation and related materials are owned by
60445
- // the Alliance. The software may only be incorporated into application
60446
- // programs owned by members of the Alliance, subject to a signed
60447
- // Membership Agreement and Supplemental Software License Agreement with the
60448
- // Alliance. The structure and organization of this software are the valuable
60449
- // trade secrets of the Alliance and its suppliers. The software is also
60450
- // protected by copyright law and international treaty provisions. Application
60451
- // programs incorporating this software must include the following statement
60452
- // with their copyright notices:
60453
- //
60454
- // This application incorporates Open Design Alliance software pursuant to a
60455
- // license agreement with Open Design Alliance.
60456
- // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
60457
- // All rights reserved.
60458
- //
60459
- // By use of this software, its documentation or related materials, you
60460
- // acknowledge and accept the above terms.
60461
- ///////////////////////////////////////////////////////////////////////////////
60462
- class RoomEnvironmentComponent {
60463
- constructor(viewer) {
60464
- this.viewer = viewer;
60465
- const environment = new RoomEnvironment();
60466
- const pmremGenerator = new PMREMGenerator(this.viewer.renderer);
60467
- this.viewer.scene.environment = pmremGenerator.fromScene(environment).texture;
60468
- environment.dispose();
60469
- }
60470
- dispose() {
60471
- this.viewer.scene.environment = undefined;
60472
- }
60473
- }
60474
-
60475
60296
  ///////////////////////////////////////////////////////////////////////////////
60476
60297
  // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
60477
60298
  // All rights reserved.
@@ -60616,21 +60437,37 @@ void main() {
60616
60437
  this.geometryEnd = () => {
60617
60438
  this.ambientLight.removeFromParent();
60618
60439
  this.directionalLight.removeFromParent();
60440
+ this.frontLight.removeFromParent();
60441
+ this.hemisphereLight.removeFromParent();
60619
60442
  if (this.viewer.extents.isEmpty())
60620
60443
  return;
60621
60444
  const extentsCenter = this.viewer.extents.getCenter(new Vector3());
60622
- const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius * 2;
60623
- this.directionalLight.position.set(0.5, 0, 0.866).multiplyScalar(extentsSize).add(extentsCenter);
60445
+ const extentsSize = this.viewer.extents.getBoundingSphere(new Sphere()).radius;
60446
+ this.directionalLight.position
60447
+ .set(0.5, 0, 0.866)
60448
+ .multiplyScalar(extentsSize * 2)
60449
+ .add(extentsCenter);
60624
60450
  this.directionalLight.target.position.copy(extentsCenter);
60451
+ this.frontLight.position.set(0, extentsSize * 2, 0).add(extentsCenter);
60452
+ this.frontLight.target.position.copy(extentsCenter);
60453
+ this.hemisphereLight.position.set(0, extentsSize * 3, 0).add(extentsCenter);
60625
60454
  this.viewer.scene.add(this.ambientLight);
60626
60455
  this.viewer.scene.add(this.directionalLight);
60456
+ this.viewer.scene.add(this.frontLight);
60457
+ this.viewer.scene.add(this.hemisphereLight);
60627
60458
  };
60628
60459
  this.viewer = viewer;
60629
- this.ambientLight = new AmbientLight(0xffffff, 0);
60460
+ this.ambientLight = new AmbientLight(0xffffff, 1);
60630
60461
  this.viewer.scene.add(this.ambientLight);
60631
60462
  this.directionalLight = new DirectionalLight(0xffffff, 1);
60632
60463
  this.directionalLight.position.set(0.5, 0, 0.866); // ~60º
60633
60464
  this.viewer.scene.add(this.directionalLight);
60465
+ this.frontLight = new DirectionalLight(0xffffff, 1.25);
60466
+ this.frontLight.position.set(0, 1, 0);
60467
+ this.viewer.scene.add(this.frontLight);
60468
+ this.hemisphereLight = new HemisphereLight(0xffffff, 0x444444, 1.25);
60469
+ this.hemisphereLight.position.set(0, 0, 1);
60470
+ this.viewer.scene.add(this.hemisphereLight);
60634
60471
  this.viewer.addEventListener("databasechunk", this.geometryEnd);
60635
60472
  this.viewer.addEventListener("clear", this.geometryEnd);
60636
60473
  }
@@ -60639,6 +60476,10 @@ void main() {
60639
60476
  this.ambientLight.dispose();
60640
60477
  this.directionalLight.removeFromParent();
60641
60478
  this.directionalLight.dispose();
60479
+ this.frontLight.removeFromParent();
60480
+ this.frontLight.dispose();
60481
+ this.hemisphereLight.removeFromParent();
60482
+ this.hemisphereLight.dispose();
60642
60483
  this.viewer.removeEventListener("databasechunk", this.geometryEnd);
60643
60484
  this.viewer.removeEventListener("clear", this.geometryEnd);
60644
60485
  }
@@ -60732,6 +60573,1096 @@ void main() {
60732
60573
  }
60733
60574
  }
60734
60575
 
60576
+ const _box = new Box3();
60577
+ const _vector = new Vector3();
60578
+
60579
+ class LineSegmentsGeometry extends InstancedBufferGeometry {
60580
+
60581
+ constructor() {
60582
+
60583
+ super();
60584
+
60585
+ this.isLineSegmentsGeometry = true;
60586
+
60587
+ this.type = 'LineSegmentsGeometry';
60588
+
60589
+ const positions = [ -1, 2, 0, 1, 2, 0, -1, 1, 0, 1, 1, 0, -1, 0, 0, 1, 0, 0, -1, -1, 0, 1, -1, 0 ];
60590
+ const uvs = [ -1, 2, 1, 2, -1, 1, 1, 1, -1, -1, 1, -1, -1, -2, 1, -2 ];
60591
+ const index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
60592
+
60593
+ this.setIndex( index );
60594
+ this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
60595
+ this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
60596
+
60597
+ }
60598
+
60599
+ applyMatrix4( matrix ) {
60600
+
60601
+ const start = this.attributes.instanceStart;
60602
+ const end = this.attributes.instanceEnd;
60603
+
60604
+ if ( start !== undefined ) {
60605
+
60606
+ start.applyMatrix4( matrix );
60607
+
60608
+ end.applyMatrix4( matrix );
60609
+
60610
+ start.needsUpdate = true;
60611
+
60612
+ }
60613
+
60614
+ if ( this.boundingBox !== null ) {
60615
+
60616
+ this.computeBoundingBox();
60617
+
60618
+ }
60619
+
60620
+ if ( this.boundingSphere !== null ) {
60621
+
60622
+ this.computeBoundingSphere();
60623
+
60624
+ }
60625
+
60626
+ return this;
60627
+
60628
+ }
60629
+
60630
+ setPositions( array ) {
60631
+
60632
+ let lineSegments;
60633
+
60634
+ if ( array instanceof Float32Array ) {
60635
+
60636
+ lineSegments = array;
60637
+
60638
+ } else if ( Array.isArray( array ) ) {
60639
+
60640
+ lineSegments = new Float32Array( array );
60641
+
60642
+ }
60643
+
60644
+ const instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
60645
+
60646
+ this.setAttribute( 'instanceStart', new InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
60647
+ this.setAttribute( 'instanceEnd', new InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
60648
+
60649
+ this.instanceCount = this.attributes.instanceStart.count;
60650
+
60651
+ //
60652
+
60653
+ this.computeBoundingBox();
60654
+ this.computeBoundingSphere();
60655
+
60656
+ return this;
60657
+
60658
+ }
60659
+
60660
+ setColors( array ) {
60661
+
60662
+ let colors;
60663
+
60664
+ if ( array instanceof Float32Array ) {
60665
+
60666
+ colors = array;
60667
+
60668
+ } else if ( Array.isArray( array ) ) {
60669
+
60670
+ colors = new Float32Array( array );
60671
+
60672
+ }
60673
+
60674
+ const instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
60675
+
60676
+ this.setAttribute( 'instanceColorStart', new InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
60677
+ this.setAttribute( 'instanceColorEnd', new InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
60678
+
60679
+ return this;
60680
+
60681
+ }
60682
+
60683
+ fromWireframeGeometry( geometry ) {
60684
+
60685
+ this.setPositions( geometry.attributes.position.array );
60686
+
60687
+ return this;
60688
+
60689
+ }
60690
+
60691
+ fromEdgesGeometry( geometry ) {
60692
+
60693
+ this.setPositions( geometry.attributes.position.array );
60694
+
60695
+ return this;
60696
+
60697
+ }
60698
+
60699
+ fromMesh( mesh ) {
60700
+
60701
+ this.fromWireframeGeometry( new WireframeGeometry( mesh.geometry ) );
60702
+
60703
+ // set colors, maybe
60704
+
60705
+ return this;
60706
+
60707
+ }
60708
+
60709
+ fromLineSegments( lineSegments ) {
60710
+
60711
+ const geometry = lineSegments.geometry;
60712
+
60713
+ this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
60714
+
60715
+ // set colors, maybe
60716
+
60717
+ return this;
60718
+
60719
+ }
60720
+
60721
+ computeBoundingBox() {
60722
+
60723
+ if ( this.boundingBox === null ) {
60724
+
60725
+ this.boundingBox = new Box3();
60726
+
60727
+ }
60728
+
60729
+ const start = this.attributes.instanceStart;
60730
+ const end = this.attributes.instanceEnd;
60731
+
60732
+ if ( start !== undefined && end !== undefined ) {
60733
+
60734
+ this.boundingBox.setFromBufferAttribute( start );
60735
+
60736
+ _box.setFromBufferAttribute( end );
60737
+
60738
+ this.boundingBox.union( _box );
60739
+
60740
+ }
60741
+
60742
+ }
60743
+
60744
+ computeBoundingSphere() {
60745
+
60746
+ if ( this.boundingSphere === null ) {
60747
+
60748
+ this.boundingSphere = new Sphere();
60749
+
60750
+ }
60751
+
60752
+ if ( this.boundingBox === null ) {
60753
+
60754
+ this.computeBoundingBox();
60755
+
60756
+ }
60757
+
60758
+ const start = this.attributes.instanceStart;
60759
+ const end = this.attributes.instanceEnd;
60760
+
60761
+ if ( start !== undefined && end !== undefined ) {
60762
+
60763
+ const center = this.boundingSphere.center;
60764
+
60765
+ this.boundingBox.getCenter( center );
60766
+
60767
+ let maxRadiusSq = 0;
60768
+
60769
+ for ( let i = 0, il = start.count; i < il; i ++ ) {
60770
+
60771
+ _vector.fromBufferAttribute( start, i );
60772
+ maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
60773
+
60774
+ _vector.fromBufferAttribute( end, i );
60775
+ maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
60776
+
60777
+ }
60778
+
60779
+ this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
60780
+
60781
+ if ( isNaN( this.boundingSphere.radius ) ) {
60782
+
60783
+ console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
60784
+
60785
+ }
60786
+
60787
+ }
60788
+
60789
+ }
60790
+
60791
+ toJSON() {
60792
+
60793
+ // todo
60794
+
60795
+ }
60796
+
60797
+ applyMatrix( matrix ) {
60798
+
60799
+ console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
60800
+
60801
+ return this.applyMatrix4( matrix );
60802
+
60803
+ }
60804
+
60805
+ }
60806
+
60807
+ UniformsLib.line = {
60808
+
60809
+ worldUnits: { value: 1 },
60810
+ linewidth: { value: 1 },
60811
+ resolution: { value: new Vector2( 1, 1 ) },
60812
+ dashOffset: { value: 0 },
60813
+ dashScale: { value: 1 },
60814
+ dashSize: { value: 1 },
60815
+ gapSize: { value: 1 } // todo FIX - maybe change to totalSize
60816
+
60817
+ };
60818
+
60819
+ ShaderLib[ 'line' ] = {
60820
+
60821
+ uniforms: UniformsUtils.merge( [
60822
+ UniformsLib.common,
60823
+ UniformsLib.fog,
60824
+ UniformsLib.line
60825
+ ] ),
60826
+
60827
+ vertexShader:
60828
+ /* glsl */`
60829
+ #include <common>
60830
+ #include <color_pars_vertex>
60831
+ #include <fog_pars_vertex>
60832
+ #include <logdepthbuf_pars_vertex>
60833
+ #include <clipping_planes_pars_vertex>
60834
+
60835
+ uniform float linewidth;
60836
+ uniform vec2 resolution;
60837
+
60838
+ attribute vec3 instanceStart;
60839
+ attribute vec3 instanceEnd;
60840
+
60841
+ attribute vec3 instanceColorStart;
60842
+ attribute vec3 instanceColorEnd;
60843
+
60844
+ #ifdef WORLD_UNITS
60845
+
60846
+ varying vec4 worldPos;
60847
+ varying vec3 worldStart;
60848
+ varying vec3 worldEnd;
60849
+
60850
+ #ifdef USE_DASH
60851
+
60852
+ varying vec2 vUv;
60853
+
60854
+ #endif
60855
+
60856
+ #else
60857
+
60858
+ varying vec2 vUv;
60859
+
60860
+ #endif
60861
+
60862
+ #ifdef USE_DASH
60863
+
60864
+ uniform float dashScale;
60865
+ attribute float instanceDistanceStart;
60866
+ attribute float instanceDistanceEnd;
60867
+ varying float vLineDistance;
60868
+
60869
+ #endif
60870
+
60871
+ void trimSegment( const in vec4 start, inout vec4 end ) {
60872
+
60873
+ // trim end segment so it terminates between the camera plane and the near plane
60874
+
60875
+ // conservative estimate of the near plane
60876
+ float a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column
60877
+ float b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column
60878
+ float nearEstimate = - 0.5 * b / a;
60879
+
60880
+ float alpha = ( nearEstimate - start.z ) / ( end.z - start.z );
60881
+
60882
+ end.xyz = mix( start.xyz, end.xyz, alpha );
60883
+
60884
+ }
60885
+
60886
+ void main() {
60887
+
60888
+ #ifdef USE_COLOR
60889
+
60890
+ vColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd;
60891
+
60892
+ #endif
60893
+
60894
+ #ifdef USE_DASH
60895
+
60896
+ vLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd;
60897
+ vUv = uv;
60898
+
60899
+ #endif
60900
+
60901
+ float aspect = resolution.x / resolution.y;
60902
+
60903
+ // camera space
60904
+ vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 );
60905
+ vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 );
60906
+
60907
+ #ifdef WORLD_UNITS
60908
+
60909
+ worldStart = start.xyz;
60910
+ worldEnd = end.xyz;
60911
+
60912
+ #else
60913
+
60914
+ vUv = uv;
60915
+
60916
+ #endif
60917
+
60918
+ // special case for perspective projection, and segments that terminate either in, or behind, the camera plane
60919
+ // clearly the gpu firmware has a way of addressing this issue when projecting into ndc space
60920
+ // but we need to perform ndc-space calculations in the shader, so we must address this issue directly
60921
+ // perhaps there is a more elegant solution -- WestLangley
60922
+
60923
+ bool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column
60924
+
60925
+ if ( perspective ) {
60926
+
60927
+ if ( start.z < 0.0 && end.z >= 0.0 ) {
60928
+
60929
+ trimSegment( start, end );
60930
+
60931
+ } else if ( end.z < 0.0 && start.z >= 0.0 ) {
60932
+
60933
+ trimSegment( end, start );
60934
+
60935
+ }
60936
+
60937
+ }
60938
+
60939
+ // clip space
60940
+ vec4 clipStart = projectionMatrix * start;
60941
+ vec4 clipEnd = projectionMatrix * end;
60942
+
60943
+ // ndc space
60944
+ vec3 ndcStart = clipStart.xyz / clipStart.w;
60945
+ vec3 ndcEnd = clipEnd.xyz / clipEnd.w;
60946
+
60947
+ // direction
60948
+ vec2 dir = ndcEnd.xy - ndcStart.xy;
60949
+
60950
+ // account for clip-space aspect ratio
60951
+ dir.x *= aspect;
60952
+ dir = normalize( dir );
60953
+
60954
+ #ifdef WORLD_UNITS
60955
+
60956
+ vec3 worldDir = normalize( end.xyz - start.xyz );
60957
+ vec3 tmpFwd = normalize( mix( start.xyz, end.xyz, 0.5 ) );
60958
+ vec3 worldUp = normalize( cross( worldDir, tmpFwd ) );
60959
+ vec3 worldFwd = cross( worldDir, worldUp );
60960
+ worldPos = position.y < 0.5 ? start: end;
60961
+
60962
+ // height offset
60963
+ float hw = linewidth * 0.5;
60964
+ worldPos.xyz += position.x < 0.0 ? hw * worldUp : - hw * worldUp;
60965
+
60966
+ // don't extend the line if we're rendering dashes because we
60967
+ // won't be rendering the endcaps
60968
+ #ifndef USE_DASH
60969
+
60970
+ // cap extension
60971
+ worldPos.xyz += position.y < 0.5 ? - hw * worldDir : hw * worldDir;
60972
+
60973
+ // add width to the box
60974
+ worldPos.xyz += worldFwd * hw;
60975
+
60976
+ // endcaps
60977
+ if ( position.y > 1.0 || position.y < 0.0 ) {
60978
+
60979
+ worldPos.xyz -= worldFwd * 2.0 * hw;
60980
+
60981
+ }
60982
+
60983
+ #endif
60984
+
60985
+ // project the worldpos
60986
+ vec4 clip = projectionMatrix * worldPos;
60987
+
60988
+ // shift the depth of the projected points so the line
60989
+ // segments overlap neatly
60990
+ vec3 clipPose = ( position.y < 0.5 ) ? ndcStart : ndcEnd;
60991
+ clip.z = clipPose.z * clip.w;
60992
+
60993
+ #else
60994
+
60995
+ vec2 offset = vec2( dir.y, - dir.x );
60996
+ // undo aspect ratio adjustment
60997
+ dir.x /= aspect;
60998
+ offset.x /= aspect;
60999
+
61000
+ // sign flip
61001
+ if ( position.x < 0.0 ) offset *= - 1.0;
61002
+
61003
+ // endcaps
61004
+ if ( position.y < 0.0 ) {
61005
+
61006
+ offset += - dir;
61007
+
61008
+ } else if ( position.y > 1.0 ) {
61009
+
61010
+ offset += dir;
61011
+
61012
+ }
61013
+
61014
+ // adjust for linewidth
61015
+ offset *= linewidth;
61016
+
61017
+ // adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
61018
+ offset /= resolution.y;
61019
+
61020
+ // select end
61021
+ vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd;
61022
+
61023
+ // back to clip space
61024
+ offset *= clip.w;
61025
+
61026
+ clip.xy += offset;
61027
+
61028
+ #endif
61029
+
61030
+ gl_Position = clip;
61031
+
61032
+ vec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation
61033
+
61034
+ #include <logdepthbuf_vertex>
61035
+ #include <clipping_planes_vertex>
61036
+ #include <fog_vertex>
61037
+
61038
+ }
61039
+ `,
61040
+
61041
+ fragmentShader:
61042
+ /* glsl */`
61043
+ uniform vec3 diffuse;
61044
+ uniform float opacity;
61045
+ uniform float linewidth;
61046
+
61047
+ #ifdef USE_DASH
61048
+
61049
+ uniform float dashOffset;
61050
+ uniform float dashSize;
61051
+ uniform float gapSize;
61052
+
61053
+ #endif
61054
+
61055
+ varying float vLineDistance;
61056
+
61057
+ #ifdef WORLD_UNITS
61058
+
61059
+ varying vec4 worldPos;
61060
+ varying vec3 worldStart;
61061
+ varying vec3 worldEnd;
61062
+
61063
+ #ifdef USE_DASH
61064
+
61065
+ varying vec2 vUv;
61066
+
61067
+ #endif
61068
+
61069
+ #else
61070
+
61071
+ varying vec2 vUv;
61072
+
61073
+ #endif
61074
+
61075
+ #include <common>
61076
+ #include <color_pars_fragment>
61077
+ #include <fog_pars_fragment>
61078
+ #include <logdepthbuf_pars_fragment>
61079
+ #include <clipping_planes_pars_fragment>
61080
+
61081
+ vec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) {
61082
+
61083
+ float mua;
61084
+ float mub;
61085
+
61086
+ vec3 p13 = p1 - p3;
61087
+ vec3 p43 = p4 - p3;
61088
+
61089
+ vec3 p21 = p2 - p1;
61090
+
61091
+ float d1343 = dot( p13, p43 );
61092
+ float d4321 = dot( p43, p21 );
61093
+ float d1321 = dot( p13, p21 );
61094
+ float d4343 = dot( p43, p43 );
61095
+ float d2121 = dot( p21, p21 );
61096
+
61097
+ float denom = d2121 * d4343 - d4321 * d4321;
61098
+
61099
+ float numer = d1343 * d4321 - d1321 * d4343;
61100
+
61101
+ mua = numer / denom;
61102
+ mua = clamp( mua, 0.0, 1.0 );
61103
+ mub = ( d1343 + d4321 * ( mua ) ) / d4343;
61104
+ mub = clamp( mub, 0.0, 1.0 );
61105
+
61106
+ return vec2( mua, mub );
61107
+
61108
+ }
61109
+
61110
+ void main() {
61111
+
61112
+ #include <clipping_planes_fragment>
61113
+
61114
+ #ifdef USE_DASH
61115
+
61116
+ if ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps
61117
+
61118
+ if ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard; // todo - FIX
61119
+
61120
+ #endif
61121
+
61122
+ float alpha = opacity;
61123
+
61124
+ #ifdef WORLD_UNITS
61125
+
61126
+ // Find the closest points on the view ray and the line segment
61127
+ vec3 rayEnd = normalize( worldPos.xyz ) * 1e5;
61128
+ vec3 lineDir = worldEnd - worldStart;
61129
+ vec2 params = closestLineToLine( worldStart, worldEnd, vec3( 0.0, 0.0, 0.0 ), rayEnd );
61130
+
61131
+ vec3 p1 = worldStart + lineDir * params.x;
61132
+ vec3 p2 = rayEnd * params.y;
61133
+ vec3 delta = p1 - p2;
61134
+ float len = length( delta );
61135
+ float norm = len / linewidth;
61136
+
61137
+ #ifndef USE_DASH
61138
+
61139
+ #ifdef USE_ALPHA_TO_COVERAGE
61140
+
61141
+ float dnorm = fwidth( norm );
61142
+ alpha = 1.0 - smoothstep( 0.5 - dnorm, 0.5 + dnorm, norm );
61143
+
61144
+ #else
61145
+
61146
+ if ( norm > 0.5 ) {
61147
+
61148
+ discard;
61149
+
61150
+ }
61151
+
61152
+ #endif
61153
+
61154
+ #endif
61155
+
61156
+ #else
61157
+
61158
+ #ifdef USE_ALPHA_TO_COVERAGE
61159
+
61160
+ // artifacts appear on some hardware if a derivative is taken within a conditional
61161
+ float a = vUv.x;
61162
+ float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
61163
+ float len2 = a * a + b * b;
61164
+ float dlen = fwidth( len2 );
61165
+
61166
+ if ( abs( vUv.y ) > 1.0 ) {
61167
+
61168
+ alpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 );
61169
+
61170
+ }
61171
+
61172
+ #else
61173
+
61174
+ if ( abs( vUv.y ) > 1.0 ) {
61175
+
61176
+ float a = vUv.x;
61177
+ float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
61178
+ float len2 = a * a + b * b;
61179
+
61180
+ if ( len2 > 1.0 ) discard;
61181
+
61182
+ }
61183
+
61184
+ #endif
61185
+
61186
+ #endif
61187
+
61188
+ vec4 diffuseColor = vec4( diffuse, alpha );
61189
+
61190
+ #include <logdepthbuf_fragment>
61191
+ #include <color_fragment>
61192
+
61193
+ gl_FragColor = vec4( diffuseColor.rgb, alpha );
61194
+
61195
+ #include <tonemapping_fragment>
61196
+ #include <colorspace_fragment>
61197
+ #include <fog_fragment>
61198
+ #include <premultiplied_alpha_fragment>
61199
+
61200
+ }
61201
+ `
61202
+ };
61203
+
61204
+ class LineMaterial extends ShaderMaterial {
61205
+
61206
+ constructor( parameters ) {
61207
+
61208
+ super( {
61209
+
61210
+ type: 'LineMaterial',
61211
+ uniforms: UniformsUtils.clone( ShaderLib[ 'line' ].uniforms ),
61212
+
61213
+ vertexShader: ShaderLib[ 'line' ].vertexShader,
61214
+ fragmentShader: ShaderLib[ 'line' ].fragmentShader,
61215
+
61216
+ clipping: true // required for clipping support
61217
+
61218
+ } );
61219
+
61220
+ this.isLineMaterial = true;
61221
+
61222
+ this.setValues( parameters );
61223
+
61224
+ }
61225
+
61226
+ get color() {
61227
+
61228
+ return this.uniforms.diffuse.value;
61229
+
61230
+ }
61231
+
61232
+ set color( value ) {
61233
+
61234
+ this.uniforms.diffuse.value = value;
61235
+
61236
+ }
61237
+
61238
+ get worldUnits() {
61239
+
61240
+ return 'WORLD_UNITS' in this.defines;
61241
+
61242
+ }
61243
+
61244
+ set worldUnits( value ) {
61245
+
61246
+ if ( value === true ) {
61247
+
61248
+ this.defines.WORLD_UNITS = '';
61249
+
61250
+ } else {
61251
+
61252
+ delete this.defines.WORLD_UNITS;
61253
+
61254
+ }
61255
+
61256
+ }
61257
+
61258
+ get linewidth() {
61259
+
61260
+ return this.uniforms.linewidth.value;
61261
+
61262
+ }
61263
+
61264
+ set linewidth( value ) {
61265
+
61266
+ if ( ! this.uniforms.linewidth ) return;
61267
+ this.uniforms.linewidth.value = value;
61268
+
61269
+ }
61270
+
61271
+ get dashed() {
61272
+
61273
+ return 'USE_DASH' in this.defines;
61274
+
61275
+ }
61276
+
61277
+ set dashed( value ) {
61278
+
61279
+ if ( ( value === true ) !== this.dashed ) {
61280
+
61281
+ this.needsUpdate = true;
61282
+
61283
+ }
61284
+
61285
+ if ( value === true ) {
61286
+
61287
+ this.defines.USE_DASH = '';
61288
+
61289
+ } else {
61290
+
61291
+ delete this.defines.USE_DASH;
61292
+
61293
+ }
61294
+
61295
+ }
61296
+
61297
+ get dashScale() {
61298
+
61299
+ return this.uniforms.dashScale.value;
61300
+
61301
+ }
61302
+
61303
+ set dashScale( value ) {
61304
+
61305
+ this.uniforms.dashScale.value = value;
61306
+
61307
+ }
61308
+
61309
+ get dashSize() {
61310
+
61311
+ return this.uniforms.dashSize.value;
61312
+
61313
+ }
61314
+
61315
+ set dashSize( value ) {
61316
+
61317
+ this.uniforms.dashSize.value = value;
61318
+
61319
+ }
61320
+
61321
+ get dashOffset() {
61322
+
61323
+ return this.uniforms.dashOffset.value;
61324
+
61325
+ }
61326
+
61327
+ set dashOffset( value ) {
61328
+
61329
+ this.uniforms.dashOffset.value = value;
61330
+
61331
+ }
61332
+
61333
+ get gapSize() {
61334
+
61335
+ return this.uniforms.gapSize.value;
61336
+
61337
+ }
61338
+
61339
+ set gapSize( value ) {
61340
+
61341
+ this.uniforms.gapSize.value = value;
61342
+
61343
+ }
61344
+
61345
+ get opacity() {
61346
+
61347
+ return this.uniforms.opacity.value;
61348
+
61349
+ }
61350
+
61351
+ set opacity( value ) {
61352
+
61353
+ if ( ! this.uniforms ) return;
61354
+ this.uniforms.opacity.value = value;
61355
+
61356
+ }
61357
+
61358
+ get resolution() {
61359
+
61360
+ return this.uniforms.resolution.value;
61361
+
61362
+ }
61363
+
61364
+ set resolution( value ) {
61365
+
61366
+ this.uniforms.resolution.value.copy( value );
61367
+
61368
+ }
61369
+
61370
+ get alphaToCoverage() {
61371
+
61372
+ return 'USE_ALPHA_TO_COVERAGE' in this.defines;
61373
+
61374
+ }
61375
+
61376
+ set alphaToCoverage( value ) {
61377
+
61378
+ if ( ! this.defines ) return;
61379
+
61380
+ if ( ( value === true ) !== this.alphaToCoverage ) {
61381
+
61382
+ this.needsUpdate = true;
61383
+
61384
+ }
61385
+
61386
+ if ( value === true ) {
61387
+
61388
+ this.defines.USE_ALPHA_TO_COVERAGE = '';
61389
+
61390
+ } else {
61391
+
61392
+ delete this.defines.USE_ALPHA_TO_COVERAGE;
61393
+
61394
+ }
61395
+
61396
+ }
61397
+
61398
+ }
61399
+
61400
+ const _start = new Vector3();
61401
+ const _end = new Vector3();
61402
+ const _viewport = new Vector4();
61403
+
61404
+ class Wireframe extends Mesh {
61405
+
61406
+ constructor( geometry = new LineSegmentsGeometry(), material = new LineMaterial( { color: Math.random() * 0xffffff } ) ) {
61407
+
61408
+ super( geometry, material );
61409
+
61410
+ this.isWireframe = true;
61411
+
61412
+ this.type = 'Wireframe';
61413
+
61414
+ }
61415
+
61416
+ // for backwards-compatibility, but could be a method of LineSegmentsGeometry...
61417
+
61418
+ computeLineDistances() {
61419
+
61420
+ const geometry = this.geometry;
61421
+
61422
+ const instanceStart = geometry.attributes.instanceStart;
61423
+ const instanceEnd = geometry.attributes.instanceEnd;
61424
+ const lineDistances = new Float32Array( 2 * instanceStart.count );
61425
+
61426
+ for ( let i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) {
61427
+
61428
+ _start.fromBufferAttribute( instanceStart, i );
61429
+ _end.fromBufferAttribute( instanceEnd, i );
61430
+
61431
+ lineDistances[ j ] = ( j === 0 ) ? 0 : lineDistances[ j - 1 ];
61432
+ lineDistances[ j + 1 ] = lineDistances[ j ] + _start.distanceTo( _end );
61433
+
61434
+ }
61435
+
61436
+ const instanceDistanceBuffer = new InstancedInterleavedBuffer( lineDistances, 2, 1 ); // d0, d1
61437
+
61438
+ geometry.setAttribute( 'instanceDistanceStart', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 0 ) ); // d0
61439
+ geometry.setAttribute( 'instanceDistanceEnd', new InterleavedBufferAttribute( instanceDistanceBuffer, 1, 1 ) ); // d1
61440
+
61441
+ return this;
61442
+
61443
+ }
61444
+
61445
+ onBeforeRender( renderer ) {
61446
+
61447
+ const uniforms = this.material.uniforms;
61448
+
61449
+ if ( uniforms && uniforms.resolution ) {
61450
+
61451
+ renderer.getViewport( _viewport );
61452
+ this.material.uniforms.resolution.value.set( _viewport.z, _viewport.w );
61453
+
61454
+ }
61455
+
61456
+ }
61457
+
61458
+ }
61459
+
61460
+ ///////////////////////////////////////////////////////////////////////////////
61461
+ // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
61462
+ // All rights reserved.
61463
+ //
61464
+ // This software and its documentation and related materials are owned by
61465
+ // the Alliance. The software may only be incorporated into application
61466
+ // programs owned by members of the Alliance, subject to a signed
61467
+ // Membership Agreement and Supplemental Software License Agreement with the
61468
+ // Alliance. The structure and organization of this software are the valuable
61469
+ // trade secrets of the Alliance and its suppliers. The software is also
61470
+ // protected by copyright law and international treaty provisions. Application
61471
+ // programs incorporating this software must include the following statement
61472
+ // with their copyright notices:
61473
+ //
61474
+ // This application incorporates Open Design Alliance software pursuant to a
61475
+ // license agreement with Open Design Alliance.
61476
+ // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
61477
+ // All rights reserved.
61478
+ //
61479
+ // By use of this software, its documentation or related materials, you
61480
+ // acknowledge and accept the above terms.
61481
+ ///////////////////////////////////////////////////////////////////////////////
61482
+ class HighlighterUtils {
61483
+ static isBreak(positions, i) {
61484
+ return (isNaN(positions[i]) ||
61485
+ isNaN(positions[i + 1]) ||
61486
+ isNaN(positions[i + 2]) ||
61487
+ positions[i] === Infinity ||
61488
+ positions[i] === -Infinity ||
61489
+ positions[i + 1] === Infinity ||
61490
+ positions[i + 1] === -Infinity ||
61491
+ positions[i + 2] === Infinity ||
61492
+ positions[i + 2] === -Infinity);
61493
+ }
61494
+ static fromIndexedLine(positions, indices) {
61495
+ const lineGeometry = new LineSegmentsGeometry();
61496
+ const segments = [];
61497
+ for (let i = 0; i < indices.length; i += 2) {
61498
+ const idx1 = indices[i] * 3;
61499
+ const idx2 = indices[i + 1] * 3;
61500
+ if (indices[i] === -1 || indices[i + 1] === -1) {
61501
+ continue;
61502
+ }
61503
+ segments.push(positions[idx1], positions[idx1 + 1], positions[idx1 + 2], positions[idx2], positions[idx2 + 1], positions[idx2 + 2]);
61504
+ }
61505
+ if (segments.length === 0)
61506
+ return null;
61507
+ lineGeometry.setPositions(segments);
61508
+ return lineGeometry;
61509
+ }
61510
+ static fromNonIndexedLine(positions, isLineSegments) {
61511
+ const lineGeometry = new LineSegmentsGeometry();
61512
+ const segments = [];
61513
+ if (isLineSegments) {
61514
+ for (let i = 0; i < positions.length; i += 6) {
61515
+ if (i + 5 >= positions.length)
61516
+ break;
61517
+ if (HighlighterUtils.isBreak(positions, i) || HighlighterUtils.isBreak(positions, i + 3))
61518
+ continue;
61519
+ segments.push(positions[i], positions[i + 1], positions[i + 2], positions[i + 3], positions[i + 4], positions[i + 5]);
61520
+ }
61521
+ }
61522
+ else {
61523
+ let lastValidIndex = -1;
61524
+ for (let i = 0; i < positions.length; i += 3) {
61525
+ if (HighlighterUtils.isBreak(positions, i)) {
61526
+ lastValidIndex = -1;
61527
+ continue;
61528
+ }
61529
+ if (lastValidIndex !== -1) {
61530
+ segments.push(positions[lastValidIndex], positions[lastValidIndex + 1], positions[lastValidIndex + 2], positions[i], positions[i + 1], positions[i + 2]);
61531
+ }
61532
+ lastValidIndex = i;
61533
+ }
61534
+ }
61535
+ if (segments.length === 0)
61536
+ return null;
61537
+ lineGeometry.setPositions(segments);
61538
+ return lineGeometry;
61539
+ }
61540
+ }
61541
+
61542
+ ///////////////////////////////////////////////////////////////////////////////
61543
+ // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance").
61544
+ // All rights reserved.
61545
+ //
61546
+ // This software and its documentation and related materials are owned by
61547
+ // the Alliance. The software may only be incorporated into application
61548
+ // programs owned by members of the Alliance, subject to a signed
61549
+ // Membership Agreement and Supplemental Software License Agreement with the
61550
+ // Alliance. The structure and organization of this software are the valuable
61551
+ // trade secrets of the Alliance and its suppliers. The software is also
61552
+ // protected by copyright law and international treaty provisions. Application
61553
+ // programs incorporating this software must include the following statement
61554
+ // with their copyright notices:
61555
+ //
61556
+ // This application incorporates Open Design Alliance software pursuant to a
61557
+ // license agreement with Open Design Alliance.
61558
+ // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance.
61559
+ // All rights reserved.
61560
+ //
61561
+ // By use of this software, its documentation or related materials, you
61562
+ // acknowledge and accept the above terms.
61563
+ ///////////////////////////////////////////////////////////////////////////////
61564
+ class HighlighterComponent {
61565
+ constructor(viewer) {
61566
+ this.geometryEnd = () => {
61567
+ const { facesColor, facesTransparancy, edgesColor } = this.viewer.options;
61568
+ this.highlightMaterial = new MeshBasicMaterial({
61569
+ color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
61570
+ transparent: true,
61571
+ opacity: (255 - facesTransparancy) / 255,
61572
+ depthTest: false,
61573
+ depthWrite: false,
61574
+ });
61575
+ this.outlineMaterial = new LineMaterial({
61576
+ color: new Color(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255),
61577
+ linewidth: 1.5,
61578
+ depthTest: false,
61579
+ depthWrite: false,
61580
+ resolution: new Vector2(window.innerWidth, window.innerHeight),
61581
+ });
61582
+ this.highlightLineMaterial = new LineBasicMaterial({
61583
+ color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
61584
+ depthTest: false,
61585
+ depthWrite: false,
61586
+ });
61587
+ this.highlightLineGlowMaterial = new LineMaterial({
61588
+ color: new Color(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255),
61589
+ linewidth: 5,
61590
+ transparent: true,
61591
+ opacity: 0.8,
61592
+ depthTest: true,
61593
+ depthWrite: true,
61594
+ resolution: new Vector2(window.innerWidth, window.innerHeight),
61595
+ });
61596
+ };
61597
+ this.optionsChange = () => {
61598
+ const { facesColor, facesTransparancy, edgesColor } = this.viewer.options;
61599
+ this.highlightMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
61600
+ this.highlightMaterial.opacity = (255 - facesTransparancy) / 255;
61601
+ this.outlineMaterial.color.setRGB(edgesColor.r / 255, edgesColor.g / 255, edgesColor.b / 255);
61602
+ this.highlightLineMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
61603
+ this.highlightLineGlowMaterial.color.setRGB(facesColor.r / 255, facesColor.g / 255, facesColor.b / 255);
61604
+ this.viewer.update();
61605
+ };
61606
+ this.viewer = viewer;
61607
+ this.viewer.addEventListener("databasechunk", this.geometryEnd);
61608
+ this.viewer.addEventListener("optionschange", this.optionsChange);
61609
+ this.viewer.addEventListener("resize", this.viewerResize);
61610
+ this.geometryEnd();
61611
+ }
61612
+ dispose() {
61613
+ this.viewer.removeEventListener("databasechunk", this.geometryEnd);
61614
+ this.viewer.removeEventListener("optionschange", this.optionsChange);
61615
+ this.viewer.removeEventListener("resize", this.viewerResize);
61616
+ }
61617
+ highlight(object) {
61618
+ if (object.isHighlighted)
61619
+ return;
61620
+ if (object.isLine || object.isLineSegments) {
61621
+ const positions = object.geometry.attributes.position.array;
61622
+ const indices = object.geometry.index ? object.geometry.index.array : null;
61623
+ const lineGeometry = indices
61624
+ ? HighlighterUtils.fromIndexedLine(positions, indices)
61625
+ : HighlighterUtils.fromNonIndexedLine(positions, object.isLineSegments);
61626
+ const wireframe = new Wireframe(lineGeometry, this.highlightLineGlowMaterial);
61627
+ wireframe.position.copy(object.position);
61628
+ wireframe.rotation.copy(object.rotation);
61629
+ wireframe.scale.copy(object.scale);
61630
+ object.parent.add(wireframe);
61631
+ object.userData.highlightwireframe = wireframe;
61632
+ object.userData.originalMaterial = object.material;
61633
+ object.material = this.highlightLineMaterial;
61634
+ object.isHighlighted = true;
61635
+ }
61636
+ else if (object.isMesh) {
61637
+ const edgesGeometry = new EdgesGeometry(object.geometry, 30);
61638
+ const lineGeometry = new LineSegmentsGeometry().fromEdgesGeometry(edgesGeometry);
61639
+ const wireframe = new Wireframe(lineGeometry, this.outlineMaterial);
61640
+ wireframe.position.copy(object.position);
61641
+ wireframe.rotation.copy(object.rotation);
61642
+ wireframe.scale.copy(object.scale);
61643
+ object.parent.add(wireframe);
61644
+ object.userData.highlightwireframe = wireframe;
61645
+ object.userData.originalMaterial = object.material;
61646
+ object.material = this.highlightMaterial;
61647
+ object.isHighlighted = true;
61648
+ }
61649
+ }
61650
+ unhighlight(object) {
61651
+ if (!object.isHighlighted)
61652
+ return;
61653
+ object.isHighlighted = false;
61654
+ object.material = object.userData.originalMaterial;
61655
+ object.userData.highlightwireframe.removeFromParent();
61656
+ delete object.userData.originalMaterial;
61657
+ delete object.userData.highlightwireframe;
61658
+ }
61659
+ viewerResize(event) {
61660
+ if (!this.outlineMaterial)
61661
+ return;
61662
+ this.outlineMaterial.resolution.set(event.width, event.height);
61663
+ }
61664
+ }
61665
+
60735
61666
  class WCSHelper extends Object3D {
60736
61667
  constructor(camera) {
60737
61668
  super();
@@ -60929,10 +61860,10 @@ void main() {
60929
61860
  components.registerComponent("ExtentsComponent", (viewer) => new ExtentsComponent(viewer));
60930
61861
  components.registerComponent("CameraComponent", (viewer) => new CameraComponent(viewer));
60931
61862
  components.registerComponent("BackgroundComponent", (viewer) => new BackgroundComponent(viewer));
60932
- components.registerComponent("RoomEnvironmentComponent", (viewer) => new RoomEnvironmentComponent(viewer));
60933
61863
  components.registerComponent("LightComponent", (viewer) => new LightComponent(viewer));
60934
61864
  components.registerComponent("ResizeCanvasComponent", (viewer) => new ResizeCanvasComponent(viewer));
60935
61865
  components.registerComponent("RenderLoopComponent", (viewer) => new RenderLoopComponent(viewer));
61866
+ components.registerComponent("HighlighterComponent", (viewer) => new HighlighterComponent(viewer));
60936
61867
  components.registerComponent("SelectionComponent", (viewer) => new SelectionComponent(viewer));
60937
61868
  components.registerComponent("WCSHelperComponent", (viewer) => new WCSHelperComponent(viewer));
60938
61869
 
@@ -77966,7 +78897,7 @@ void main() {
77966
78897
  let wcsPoints = this._ref.getAttr("wcsPoints");
77967
78898
  if (!wcsPoints) {
77968
78899
  wcsPoints = [];
77969
- let points = this._ref.points();
78900
+ const points = this._ref.points();
77970
78901
  let wcsPoint;
77971
78902
  for (let i = 0; i < points.length; i += 2) {
77972
78903
  wcsPoint = this._worldTransformer.screenToWorld({
@@ -77995,7 +78926,7 @@ void main() {
77995
78926
  const wcsPoints = [];
77996
78927
  params.points.forEach((point => {
77997
78928
  konvaPoints.push(point.x, point.y);
77998
- let wcsPoint = this._worldTransformer.screenToWorld({
78929
+ const wcsPoint = this._worldTransformer.screenToWorld({
77999
78930
  x: point.x,
78000
78931
  y: point.y
78001
78932
  });
@@ -78023,8 +78954,8 @@ void main() {
78023
78954
  }));
78024
78955
  this._ref.on("transformend", (e => {
78025
78956
  const absoluteTransform = this._ref.getAbsoluteTransform();
78026
- let wcsPoints = [];
78027
- let points = this._ref.points();
78957
+ const wcsPoints = [];
78958
+ const points = this._ref.points();
78028
78959
  let wcsPoint;
78029
78960
  for (let i = 0; i < points.length; i += 2) {
78030
78961
  const position = absoluteTransform.point({
@@ -78045,8 +78976,8 @@ void main() {
78045
78976
  }));
78046
78977
  this._ref.on("dragend", (e => {
78047
78978
  const absoluteTransform = this._ref.getAbsoluteTransform();
78048
- let wcsPoints = [];
78049
- let points = this._ref.points();
78979
+ const wcsPoints = [];
78980
+ const points = this._ref.points();
78050
78981
  let wcsPoint;
78051
78982
  for (let i = 0; i < points.length; i += 2) {
78052
78983
  const position = absoluteTransform.point({
@@ -78134,17 +79065,17 @@ void main() {
78134
79065
  }
78135
79066
  addPoints(points) {
78136
79067
  let newPoints = this._ref.points();
78137
- let wcsPoints = this._ref.getAttr("wcsPoints");
79068
+ const wcsPoints = this._ref.getAttr("wcsPoints");
78138
79069
  points.forEach((point => {
78139
79070
  newPoints = newPoints.concat([ point.x, point.y ]);
78140
- let wcsPoint = this._worldTransformer.screenToWorld(point);
79071
+ const wcsPoint = this._worldTransformer.screenToWorld(point);
78141
79072
  wcsPoints.push(wcsPoint);
78142
79073
  }));
78143
79074
  this._ref.points(newPoints);
78144
79075
  }
78145
79076
  updateScreenCoordinates() {
78146
- let wcsPoints = this._ref.getAttr("wcsPoints");
78147
- let points = [];
79077
+ const wcsPoints = this._ref.getAttr("wcsPoints");
79078
+ const points = [];
78148
79079
  let invert = this._ref.getAbsoluteTransform().copy();
78149
79080
  invert = invert.invert();
78150
79081
  wcsPoints.forEach((point => {
@@ -78303,7 +79234,7 @@ void main() {
78303
79234
  this._ref.fontSize(size);
78304
79235
  }
78305
79236
  updateScreenCoordinates() {
78306
- let screenPositionStart = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
79237
+ const screenPositionStart = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
78307
79238
  let invert = this._ref.getStage().getAbsoluteTransform().copy();
78308
79239
  invert = invert.invert();
78309
79240
  const positionStart = invert.point(screenPositionStart);
@@ -78519,8 +79450,8 @@ void main() {
78519
79450
  return this._ref.strokeWidth();
78520
79451
  }
78521
79452
  updateScreenCoordinates() {
78522
- let screenPositionStart = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
78523
- let screenPositionEnd = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsEnd"));
79453
+ const screenPositionStart = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
79454
+ const screenPositionEnd = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsEnd"));
78524
79455
  let invert = this._ref.getStage().getAbsoluteTransform().copy();
78525
79456
  invert = invert.invert();
78526
79457
  const positionStart = invert.point(screenPositionStart);
@@ -78758,9 +79689,9 @@ void main() {
78758
79689
  this._ref = null;
78759
79690
  }
78760
79691
  updateScreenCoordinates() {
78761
- let screenPosition = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsPosition"));
78762
- let radiusX = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsRadiusX"));
78763
- let radiusY = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsRadiusY"));
79692
+ const screenPosition = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsPosition"));
79693
+ const radiusX = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsRadiusX"));
79694
+ const radiusY = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsRadiusY"));
78764
79695
  let invert = this._ref.getStage().getAbsoluteTransform().copy();
78765
79696
  invert = invert.invert();
78766
79697
  const position = invert.point({
@@ -78945,8 +79876,8 @@ void main() {
78945
79876
  }));
78946
79877
  }
78947
79878
  updateScreenCoordinates() {
78948
- let screenStartPoint = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
78949
- let screenEndPoint = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsEnd"));
79879
+ const screenStartPoint = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
79880
+ const screenEndPoint = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsEnd"));
78950
79881
  let invert = this._ref.getAbsoluteTransform().copy();
78951
79882
  invert = invert.invert();
78952
79883
  const startPoint = invert.point({
@@ -79184,8 +80115,8 @@ void main() {
79184
80115
  this._ref.setAttr("wcsEnd", wcsRightLowerPoint);
79185
80116
  }
79186
80117
  updateScreenCoordinates() {
79187
- let screenPositionStart = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
79188
- let screenPositionEnd = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsEnd"));
80118
+ const screenPositionStart = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
80119
+ const screenPositionEnd = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsEnd"));
79189
80120
  let invert = this._ref.getStage().getAbsoluteTransform().copy();
79190
80121
  invert = invert.invert();
79191
80122
  const positionStart = invert.point(screenPositionStart);
@@ -79483,8 +80414,8 @@ void main() {
79483
80414
  this._ref.strokeWidth(size);
79484
80415
  }
79485
80416
  updateScreenCoordinates() {
79486
- let screenPositionStart = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
79487
- let screenPositionEnd = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsEnd"));
80417
+ const screenPositionStart = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsStart"));
80418
+ const screenPositionEnd = this._worldTransformer.worldToScreen(this._ref.getAttr("wcsEnd"));
79488
80419
  let invert = this._ref.getStage().getAbsoluteTransform().copy();
79489
80420
  invert = invert.invert();
79490
80421
  const positionStart = invert.point(screenPositionStart);
@@ -80777,6 +81708,9 @@ void main() {
80777
81708
  this.setActiveDragger(dragger.name);
80778
81709
  }
80779
81710
  }
81711
+ getComponent(name) {
81712
+ return this._components.find((component) => component.name === name);
81713
+ }
80780
81714
  is3D() {
80781
81715
  return true;
80782
81716
  }
@@ -80806,9 +81740,6 @@ void main() {
80806
81740
  executeCommand(id, ...args) {
80807
81741
  return commands.executeCommand(id, this, ...args);
80808
81742
  }
80809
- getComponent(name) {
80810
- return this._components.find((component) => component.name === name);
80811
- }
80812
81743
  drawViewpoint(viewpoint) {
80813
81744
  var _a, _b, _c;
80814
81745
  if (!this.renderer)