Javascript 如何在ThreeJs R71中对点云进行光线投射

Javascript 如何在ThreeJs R71中对点云进行光线投射,javascript,three.js,autodesk-forge,Javascript,Three.js,Autodesk Forge,我在autodesk forge工作,其中包括Threejs r71,我想使用raycaster来检测点云中不同元素上的点击 对于如何使用ThreeJs r71执行此操作的示例代码,我们将不胜感激 现在,我向forge api注册了一个扩展,并在其中运行下面的代码。它创建一个点云,并将点定位在cameraInfo阵列中保存的预定位置 let geometry = new THREE.Geometry(); this.cameraInfo.forEach( function(e) {

我在autodesk forge工作,其中包括Threejs r71,我想使用raycaster来检测点云中不同元素上的点击

对于如何使用ThreeJs r71执行此操作的示例代码,我们将不胜感激

现在,我向forge api注册了一个扩展,并在其中运行下面的代码。它创建一个点云,并将点定位在cameraInfo阵列中保存的预定位置

let geometry = new THREE.Geometry();
this.cameraInfo.forEach( function(e) {
        geometry.vertices.push(e.position);
    }
)
const material = new THREE.PointCloudMaterial( { size: 150, color: 0Xff0000, sizeAttenuation: true } );
this.points = new THREE.PointCloud( geometry, material );
this.scene.add(this.points);

/* Set up event listeners */
document.addEventListener('mousemove', event => {
    // console.log('mouse move!');
    let mouse = {
        x: ( event.clientX / window.innerWidth ) * 2 - 1,
        y: - ( event.clientY / window.innerHeight ) * 2 + 1
    };

    let raycaster = new THREE.Raycaster();

    raycaster.params.PointCloud.threshold = 15;
    let vector = new THREE.Vector3(mouse.x, mouse.y, 0.5).unproject(this.camera);
    raycaster.ray.set(this.camera.position, vector.sub(this.camera.position).normalize());
    this.scene.updateMatrixWorld();
    let intersects = raycaster.intersectObject(this.points);


    if (intersects.length > 0) {
        const hitIndex = intersects[0].index;
        const hitPoint = this.points.geometry.vertices[ hitIndex ];
        console.log(hitIndex);
        console.log(hitPoint);
    }

}, false);
结果似乎不合逻辑。在某些相机位置,无论鼠标在何处,它都会不断告诉我它与点云中的某个项目相交。在某些摄像机位置,它根本检测不到交叉点


TLDR:它实际上不会检测到我的点云和鼠标之间的交叉点。

我使用了一些查看器API,在点云中使用了几个采样点,从而简化了代码:

  const viewer = NOP_VIEWER;
  const geometry = new THREE.Geometry();
  for (let i = -100; i <= 100; i += 10) {
    geometry.vertices.push(new THREE.Vector3(i, i, i));
  }
  const material = new THREE.PointCloudMaterial({ size: 50, color: 0Xff0000, sizeAttenuation: true });
  const points = new THREE.PointCloud(geometry, material);
  viewer.impl.scene.add(points);

  const raycaster = new THREE.Raycaster();
  raycaster.params.PointCloud.threshold = 50;
  document.addEventListener('mousemove', function(event) {
    const ray = viewer.impl.viewportToRay(viewer.impl.clientToViewport(event.clientX, event.clientY));
    raycaster.ray.set(ray.origin, ray.direction);
    let intersects = raycaster.intersectObject(viewer.impl.scene, true);
    if (intersects.length > 0) {
      console.log(intersects[0]);
    }
  });
我相信您需要调整raycaster.params.PointCloud.threshold值。three.js中的光线投射逻辑实际上并不与屏幕上渲染的点框相交。它仅计算光线与世界坐标系中的点之间的距离,并且仅在距离低于阈值时输出交点。在我的示例中,我尝试将阈值设置为50,并且相交结果稍微好一些

作为一个旁注,如果你不一定需要场景中的点云,那么可以考虑在3D视图上叠加HTML元素。我们使用演示中的方法来显示附加到3D空间中特定位置的丰富注释。使用这种方法,您不必担心自定义交点-浏览器会为您处理所有事情