Javascript 如何在ThreeJs R71中对点云进行光线投射
我在autodesk forge工作,其中包括Threejs r71,我想使用raycaster来检测点云中不同元素上的点击 对于如何使用ThreeJs r71执行此操作的示例代码,我们将不胜感激 现在,我向forge api注册了一个扩展,并在其中运行下面的代码。它创建一个点云,并将点定位在cameraInfo阵列中保存的预定位置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) {
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空间中特定位置的丰富注释。使用这种方法,您不必担心自定义交点-浏览器会为您处理所有事情