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.
@@ -910,7 +910,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
910
910
  return dist$3;
911
911
  }
912
912
  var distExports$2 = requireDist$2();
913
- const MAX_VIMS = 256;
913
+ const MAX_VIMS = 255;
914
914
  let VimCollection$1 = class VimCollection {
915
915
  constructor() {
916
916
  // Sparse storage indexed by stable ID
@@ -48665,6 +48665,266 @@ void main() {
48665
48665
  return this.mesh;
48666
48666
  }
48667
48667
  }
48668
+ const MARKER_VIM_INDEX = 255;
48669
+ function packPickingId(vimIndex, elementIndex) {
48670
+ return (vimIndex & 255) << 24 | elementIndex & 16777215;
48671
+ }
48672
+ function unpackPickingId(packedId) {
48673
+ return {
48674
+ vimIndex: packedId >>> 24,
48675
+ elementIndex: packedId & 16777215
48676
+ };
48677
+ }
48678
+ class GpuPickResult {
48679
+ constructor(elementIndex, vimIndex, worldPosition, worldNormal, vim, marker) {
48680
+ /** The element index in the vim (or marker index if vimIndex === MARKER_VIM_INDEX) */
48681
+ __publicField(this, "elementIndex");
48682
+ /** The vim index identifying which vim the element belongs to (255 = marker) */
48683
+ __publicField(this, "vimIndex");
48684
+ /** The world position of the hit */
48685
+ __publicField(this, "worldPosition");
48686
+ /** The world normal at the hit point */
48687
+ __publicField(this, "worldNormal");
48688
+ /** Reference to the vim containing the element */
48689
+ __publicField(this, "_vim");
48690
+ /** Reference to the marker if this is a marker hit */
48691
+ __publicField(this, "_marker");
48692
+ this.elementIndex = elementIndex;
48693
+ this.vimIndex = vimIndex;
48694
+ this.worldPosition = worldPosition;
48695
+ this.worldNormal = worldNormal;
48696
+ this._vim = vim;
48697
+ this._marker = marker;
48698
+ }
48699
+ /**
48700
+ * The object property for IRaycastResult interface.
48701
+ * Returns the Element3D or Marker for the picked object.
48702
+ */
48703
+ get object() {
48704
+ return this._marker ?? this.getElement();
48705
+ }
48706
+ /**
48707
+ * Gets the Element3D object for the picked element.
48708
+ * @returns The Element3D object, or undefined if not found or if this is a marker hit
48709
+ */
48710
+ getElement() {
48711
+ var _a3;
48712
+ return (_a3 = this._vim) == null ? void 0 : _a3.getElementFromIndex(this.elementIndex);
48713
+ }
48714
+ /**
48715
+ * Gets the Marker object if this is a marker hit.
48716
+ * @returns The Marker object, or undefined if this is an element hit
48717
+ */
48718
+ getMarker() {
48719
+ return this._marker;
48720
+ }
48721
+ }
48722
+ class GpuPicker {
48723
+ constructor(renderer, camera2, scene, vims, section, width, height) {
48724
+ __publicField(this, "_renderer");
48725
+ __publicField(this, "_camera");
48726
+ __publicField(this, "_scene");
48727
+ __publicField(this, "_vims");
48728
+ __publicField(this, "_markers");
48729
+ __publicField(this, "_section");
48730
+ __publicField(this, "_renderTarget");
48731
+ __publicField(this, "_pickingMaterial");
48732
+ __publicField(this, "_readBuffer");
48733
+ // Debug visualization
48734
+ __publicField(this, "debug", true);
48735
+ __publicField(this, "_debugSphere");
48736
+ __publicField(this, "_debugLine");
48737
+ this._renderer = renderer;
48738
+ this._camera = camera2;
48739
+ this._scene = scene;
48740
+ this._vims = vims;
48741
+ this._section = section;
48742
+ this._renderTarget = new WebGLRenderTarget(width, height, {
48743
+ minFilter: NearestFilter,
48744
+ magFilter: NearestFilter,
48745
+ format: RGBAFormat,
48746
+ type: FloatType,
48747
+ depthBuffer: true
48748
+ });
48749
+ this._pickingMaterial = new PickingMaterial();
48750
+ this._readBuffer = new Float32Array(4);
48751
+ }
48752
+ /**
48753
+ * Sets the GizmoMarkers reference for marker picking.
48754
+ * Must be called after gizmos are initialized.
48755
+ */
48756
+ setMarkers(markers) {
48757
+ this._markers = markers;
48758
+ }
48759
+ /**
48760
+ * Updates the render target size to match viewport.
48761
+ */
48762
+ setSize(width, height) {
48763
+ this._renderTarget.setSize(width, height);
48764
+ }
48765
+ /**
48766
+ * Performs GPU picking at the given screen coordinates.
48767
+ * Returns a result object with element index, world position, and getElement() method.
48768
+ *
48769
+ * @param screenPos Screen position in 0-1 range (0,0 is top-left)
48770
+ * @returns Pick result with element index, world position, and getElement(), or undefined if no hit
48771
+ */
48772
+ pick(screenPos) {
48773
+ var _a3;
48774
+ const camera2 = this._camera.three;
48775
+ camera2.updateMatrixWorld(true);
48776
+ const currentRenderTarget = this._renderer.getRenderTarget();
48777
+ const currentOverrideMaterial = this._scene.threeScene.overrideMaterial;
48778
+ const currentBackground = this._scene.threeScene.background;
48779
+ this._pickingMaterial.updateCamera(camera2);
48780
+ if (this._section.active) {
48781
+ this._pickingMaterial.clippingPlanes = this._section.clippingPlanes;
48782
+ } else {
48783
+ this._pickingMaterial.clippingPlanes = [];
48784
+ }
48785
+ this._scene.threeScene.background = null;
48786
+ this._scene.threeScene.overrideMaterial = this._pickingMaterial.material;
48787
+ camera2.layers.disable(1);
48788
+ this._renderer.setRenderTarget(this._renderTarget);
48789
+ this._renderer.setClearColor(0, 0);
48790
+ this._renderer.clear();
48791
+ this._renderer.render(this._scene.threeScene, camera2);
48792
+ this._renderer.setRenderTarget(currentRenderTarget);
48793
+ camera2.layers.enable(1);
48794
+ this._scene.threeScene.overrideMaterial = currentOverrideMaterial;
48795
+ this._scene.threeScene.background = currentBackground;
48796
+ const pixelX = Math.floor(screenPos.x * this._renderTarget.width);
48797
+ const pixelY = Math.floor((1 - screenPos.y) * this._renderTarget.height);
48798
+ this._renderer.readRenderTargetPixels(
48799
+ this._renderTarget,
48800
+ pixelX,
48801
+ pixelY,
48802
+ 1,
48803
+ 1,
48804
+ this._readBuffer
48805
+ );
48806
+ const depth = this._readBuffer[1];
48807
+ const normalX = this._readBuffer[2];
48808
+ const normalY = this._readBuffer[3];
48809
+ if (depth <= 0) {
48810
+ return void 0;
48811
+ }
48812
+ const dataView = new DataView(this._readBuffer.buffer);
48813
+ const packedId = dataView.getUint32(0, true);
48814
+ const { vimIndex, elementIndex } = unpackPickingId(packedId);
48815
+ const normalZ = Math.sqrt(Math.max(0, 1 - normalX * normalX - normalY * normalY));
48816
+ const worldNormal = new Vector3(normalX, normalY, normalZ).normalize();
48817
+ const worldPosition = this.reconstructWorldPosition(screenPos, depth, camera2);
48818
+ if (vimIndex === MARKER_VIM_INDEX) {
48819
+ const marker = (_a3 = this._markers) == null ? void 0 : _a3.getMarkerFromIndex(elementIndex);
48820
+ const result2 = new GpuPickResult(elementIndex, vimIndex, worldPosition, worldNormal, void 0, marker);
48821
+ if (this.debug) {
48822
+ this.showDebugVisuals(result2);
48823
+ }
48824
+ return result2;
48825
+ }
48826
+ const vim = this._vims.getFromId(vimIndex);
48827
+ const result = new GpuPickResult(elementIndex, vimIndex, worldPosition, worldNormal, vim);
48828
+ if (this.debug) {
48829
+ this.showDebugVisuals(result);
48830
+ }
48831
+ return result;
48832
+ }
48833
+ /**
48834
+ * Shows debug visuals (sphere at hit point, line showing normal direction).
48835
+ */
48836
+ showDebugVisuals(result) {
48837
+ this.clearDebugVisuals();
48838
+ const sphereGeometry = new SphereGeometry(0.5, 16, 16);
48839
+ const sphereMaterial = new MeshBasicMaterial({ color: 16711680 });
48840
+ this._debugSphere = new Mesh(sphereGeometry, sphereMaterial);
48841
+ this._debugSphere.position.copy(result.worldPosition);
48842
+ this._debugSphere.layers.set(1);
48843
+ this._scene.threeScene.add(this._debugSphere);
48844
+ const lineLength = 2;
48845
+ const lineStart = result.worldPosition.clone();
48846
+ const lineEnd = result.worldPosition.clone().add(result.worldNormal.clone().multiplyScalar(lineLength));
48847
+ const lineGeometry = new BufferGeometry().setFromPoints([lineStart, lineEnd]);
48848
+ const lineMaterial = new LineBasicMaterial({ color: 65280, linewidth: 2 });
48849
+ this._debugLine = new Line(lineGeometry, lineMaterial);
48850
+ this._debugLine.layers.set(1);
48851
+ this._scene.threeScene.add(this._debugLine);
48852
+ this._renderer.domElement.dispatchEvent(new Event("needsUpdate"));
48853
+ }
48854
+ /**
48855
+ * Reconstructs world position from screen coordinates and depth value.
48856
+ */
48857
+ reconstructWorldPosition(screenPos, depth, camera2) {
48858
+ const ndcX = screenPos.x * 2 - 1;
48859
+ const ndcY = (1 - screenPos.y) * 2 - 1;
48860
+ const rayEnd = new Vector3(ndcX, ndcY, 1).unproject(camera2);
48861
+ const rayDir = rayEnd.sub(camera2.position).normalize();
48862
+ const cameraDir = new Vector3();
48863
+ camera2.getWorldDirection(cameraDir);
48864
+ const t = depth / rayDir.dot(cameraDir);
48865
+ const worldPos = camera2.position.clone().add(rayDir.clone().multiplyScalar(t));
48866
+ return worldPos;
48867
+ }
48868
+ /**
48869
+ * Removes debug visuals (sphere and normal line) from the scene.
48870
+ */
48871
+ clearDebugVisuals() {
48872
+ if (this._debugSphere) {
48873
+ this._scene.threeScene.remove(this._debugSphere);
48874
+ this._debugSphere.geometry.dispose();
48875
+ this._debugSphere.material.dispose();
48876
+ this._debugSphere = void 0;
48877
+ }
48878
+ if (this._debugLine) {
48879
+ this._scene.threeScene.remove(this._debugLine);
48880
+ this._debugLine.geometry.dispose();
48881
+ this._debugLine.material.dispose();
48882
+ this._debugLine = void 0;
48883
+ }
48884
+ }
48885
+ /**
48886
+ * Raycasts from camera to the screen position to find the first object hit.
48887
+ * Implements IRaycaster interface.
48888
+ * @param position - Screen position in 0-1 range (0,0 is top-left)
48889
+ * @returns A promise that resolves to the raycast result, or undefined if no hit
48890
+ */
48891
+ raycastFromScreen(position) {
48892
+ return Promise.resolve(this.pick(position));
48893
+ }
48894
+ /**
48895
+ * Raycasts from camera towards a world position to find the first object hit.
48896
+ * Implements IRaycaster interface.
48897
+ * @param position - The world position to raycast towards
48898
+ * @returns A promise that resolves to the raycast result, or undefined if no hit
48899
+ */
48900
+ raycastFromWorld(position) {
48901
+ const screenPos = this.worldToScreen(position);
48902
+ if (!screenPos) return Promise.resolve(void 0);
48903
+ return Promise.resolve(this.pick(screenPos));
48904
+ }
48905
+ /**
48906
+ * Converts a world position to screen coordinates (0-1 range).
48907
+ * @param worldPos - The world position to convert
48908
+ * @returns Screen position in 0-1 range, or undefined if behind camera
48909
+ */
48910
+ worldToScreen(worldPos) {
48911
+ const camera2 = this._camera.three;
48912
+ camera2.updateMatrixWorld(true);
48913
+ const ndc = worldPos.clone().project(camera2);
48914
+ if (ndc.z > 1) return void 0;
48915
+ const screenX = (ndc.x + 1) / 2;
48916
+ const screenY = (1 - ndc.y) / 2;
48917
+ return new Vector2(screenX, screenY);
48918
+ }
48919
+ /**
48920
+ * Disposes of all resources.
48921
+ */
48922
+ dispose() {
48923
+ this.clearDebugVisuals();
48924
+ this._renderTarget.dispose();
48925
+ this._pickingMaterial.dispose();
48926
+ }
48927
+ }
48668
48928
  class GizmoMarkers {
48669
48929
  /**
48670
48930
  * Constructs the marker manager and sets up an initial instanced mesh.
@@ -48708,6 +48968,12 @@ void main() {
48708
48968
  mesh.count = 0;
48709
48969
  mesh.frustumCulled = false;
48710
48970
  mesh.layers.enableAll();
48971
+ const packedIdArray = new Uint32Array(capacity);
48972
+ const packedIdAttr = new InstancedBufferAttribute(packedIdArray, 1);
48973
+ mesh.geometry.setAttribute("packedId", packedIdAttr);
48974
+ const ignoreArray = new Float32Array(capacity);
48975
+ const ignoreAttr = new InstancedBufferAttribute(ignoreArray, 1);
48976
+ mesh.geometry.setAttribute("ignore", ignoreAttr);
48711
48977
  this._viewer.renderer.add(mesh);
48712
48978
  return mesh;
48713
48979
  }
@@ -48717,12 +48983,20 @@ void main() {
48717
48983
  resizeMesh() {
48718
48984
  const larger = this.createMesh(this._mesh, this._mesh.count * 2);
48719
48985
  larger.count = this._mesh.count;
48986
+ const oldPackedId = this._mesh.geometry.getAttribute("packedId");
48987
+ const oldIgnore = this._mesh.geometry.getAttribute("ignore");
48988
+ const newPackedId = larger.geometry.getAttribute("packedId");
48989
+ const newIgnore = larger.geometry.getAttribute("ignore");
48720
48990
  for (let i2 = 0; i2 < this._mesh.count; i2++) {
48721
48991
  this._mesh.getMatrixAt(i2, this._reusableMatrix);
48722
48992
  larger.setMatrixAt(i2, this._reusableMatrix);
48993
+ newPackedId.setX(i2, oldPackedId.getX(i2));
48994
+ newIgnore.setX(i2, oldIgnore.getX(i2));
48723
48995
  const sub = new SimpleInstanceSubmesh(larger, i2);
48724
48996
  this._markers[i2].updateMesh(sub);
48725
48997
  }
48998
+ newPackedId.needsUpdate = true;
48999
+ newIgnore.needsUpdate = true;
48726
49000
  this._viewer.renderer.remove(this._mesh);
48727
49001
  this._mesh = larger;
48728
49002
  }
@@ -48736,8 +49010,12 @@ void main() {
48736
49010
  if (this._mesh.count === this._mesh.instanceMatrix.count) {
48737
49011
  this.resizeMesh();
48738
49012
  }
49013
+ const markerIndex = this._mesh.count;
48739
49014
  this._mesh.count += 1;
48740
- const sub = new SimpleInstanceSubmesh(this._mesh, this._mesh.count - 1);
49015
+ const packedIdAttr = this._mesh.geometry.getAttribute("packedId");
49016
+ packedIdAttr.setX(markerIndex, packPickingId(MARKER_VIM_INDEX, markerIndex));
49017
+ packedIdAttr.needsUpdate = true;
49018
+ const sub = new SimpleInstanceSubmesh(this._mesh, markerIndex);
48741
49019
  const marker = new Marker(this._viewer, sub);
48742
49020
  marker.position = position;
48743
49021
  this._markers.push(marker);
@@ -48758,7 +49036,10 @@ void main() {
48758
49036
  this._mesh.getMatrixAt(fromIndex, this._reusableMatrix);
48759
49037
  this._mesh.setMatrixAt(destIndex, this._reusableMatrix);
48760
49038
  this._mesh.instanceMatrix.needsUpdate = true;
48761
- const sub = new SimpleInstanceSubmesh(this._mesh, marker.index);
49039
+ const packedIdAttr = this._mesh.geometry.getAttribute("packedId");
49040
+ packedIdAttr.setX(destIndex, packPickingId(MARKER_VIM_INDEX, destIndex));
49041
+ packedIdAttr.needsUpdate = true;
49042
+ const sub = new SimpleInstanceSubmesh(this._mesh, destIndex);
48762
49043
  lastMarker.updateMesh(sub);
48763
49044
  }
48764
49045
  this._markers.length -= 1;
@@ -53659,238 +53940,6 @@ void main() {
53659
53940
  this.axes.dispose();
53660
53941
  }
53661
53942
  }
53662
- function packPickingId(vimIndex, elementIndex) {
53663
- return (vimIndex & 255) << 24 | elementIndex & 16777215;
53664
- }
53665
- function unpackPickingId(packedId) {
53666
- return {
53667
- vimIndex: packedId >>> 24,
53668
- elementIndex: packedId & 16777215
53669
- };
53670
- }
53671
- class GpuPickResult {
53672
- constructor(elementIndex, vimIndex, worldPosition, worldNormal, vim) {
53673
- /** The element index in the vim */
53674
- __publicField(this, "elementIndex");
53675
- /** The vim index identifying which vim the element belongs to */
53676
- __publicField(this, "vimIndex");
53677
- /** The world position of the hit */
53678
- __publicField(this, "worldPosition");
53679
- /** The world normal at the hit point */
53680
- __publicField(this, "worldNormal");
53681
- /** Reference to the vim containing the element */
53682
- __publicField(this, "_vim");
53683
- this.elementIndex = elementIndex;
53684
- this.vimIndex = vimIndex;
53685
- this.worldPosition = worldPosition;
53686
- this.worldNormal = worldNormal;
53687
- this._vim = vim;
53688
- }
53689
- /**
53690
- * The object property for IRaycastResult interface.
53691
- * Returns the Element3D for the picked element.
53692
- */
53693
- get object() {
53694
- return this.getElement();
53695
- }
53696
- /**
53697
- * Gets the Element3D object for the picked element.
53698
- * @returns The Element3D object, or undefined if not found
53699
- */
53700
- getElement() {
53701
- var _a3;
53702
- return (_a3 = this._vim) == null ? void 0 : _a3.getElementFromIndex(this.elementIndex);
53703
- }
53704
- }
53705
- class GpuPicker {
53706
- constructor(renderer, camera2, scene, vims, section, width, height) {
53707
- __publicField(this, "_renderer");
53708
- __publicField(this, "_camera");
53709
- __publicField(this, "_scene");
53710
- __publicField(this, "_vims");
53711
- __publicField(this, "_section");
53712
- __publicField(this, "_renderTarget");
53713
- __publicField(this, "_pickingMaterial");
53714
- __publicField(this, "_readBuffer");
53715
- // Debug visualization
53716
- __publicField(this, "debug", true);
53717
- __publicField(this, "_debugSphere");
53718
- __publicField(this, "_debugLine");
53719
- this._renderer = renderer;
53720
- this._camera = camera2;
53721
- this._scene = scene;
53722
- this._vims = vims;
53723
- this._section = section;
53724
- this._renderTarget = new WebGLRenderTarget(width, height, {
53725
- minFilter: NearestFilter,
53726
- magFilter: NearestFilter,
53727
- format: RGBAFormat,
53728
- type: FloatType,
53729
- depthBuffer: true
53730
- });
53731
- this._pickingMaterial = new PickingMaterial();
53732
- this._readBuffer = new Float32Array(4);
53733
- }
53734
- /**
53735
- * Updates the render target size to match viewport.
53736
- */
53737
- setSize(width, height) {
53738
- this._renderTarget.setSize(width, height);
53739
- }
53740
- /**
53741
- * Performs GPU picking at the given screen coordinates.
53742
- * Returns a result object with element index, world position, and getElement() method.
53743
- *
53744
- * @param screenPos Screen position in 0-1 range (0,0 is top-left)
53745
- * @returns Pick result with element index, world position, and getElement(), or undefined if no hit
53746
- */
53747
- pick(screenPos) {
53748
- const camera2 = this._camera.three;
53749
- camera2.updateMatrixWorld(true);
53750
- const currentRenderTarget = this._renderer.getRenderTarget();
53751
- const currentOverrideMaterial = this._scene.threeScene.overrideMaterial;
53752
- const currentBackground = this._scene.threeScene.background;
53753
- this._pickingMaterial.updateCamera(camera2);
53754
- if (this._section.active) {
53755
- this._pickingMaterial.clippingPlanes = this._section.clippingPlanes;
53756
- } else {
53757
- this._pickingMaterial.clippingPlanes = [];
53758
- }
53759
- this._scene.threeScene.background = null;
53760
- this._scene.threeScene.overrideMaterial = this._pickingMaterial.material;
53761
- camera2.layers.disable(1);
53762
- this._renderer.setRenderTarget(this._renderTarget);
53763
- this._renderer.setClearColor(0, 0);
53764
- this._renderer.clear();
53765
- this._renderer.render(this._scene.threeScene, camera2);
53766
- this._renderer.setRenderTarget(currentRenderTarget);
53767
- camera2.layers.enable(1);
53768
- this._scene.threeScene.overrideMaterial = currentOverrideMaterial;
53769
- this._scene.threeScene.background = currentBackground;
53770
- const pixelX = Math.floor(screenPos.x * this._renderTarget.width);
53771
- const pixelY = Math.floor((1 - screenPos.y) * this._renderTarget.height);
53772
- this._renderer.readRenderTargetPixels(
53773
- this._renderTarget,
53774
- pixelX,
53775
- pixelY,
53776
- 1,
53777
- 1,
53778
- this._readBuffer
53779
- );
53780
- const depth = this._readBuffer[1];
53781
- const normalX = this._readBuffer[2];
53782
- const normalY = this._readBuffer[3];
53783
- if (depth <= 0) {
53784
- return void 0;
53785
- }
53786
- const dataView = new DataView(this._readBuffer.buffer);
53787
- const packedId = dataView.getUint32(0, true);
53788
- const { vimIndex, elementIndex } = unpackPickingId(packedId);
53789
- const normalZ = Math.sqrt(Math.max(0, 1 - normalX * normalX - normalY * normalY));
53790
- const worldNormal = new Vector3(normalX, normalY, normalZ).normalize();
53791
- const worldPosition = this.reconstructWorldPosition(screenPos, depth, camera2);
53792
- const vim = this._vims.getFromId(vimIndex);
53793
- const result = new GpuPickResult(elementIndex, vimIndex, worldPosition, worldNormal, vim);
53794
- if (this.debug) {
53795
- this.showDebugVisuals(result);
53796
- }
53797
- return result;
53798
- }
53799
- /**
53800
- * Shows debug visuals (sphere at hit point, line showing normal direction).
53801
- */
53802
- showDebugVisuals(result) {
53803
- this.clearDebugVisuals();
53804
- const sphereGeometry = new SphereGeometry(0.5, 16, 16);
53805
- const sphereMaterial = new MeshBasicMaterial({ color: 16711680 });
53806
- this._debugSphere = new Mesh(sphereGeometry, sphereMaterial);
53807
- this._debugSphere.position.copy(result.worldPosition);
53808
- this._debugSphere.layers.set(1);
53809
- this._scene.threeScene.add(this._debugSphere);
53810
- const lineLength = 2;
53811
- const lineStart = result.worldPosition.clone();
53812
- const lineEnd = result.worldPosition.clone().add(result.worldNormal.clone().multiplyScalar(lineLength));
53813
- const lineGeometry = new BufferGeometry().setFromPoints([lineStart, lineEnd]);
53814
- const lineMaterial = new LineBasicMaterial({ color: 65280, linewidth: 2 });
53815
- this._debugLine = new Line(lineGeometry, lineMaterial);
53816
- this._debugLine.layers.set(1);
53817
- this._scene.threeScene.add(this._debugLine);
53818
- this._renderer.domElement.dispatchEvent(new Event("needsUpdate"));
53819
- }
53820
- /**
53821
- * Reconstructs world position from screen coordinates and depth value.
53822
- */
53823
- reconstructWorldPosition(screenPos, depth, camera2) {
53824
- const ndcX = screenPos.x * 2 - 1;
53825
- const ndcY = (1 - screenPos.y) * 2 - 1;
53826
- const rayEnd = new Vector3(ndcX, ndcY, 1).unproject(camera2);
53827
- const rayDir = rayEnd.sub(camera2.position).normalize();
53828
- const cameraDir = new Vector3();
53829
- camera2.getWorldDirection(cameraDir);
53830
- const t = depth / rayDir.dot(cameraDir);
53831
- const worldPos = camera2.position.clone().add(rayDir.clone().multiplyScalar(t));
53832
- return worldPos;
53833
- }
53834
- /**
53835
- * Removes debug visuals (sphere and normal line) from the scene.
53836
- */
53837
- clearDebugVisuals() {
53838
- if (this._debugSphere) {
53839
- this._scene.threeScene.remove(this._debugSphere);
53840
- this._debugSphere.geometry.dispose();
53841
- this._debugSphere.material.dispose();
53842
- this._debugSphere = void 0;
53843
- }
53844
- if (this._debugLine) {
53845
- this._scene.threeScene.remove(this._debugLine);
53846
- this._debugLine.geometry.dispose();
53847
- this._debugLine.material.dispose();
53848
- this._debugLine = void 0;
53849
- }
53850
- }
53851
- /**
53852
- * Raycasts from camera to the screen position to find the first object hit.
53853
- * Implements IRaycaster interface.
53854
- * @param position - Screen position in 0-1 range (0,0 is top-left)
53855
- * @returns A promise that resolves to the raycast result, or undefined if no hit
53856
- */
53857
- raycastFromScreen(position) {
53858
- return Promise.resolve(this.pick(position));
53859
- }
53860
- /**
53861
- * Raycasts from camera towards a world position to find the first object hit.
53862
- * Implements IRaycaster interface.
53863
- * @param position - The world position to raycast towards
53864
- * @returns A promise that resolves to the raycast result, or undefined if no hit
53865
- */
53866
- raycastFromWorld(position) {
53867
- const screenPos = this.worldToScreen(position);
53868
- if (!screenPos) return Promise.resolve(void 0);
53869
- return Promise.resolve(this.pick(screenPos));
53870
- }
53871
- /**
53872
- * Converts a world position to screen coordinates (0-1 range).
53873
- * @param worldPos - The world position to convert
53874
- * @returns Screen position in 0-1 range, or undefined if behind camera
53875
- */
53876
- worldToScreen(worldPos) {
53877
- const camera2 = this._camera.three;
53878
- camera2.updateMatrixWorld(true);
53879
- const ndc = worldPos.clone().project(camera2);
53880
- if (ndc.z > 1) return void 0;
53881
- const screenX = (ndc.x + 1) / 2;
53882
- const screenY = (1 - ndc.y) / 2;
53883
- return new Vector2(screenX, screenY);
53884
- }
53885
- /**
53886
- * Disposes of all resources.
53887
- */
53888
- dispose() {
53889
- this.clearDebugVisuals();
53890
- this._renderTarget.dispose();
53891
- this._pickingMaterial.dispose();
53892
- }
53893
- }
53894
53943
  function getAverageBoundingBox(positions, thresholdSpan = 1e3, framingDistanceMultiplier = 2) {
53895
53944
  if (positions.length === 0) {
53896
53945
  return new Box3();
@@ -55039,14 +55088,14 @@ void main() {
55039
55088
  selectAtPointer: async (pos, add) => {
55040
55089
  const result = await viewer.raycaster.raycastFromScreen(pos);
55041
55090
  if (add) {
55042
- viewer.selection.add(result.object);
55091
+ viewer.selection.add(result == null ? void 0 : result.object);
55043
55092
  } else {
55044
- viewer.selection.select(result.object);
55093
+ viewer.selection.select(result == null ? void 0 : result.object);
55045
55094
  }
55046
55095
  },
55047
55096
  frameAtPointer: async (pos) => {
55048
55097
  const result = await viewer.raycaster.raycastFromScreen(pos);
55049
- viewer.camera.lerp(0.75).frame(result.object ?? "all");
55098
+ viewer.camera.lerp(0.75).frame((result == null ? void 0 : result.object) ?? "all");
55050
55099
  },
55051
55100
  zoom: async (value, pos) => {
55052
55101
  if (pos) {
@@ -56349,7 +56398,7 @@ void main() {
56349
56398
  this.environment = new Environment(this.camera, this.renderer, this.materials, this.settings);
56350
56399
  this.selection = createSelection$1();
56351
56400
  const size = this.renderer.renderer.getSize(new Vector2());
56352
- this.raycaster = new GpuPicker(
56401
+ const gpuPicker = new GpuPicker(
56353
56402
  this.renderer.renderer,
56354
56403
  this._camera,
56355
56404
  scene,
@@ -56358,6 +56407,8 @@ void main() {
56358
56407
  size.x || 1,
56359
56408
  size.y || 1
56360
56409
  );
56410
+ gpuPicker.setMarkers(this.gizmos.markers);
56411
+ this.raycaster = gpuPicker;
56361
56412
  this.viewport.onResize.sub(() => {
56362
56413
  const size2 = this.viewport.getParentSize();
56363
56414
  this.raycaster.setSize(size2.x, size2.y);