简体   繁体   English

如何在ThreeJs R71中光线投射到Pointcloud

[英]How to raycast onto a pointcloud in ThreeJs R71

I am working in autodesk forge which includes Threejs r71 and I want to use a raycaster to detect clicks on different elements within a pointcloud. 我正在使用包含Threejs r71的Autodesk Forge工作,我想使用光线投射器检测Pointcloud中不同元素的点击。

Sample code for how to do this with ThreeJs r71 be appreciated. 有关如何使用ThreeJs r71进行操作的示例代码将不胜感激。

Right now, I register an extension with the forge api and run the code below within it. 现在,我向伪造的api注册一个扩展,并在其中运行下面的代码。 It creates creates a pointcloud and positions the points at predetermined locations (saved within the cameraInfo array). 它创建一个点云并将点定位在预定位置(保存在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);

The output seems to be illogical. 输出似乎是不合逻辑的。 At certain camera positions, it will constantly tell me that it is intersecting an item in the pointcloud (regardless of where the mouse is). 在某些摄像头位置,它会不断告诉我它与点云中的某个项目相交(无论鼠标在哪里)。 And at certain camera positions, it won't detect an intersection at all. 在某些相机位置,它根本不会检测到相交。

TLDR: it doesn't actually detect an intersection b/w my pointcloud and the mouse. TLDR:它实际上并没有检测到我的点云和鼠标的交集。

I've simplified the code a bit, using some of the viewer APIs (using a couple of sample points in the point cloud): 我使用了一些查看器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]);
    }
  });

I believe you'll need to tweak the raycaster.params.PointCloud.threshold value. 我相信您需要调整raycaster.params.PointCloud.threshold值。 The ray casting logic in three.js doesn't actually intersect the point "boxes" that you see rendered on the screen. three.js中的光线投射逻辑实际上并不与您在屏幕上看到的“盒子”点相交。 It only computes distance between the ray and the point (in the world coordinate system), and only outputs an intersection when the distance is under the threshold value. 它仅计算射线与点之间的距离(在世界坐标系中),并且仅在距离小于阈值时才输出交点。 In my example I tried setting the threshold to 50, and the intersection results were somewhat better. 在我的例子我试过的阈值设置为50,并且交集结果稍好

As a side note, if you don't necessarily need point clouds inside the scene, consider overlaying HTML elements over the 3D view instead. 附带说明一下,如果场景中不一定需要点云,请考虑在3D视图上覆盖HTML元素。 We're using the approach in the https://forge-digital-twin.autodesk.io demo ( source ) to show rich annotations attached to specific positions in the 3D space. 我们正在使用https://forge-digital-twin.autodesk.io演示( )中的方法来显示附加到3D空间中特定位置的丰富注释。 With this approach, you don't have to worry about custom intersections - the browser handles everything for you. 使用这种方法,您不必担心自定义交叉点-浏览器会为您处理所有事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM