vim-web 0.6.0-dev.1 → 0.6.0-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vim-web.js CHANGED
@@ -894,7 +894,7 @@ function requireDist$2() {
894
894
  return dist$3;
895
895
  }
896
896
  var distExports$2 = requireDist$2();
897
- const MAX_VIMS = 256;
897
+ const MAX_VIMS = 255;
898
898
  let VimCollection$1 = class VimCollection {
899
899
  constructor() {
900
900
  // Sparse storage indexed by stable ID
@@ -48649,6 +48649,266 @@ class SimpleInstanceSubmesh {
48649
48649
  return this.mesh;
48650
48650
  }
48651
48651
  }
48652
+ const MARKER_VIM_INDEX = 255;
48653
+ function packPickingId(vimIndex, elementIndex) {
48654
+ return (vimIndex & 255) << 24 | elementIndex & 16777215;
48655
+ }
48656
+ function unpackPickingId(packedId) {
48657
+ return {
48658
+ vimIndex: packedId >>> 24,
48659
+ elementIndex: packedId & 16777215
48660
+ };
48661
+ }
48662
+ class GpuPickResult {
48663
+ constructor(elementIndex, vimIndex, worldPosition, worldNormal, vim, marker) {
48664
+ /** The element index in the vim (or marker index if vimIndex === MARKER_VIM_INDEX) */
48665
+ __publicField(this, "elementIndex");
48666
+ /** The vim index identifying which vim the element belongs to (255 = marker) */
48667
+ __publicField(this, "vimIndex");
48668
+ /** The world position of the hit */
48669
+ __publicField(this, "worldPosition");
48670
+ /** The world normal at the hit point */
48671
+ __publicField(this, "worldNormal");
48672
+ /** Reference to the vim containing the element */
48673
+ __publicField(this, "_vim");
48674
+ /** Reference to the marker if this is a marker hit */
48675
+ __publicField(this, "_marker");
48676
+ this.elementIndex = elementIndex;
48677
+ this.vimIndex = vimIndex;
48678
+ this.worldPosition = worldPosition;
48679
+ this.worldNormal = worldNormal;
48680
+ this._vim = vim;
48681
+ this._marker = marker;
48682
+ }
48683
+ /**
48684
+ * The object property for IRaycastResult interface.
48685
+ * Returns the Element3D or Marker for the picked object.
48686
+ */
48687
+ get object() {
48688
+ return this._marker ?? this.getElement();
48689
+ }
48690
+ /**
48691
+ * Gets the Element3D object for the picked element.
48692
+ * @returns The Element3D object, or undefined if not found or if this is a marker hit
48693
+ */
48694
+ getElement() {
48695
+ var _a3;
48696
+ return (_a3 = this._vim) == null ? void 0 : _a3.getElementFromIndex(this.elementIndex);
48697
+ }
48698
+ /**
48699
+ * Gets the Marker object if this is a marker hit.
48700
+ * @returns The Marker object, or undefined if this is an element hit
48701
+ */
48702
+ getMarker() {
48703
+ return this._marker;
48704
+ }
48705
+ }
48706
+ class GpuPicker {
48707
+ constructor(renderer, camera2, scene, vims, section, width, height) {
48708
+ __publicField(this, "_renderer");
48709
+ __publicField(this, "_camera");
48710
+ __publicField(this, "_scene");
48711
+ __publicField(this, "_vims");
48712
+ __publicField(this, "_markers");
48713
+ __publicField(this, "_section");
48714
+ __publicField(this, "_renderTarget");
48715
+ __publicField(this, "_pickingMaterial");
48716
+ __publicField(this, "_readBuffer");
48717
+ // Debug visualization
48718
+ __publicField(this, "debug", true);
48719
+ __publicField(this, "_debugSphere");
48720
+ __publicField(this, "_debugLine");
48721
+ this._renderer = renderer;
48722
+ this._camera = camera2;
48723
+ this._scene = scene;
48724
+ this._vims = vims;
48725
+ this._section = section;
48726
+ this._renderTarget = new WebGLRenderTarget(width, height, {
48727
+ minFilter: NearestFilter,
48728
+ magFilter: NearestFilter,
48729
+ format: RGBAFormat,
48730
+ type: FloatType,
48731
+ depthBuffer: true
48732
+ });
48733
+ this._pickingMaterial = new PickingMaterial();
48734
+ this._readBuffer = new Float32Array(4);
48735
+ }
48736
+ /**
48737
+ * Sets the GizmoMarkers reference for marker picking.
48738
+ * Must be called after gizmos are initialized.
48739
+ */
48740
+ setMarkers(markers) {
48741
+ this._markers = markers;
48742
+ }
48743
+ /**
48744
+ * Updates the render target size to match viewport.
48745
+ */
48746
+ setSize(width, height) {
48747
+ this._renderTarget.setSize(width, height);
48748
+ }
48749
+ /**
48750
+ * Performs GPU picking at the given screen coordinates.
48751
+ * Returns a result object with element index, world position, and getElement() method.
48752
+ *
48753
+ * @param screenPos Screen position in 0-1 range (0,0 is top-left)
48754
+ * @returns Pick result with element index, world position, and getElement(), or undefined if no hit
48755
+ */
48756
+ pick(screenPos) {
48757
+ var _a3;
48758
+ const camera2 = this._camera.three;
48759
+ camera2.updateMatrixWorld(true);
48760
+ const currentRenderTarget = this._renderer.getRenderTarget();
48761
+ const currentOverrideMaterial = this._scene.threeScene.overrideMaterial;
48762
+ const currentBackground = this._scene.threeScene.background;
48763
+ this._pickingMaterial.updateCamera(camera2);
48764
+ if (this._section.active) {
48765
+ this._pickingMaterial.clippingPlanes = this._section.clippingPlanes;
48766
+ } else {
48767
+ this._pickingMaterial.clippingPlanes = [];
48768
+ }
48769
+ this._scene.threeScene.background = null;
48770
+ this._scene.threeScene.overrideMaterial = this._pickingMaterial.material;
48771
+ camera2.layers.disable(1);
48772
+ this._renderer.setRenderTarget(this._renderTarget);
48773
+ this._renderer.setClearColor(0, 0);
48774
+ this._renderer.clear();
48775
+ this._renderer.render(this._scene.threeScene, camera2);
48776
+ this._renderer.setRenderTarget(currentRenderTarget);
48777
+ camera2.layers.enable(1);
48778
+ this._scene.threeScene.overrideMaterial = currentOverrideMaterial;
48779
+ this._scene.threeScene.background = currentBackground;
48780
+ const pixelX = Math.floor(screenPos.x * this._renderTarget.width);
48781
+ const pixelY = Math.floor((1 - screenPos.y) * this._renderTarget.height);
48782
+ this._renderer.readRenderTargetPixels(
48783
+ this._renderTarget,
48784
+ pixelX,
48785
+ pixelY,
48786
+ 1,
48787
+ 1,
48788
+ this._readBuffer
48789
+ );
48790
+ const depth = this._readBuffer[1];
48791
+ const normalX = this._readBuffer[2];
48792
+ const normalY = this._readBuffer[3];
48793
+ if (depth <= 0) {
48794
+ return void 0;
48795
+ }
48796
+ const dataView = new DataView(this._readBuffer.buffer);
48797
+ const packedId = dataView.getUint32(0, true);
48798
+ const { vimIndex, elementIndex } = unpackPickingId(packedId);
48799
+ const normalZ = Math.sqrt(Math.max(0, 1 - normalX * normalX - normalY * normalY));
48800
+ const worldNormal = new Vector3(normalX, normalY, normalZ).normalize();
48801
+ const worldPosition = this.reconstructWorldPosition(screenPos, depth, camera2);
48802
+ if (vimIndex === MARKER_VIM_INDEX) {
48803
+ const marker = (_a3 = this._markers) == null ? void 0 : _a3.getMarkerFromIndex(elementIndex);
48804
+ const result2 = new GpuPickResult(elementIndex, vimIndex, worldPosition, worldNormal, void 0, marker);
48805
+ if (this.debug) {
48806
+ this.showDebugVisuals(result2);
48807
+ }
48808
+ return result2;
48809
+ }
48810
+ const vim = this._vims.getFromId(vimIndex);
48811
+ const result = new GpuPickResult(elementIndex, vimIndex, worldPosition, worldNormal, vim);
48812
+ if (this.debug) {
48813
+ this.showDebugVisuals(result);
48814
+ }
48815
+ return result;
48816
+ }
48817
+ /**
48818
+ * Shows debug visuals (sphere at hit point, line showing normal direction).
48819
+ */
48820
+ showDebugVisuals(result) {
48821
+ this.clearDebugVisuals();
48822
+ const sphereGeometry = new SphereGeometry(0.5, 16, 16);
48823
+ const sphereMaterial = new MeshBasicMaterial({ color: 16711680 });
48824
+ this._debugSphere = new Mesh(sphereGeometry, sphereMaterial);
48825
+ this._debugSphere.position.copy(result.worldPosition);
48826
+ this._debugSphere.layers.set(1);
48827
+ this._scene.threeScene.add(this._debugSphere);
48828
+ const lineLength = 2;
48829
+ const lineStart = result.worldPosition.clone();
48830
+ const lineEnd = result.worldPosition.clone().add(result.worldNormal.clone().multiplyScalar(lineLength));
48831
+ const lineGeometry = new BufferGeometry().setFromPoints([lineStart, lineEnd]);
48832
+ const lineMaterial = new LineBasicMaterial({ color: 65280, linewidth: 2 });
48833
+ this._debugLine = new Line(lineGeometry, lineMaterial);
48834
+ this._debugLine.layers.set(1);
48835
+ this._scene.threeScene.add(this._debugLine);
48836
+ this._renderer.domElement.dispatchEvent(new Event("needsUpdate"));
48837
+ }
48838
+ /**
48839
+ * Reconstructs world position from screen coordinates and depth value.
48840
+ */
48841
+ reconstructWorldPosition(screenPos, depth, camera2) {
48842
+ const ndcX = screenPos.x * 2 - 1;
48843
+ const ndcY = (1 - screenPos.y) * 2 - 1;
48844
+ const rayEnd = new Vector3(ndcX, ndcY, 1).unproject(camera2);
48845
+ const rayDir = rayEnd.sub(camera2.position).normalize();
48846
+ const cameraDir = new Vector3();
48847
+ camera2.getWorldDirection(cameraDir);
48848
+ const t = depth / rayDir.dot(cameraDir);
48849
+ const worldPos = camera2.position.clone().add(rayDir.clone().multiplyScalar(t));
48850
+ return worldPos;
48851
+ }
48852
+ /**
48853
+ * Removes debug visuals (sphere and normal line) from the scene.
48854
+ */
48855
+ clearDebugVisuals() {
48856
+ if (this._debugSphere) {
48857
+ this._scene.threeScene.remove(this._debugSphere);
48858
+ this._debugSphere.geometry.dispose();
48859
+ this._debugSphere.material.dispose();
48860
+ this._debugSphere = void 0;
48861
+ }
48862
+ if (this._debugLine) {
48863
+ this._scene.threeScene.remove(this._debugLine);
48864
+ this._debugLine.geometry.dispose();
48865
+ this._debugLine.material.dispose();
48866
+ this._debugLine = void 0;
48867
+ }
48868
+ }
48869
+ /**
48870
+ * Raycasts from camera to the screen position to find the first object hit.
48871
+ * Implements IRaycaster interface.
48872
+ * @param position - Screen position in 0-1 range (0,0 is top-left)
48873
+ * @returns A promise that resolves to the raycast result, or undefined if no hit
48874
+ */
48875
+ raycastFromScreen(position) {
48876
+ return Promise.resolve(this.pick(position));
48877
+ }
48878
+ /**
48879
+ * Raycasts from camera towards a world position to find the first object hit.
48880
+ * Implements IRaycaster interface.
48881
+ * @param position - The world position to raycast towards
48882
+ * @returns A promise that resolves to the raycast result, or undefined if no hit
48883
+ */
48884
+ raycastFromWorld(position) {
48885
+ const screenPos = this.worldToScreen(position);
48886
+ if (!screenPos) return Promise.resolve(void 0);
48887
+ return Promise.resolve(this.pick(screenPos));
48888
+ }
48889
+ /**
48890
+ * Converts a world position to screen coordinates (0-1 range).
48891
+ * @param worldPos - The world position to convert
48892
+ * @returns Screen position in 0-1 range, or undefined if behind camera
48893
+ */
48894
+ worldToScreen(worldPos) {
48895
+ const camera2 = this._camera.three;
48896
+ camera2.updateMatrixWorld(true);
48897
+ const ndc = worldPos.clone().project(camera2);
48898
+ if (ndc.z > 1) return void 0;
48899
+ const screenX = (ndc.x + 1) / 2;
48900
+ const screenY = (1 - ndc.y) / 2;
48901
+ return new Vector2(screenX, screenY);
48902
+ }
48903
+ /**
48904
+ * Disposes of all resources.
48905
+ */
48906
+ dispose() {
48907
+ this.clearDebugVisuals();
48908
+ this._renderTarget.dispose();
48909
+ this._pickingMaterial.dispose();
48910
+ }
48911
+ }
48652
48912
  class GizmoMarkers {
48653
48913
  /**
48654
48914
  * Constructs the marker manager and sets up an initial instanced mesh.
@@ -48692,6 +48952,12 @@ class GizmoMarkers {
48692
48952
  mesh.count = 0;
48693
48953
  mesh.frustumCulled = false;
48694
48954
  mesh.layers.enableAll();
48955
+ const packedIdArray = new Uint32Array(capacity);
48956
+ const packedIdAttr = new InstancedBufferAttribute(packedIdArray, 1);
48957
+ mesh.geometry.setAttribute("packedId", packedIdAttr);
48958
+ const ignoreArray = new Float32Array(capacity);
48959
+ const ignoreAttr = new InstancedBufferAttribute(ignoreArray, 1);
48960
+ mesh.geometry.setAttribute("ignore", ignoreAttr);
48695
48961
  this._viewer.renderer.add(mesh);
48696
48962
  return mesh;
48697
48963
  }
@@ -48701,12 +48967,20 @@ class GizmoMarkers {
48701
48967
  resizeMesh() {
48702
48968
  const larger = this.createMesh(this._mesh, this._mesh.count * 2);
48703
48969
  larger.count = this._mesh.count;
48970
+ const oldPackedId = this._mesh.geometry.getAttribute("packedId");
48971
+ const oldIgnore = this._mesh.geometry.getAttribute("ignore");
48972
+ const newPackedId = larger.geometry.getAttribute("packedId");
48973
+ const newIgnore = larger.geometry.getAttribute("ignore");
48704
48974
  for (let i = 0; i < this._mesh.count; i++) {
48705
48975
  this._mesh.getMatrixAt(i, this._reusableMatrix);
48706
48976
  larger.setMatrixAt(i, this._reusableMatrix);
48977
+ newPackedId.setX(i, oldPackedId.getX(i));
48978
+ newIgnore.setX(i, oldIgnore.getX(i));
48707
48979
  const sub = new SimpleInstanceSubmesh(larger, i);
48708
48980
  this._markers[i].updateMesh(sub);
48709
48981
  }
48982
+ newPackedId.needsUpdate = true;
48983
+ newIgnore.needsUpdate = true;
48710
48984
  this._viewer.renderer.remove(this._mesh);
48711
48985
  this._mesh = larger;
48712
48986
  }
@@ -48720,8 +48994,12 @@ class GizmoMarkers {
48720
48994
  if (this._mesh.count === this._mesh.instanceMatrix.count) {
48721
48995
  this.resizeMesh();
48722
48996
  }
48997
+ const markerIndex = this._mesh.count;
48723
48998
  this._mesh.count += 1;
48724
- const sub = new SimpleInstanceSubmesh(this._mesh, this._mesh.count - 1);
48999
+ const packedIdAttr = this._mesh.geometry.getAttribute("packedId");
49000
+ packedIdAttr.setX(markerIndex, packPickingId(MARKER_VIM_INDEX, markerIndex));
49001
+ packedIdAttr.needsUpdate = true;
49002
+ const sub = new SimpleInstanceSubmesh(this._mesh, markerIndex);
48725
49003
  const marker = new Marker(this._viewer, sub);
48726
49004
  marker.position = position;
48727
49005
  this._markers.push(marker);
@@ -48742,7 +49020,10 @@ class GizmoMarkers {
48742
49020
  this._mesh.getMatrixAt(fromIndex, this._reusableMatrix);
48743
49021
  this._mesh.setMatrixAt(destIndex, this._reusableMatrix);
48744
49022
  this._mesh.instanceMatrix.needsUpdate = true;
48745
- const sub = new SimpleInstanceSubmesh(this._mesh, marker.index);
49023
+ const packedIdAttr = this._mesh.geometry.getAttribute("packedId");
49024
+ packedIdAttr.setX(destIndex, packPickingId(MARKER_VIM_INDEX, destIndex));
49025
+ packedIdAttr.needsUpdate = true;
49026
+ const sub = new SimpleInstanceSubmesh(this._mesh, destIndex);
48746
49027
  lastMarker.updateMesh(sub);
48747
49028
  }
48748
49029
  this._markers.length -= 1;
@@ -53643,238 +53924,6 @@ class Gizmos {
53643
53924
  this.axes.dispose();
53644
53925
  }
53645
53926
  }
53646
- function packPickingId(vimIndex, elementIndex) {
53647
- return (vimIndex & 255) << 24 | elementIndex & 16777215;
53648
- }
53649
- function unpackPickingId(packedId) {
53650
- return {
53651
- vimIndex: packedId >>> 24,
53652
- elementIndex: packedId & 16777215
53653
- };
53654
- }
53655
- class GpuPickResult {
53656
- constructor(elementIndex, vimIndex, worldPosition, worldNormal, vim) {
53657
- /** The element index in the vim */
53658
- __publicField(this, "elementIndex");
53659
- /** The vim index identifying which vim the element belongs to */
53660
- __publicField(this, "vimIndex");
53661
- /** The world position of the hit */
53662
- __publicField(this, "worldPosition");
53663
- /** The world normal at the hit point */
53664
- __publicField(this, "worldNormal");
53665
- /** Reference to the vim containing the element */
53666
- __publicField(this, "_vim");
53667
- this.elementIndex = elementIndex;
53668
- this.vimIndex = vimIndex;
53669
- this.worldPosition = worldPosition;
53670
- this.worldNormal = worldNormal;
53671
- this._vim = vim;
53672
- }
53673
- /**
53674
- * The object property for IRaycastResult interface.
53675
- * Returns the Element3D for the picked element.
53676
- */
53677
- get object() {
53678
- return this.getElement();
53679
- }
53680
- /**
53681
- * Gets the Element3D object for the picked element.
53682
- * @returns The Element3D object, or undefined if not found
53683
- */
53684
- getElement() {
53685
- var _a3;
53686
- return (_a3 = this._vim) == null ? void 0 : _a3.getElementFromIndex(this.elementIndex);
53687
- }
53688
- }
53689
- class GpuPicker {
53690
- constructor(renderer, camera2, scene, vims, section, width, height) {
53691
- __publicField(this, "_renderer");
53692
- __publicField(this, "_camera");
53693
- __publicField(this, "_scene");
53694
- __publicField(this, "_vims");
53695
- __publicField(this, "_section");
53696
- __publicField(this, "_renderTarget");
53697
- __publicField(this, "_pickingMaterial");
53698
- __publicField(this, "_readBuffer");
53699
- // Debug visualization
53700
- __publicField(this, "debug", true);
53701
- __publicField(this, "_debugSphere");
53702
- __publicField(this, "_debugLine");
53703
- this._renderer = renderer;
53704
- this._camera = camera2;
53705
- this._scene = scene;
53706
- this._vims = vims;
53707
- this._section = section;
53708
- this._renderTarget = new WebGLRenderTarget(width, height, {
53709
- minFilter: NearestFilter,
53710
- magFilter: NearestFilter,
53711
- format: RGBAFormat,
53712
- type: FloatType,
53713
- depthBuffer: true
53714
- });
53715
- this._pickingMaterial = new PickingMaterial();
53716
- this._readBuffer = new Float32Array(4);
53717
- }
53718
- /**
53719
- * Updates the render target size to match viewport.
53720
- */
53721
- setSize(width, height) {
53722
- this._renderTarget.setSize(width, height);
53723
- }
53724
- /**
53725
- * Performs GPU picking at the given screen coordinates.
53726
- * Returns a result object with element index, world position, and getElement() method.
53727
- *
53728
- * @param screenPos Screen position in 0-1 range (0,0 is top-left)
53729
- * @returns Pick result with element index, world position, and getElement(), or undefined if no hit
53730
- */
53731
- pick(screenPos) {
53732
- const camera2 = this._camera.three;
53733
- camera2.updateMatrixWorld(true);
53734
- const currentRenderTarget = this._renderer.getRenderTarget();
53735
- const currentOverrideMaterial = this._scene.threeScene.overrideMaterial;
53736
- const currentBackground = this._scene.threeScene.background;
53737
- this._pickingMaterial.updateCamera(camera2);
53738
- if (this._section.active) {
53739
- this._pickingMaterial.clippingPlanes = this._section.clippingPlanes;
53740
- } else {
53741
- this._pickingMaterial.clippingPlanes = [];
53742
- }
53743
- this._scene.threeScene.background = null;
53744
- this._scene.threeScene.overrideMaterial = this._pickingMaterial.material;
53745
- camera2.layers.disable(1);
53746
- this._renderer.setRenderTarget(this._renderTarget);
53747
- this._renderer.setClearColor(0, 0);
53748
- this._renderer.clear();
53749
- this._renderer.render(this._scene.threeScene, camera2);
53750
- this._renderer.setRenderTarget(currentRenderTarget);
53751
- camera2.layers.enable(1);
53752
- this._scene.threeScene.overrideMaterial = currentOverrideMaterial;
53753
- this._scene.threeScene.background = currentBackground;
53754
- const pixelX = Math.floor(screenPos.x * this._renderTarget.width);
53755
- const pixelY = Math.floor((1 - screenPos.y) * this._renderTarget.height);
53756
- this._renderer.readRenderTargetPixels(
53757
- this._renderTarget,
53758
- pixelX,
53759
- pixelY,
53760
- 1,
53761
- 1,
53762
- this._readBuffer
53763
- );
53764
- const depth = this._readBuffer[1];
53765
- const normalX = this._readBuffer[2];
53766
- const normalY = this._readBuffer[3];
53767
- if (depth <= 0) {
53768
- return void 0;
53769
- }
53770
- const dataView = new DataView(this._readBuffer.buffer);
53771
- const packedId = dataView.getUint32(0, true);
53772
- const { vimIndex, elementIndex } = unpackPickingId(packedId);
53773
- const normalZ = Math.sqrt(Math.max(0, 1 - normalX * normalX - normalY * normalY));
53774
- const worldNormal = new Vector3(normalX, normalY, normalZ).normalize();
53775
- const worldPosition = this.reconstructWorldPosition(screenPos, depth, camera2);
53776
- const vim = this._vims.getFromId(vimIndex);
53777
- const result = new GpuPickResult(elementIndex, vimIndex, worldPosition, worldNormal, vim);
53778
- if (this.debug) {
53779
- this.showDebugVisuals(result);
53780
- }
53781
- return result;
53782
- }
53783
- /**
53784
- * Shows debug visuals (sphere at hit point, line showing normal direction).
53785
- */
53786
- showDebugVisuals(result) {
53787
- this.clearDebugVisuals();
53788
- const sphereGeometry = new SphereGeometry(0.5, 16, 16);
53789
- const sphereMaterial = new MeshBasicMaterial({ color: 16711680 });
53790
- this._debugSphere = new Mesh(sphereGeometry, sphereMaterial);
53791
- this._debugSphere.position.copy(result.worldPosition);
53792
- this._debugSphere.layers.set(1);
53793
- this._scene.threeScene.add(this._debugSphere);
53794
- const lineLength = 2;
53795
- const lineStart = result.worldPosition.clone();
53796
- const lineEnd = result.worldPosition.clone().add(result.worldNormal.clone().multiplyScalar(lineLength));
53797
- const lineGeometry = new BufferGeometry().setFromPoints([lineStart, lineEnd]);
53798
- const lineMaterial = new LineBasicMaterial({ color: 65280, linewidth: 2 });
53799
- this._debugLine = new Line(lineGeometry, lineMaterial);
53800
- this._debugLine.layers.set(1);
53801
- this._scene.threeScene.add(this._debugLine);
53802
- this._renderer.domElement.dispatchEvent(new Event("needsUpdate"));
53803
- }
53804
- /**
53805
- * Reconstructs world position from screen coordinates and depth value.
53806
- */
53807
- reconstructWorldPosition(screenPos, depth, camera2) {
53808
- const ndcX = screenPos.x * 2 - 1;
53809
- const ndcY = (1 - screenPos.y) * 2 - 1;
53810
- const rayEnd = new Vector3(ndcX, ndcY, 1).unproject(camera2);
53811
- const rayDir = rayEnd.sub(camera2.position).normalize();
53812
- const cameraDir = new Vector3();
53813
- camera2.getWorldDirection(cameraDir);
53814
- const t = depth / rayDir.dot(cameraDir);
53815
- const worldPos = camera2.position.clone().add(rayDir.clone().multiplyScalar(t));
53816
- return worldPos;
53817
- }
53818
- /**
53819
- * Removes debug visuals (sphere and normal line) from the scene.
53820
- */
53821
- clearDebugVisuals() {
53822
- if (this._debugSphere) {
53823
- this._scene.threeScene.remove(this._debugSphere);
53824
- this._debugSphere.geometry.dispose();
53825
- this._debugSphere.material.dispose();
53826
- this._debugSphere = void 0;
53827
- }
53828
- if (this._debugLine) {
53829
- this._scene.threeScene.remove(this._debugLine);
53830
- this._debugLine.geometry.dispose();
53831
- this._debugLine.material.dispose();
53832
- this._debugLine = void 0;
53833
- }
53834
- }
53835
- /**
53836
- * Raycasts from camera to the screen position to find the first object hit.
53837
- * Implements IRaycaster interface.
53838
- * @param position - Screen position in 0-1 range (0,0 is top-left)
53839
- * @returns A promise that resolves to the raycast result, or undefined if no hit
53840
- */
53841
- raycastFromScreen(position) {
53842
- return Promise.resolve(this.pick(position));
53843
- }
53844
- /**
53845
- * Raycasts from camera towards a world position to find the first object hit.
53846
- * Implements IRaycaster interface.
53847
- * @param position - The world position to raycast towards
53848
- * @returns A promise that resolves to the raycast result, or undefined if no hit
53849
- */
53850
- raycastFromWorld(position) {
53851
- const screenPos = this.worldToScreen(position);
53852
- if (!screenPos) return Promise.resolve(void 0);
53853
- return Promise.resolve(this.pick(screenPos));
53854
- }
53855
- /**
53856
- * Converts a world position to screen coordinates (0-1 range).
53857
- * @param worldPos - The world position to convert
53858
- * @returns Screen position in 0-1 range, or undefined if behind camera
53859
- */
53860
- worldToScreen(worldPos) {
53861
- const camera2 = this._camera.three;
53862
- camera2.updateMatrixWorld(true);
53863
- const ndc = worldPos.clone().project(camera2);
53864
- if (ndc.z > 1) return void 0;
53865
- const screenX = (ndc.x + 1) / 2;
53866
- const screenY = (1 - ndc.y) / 2;
53867
- return new Vector2(screenX, screenY);
53868
- }
53869
- /**
53870
- * Disposes of all resources.
53871
- */
53872
- dispose() {
53873
- this.clearDebugVisuals();
53874
- this._renderTarget.dispose();
53875
- this._pickingMaterial.dispose();
53876
- }
53877
- }
53878
53927
  function getAverageBoundingBox(positions, thresholdSpan = 1e3, framingDistanceMultiplier = 2) {
53879
53928
  if (positions.length === 0) {
53880
53929
  return new Box3();
@@ -55023,14 +55072,14 @@ function createAdapter$2(viewer) {
55023
55072
  selectAtPointer: async (pos, add) => {
55024
55073
  const result = await viewer.raycaster.raycastFromScreen(pos);
55025
55074
  if (add) {
55026
- viewer.selection.add(result.object);
55075
+ viewer.selection.add(result == null ? void 0 : result.object);
55027
55076
  } else {
55028
- viewer.selection.select(result.object);
55077
+ viewer.selection.select(result == null ? void 0 : result.object);
55029
55078
  }
55030
55079
  },
55031
55080
  frameAtPointer: async (pos) => {
55032
55081
  const result = await viewer.raycaster.raycastFromScreen(pos);
55033
- viewer.camera.lerp(0.75).frame(result.object ?? "all");
55082
+ viewer.camera.lerp(0.75).frame((result == null ? void 0 : result.object) ?? "all");
55034
55083
  },
55035
55084
  zoom: async (value, pos) => {
55036
55085
  if (pos) {
@@ -56333,7 +56382,7 @@ let Viewer$3 = class Viewer {
56333
56382
  this.environment = new Environment(this.camera, this.renderer, this.materials, this.settings);
56334
56383
  this.selection = createSelection$1();
56335
56384
  const size = this.renderer.renderer.getSize(new Vector2());
56336
- this.raycaster = new GpuPicker(
56385
+ const gpuPicker = new GpuPicker(
56337
56386
  this.renderer.renderer,
56338
56387
  this._camera,
56339
56388
  scene,
@@ -56342,6 +56391,8 @@ let Viewer$3 = class Viewer {
56342
56391
  size.x || 1,
56343
56392
  size.y || 1
56344
56393
  );
56394
+ gpuPicker.setMarkers(this.gizmos.markers);
56395
+ this.raycaster = gpuPicker;
56345
56396
  this.viewport.onResize.sub(() => {
56346
56397
  const size2 = this.viewport.getParentSize();
56347
56398
  this.raycaster.setSize(size2.x, size2.y);