首页 > 解决方案 > THREE.BoxBufferGeometry 与 raycaster.intersectObjects 相交

问题描述

我想得到光线与盒子的交点。我的代码有什么问题?

    const ggeo = new THREE.BoxBufferGeometry(100, 200, 60);
    const gmesh = new THREE.Mesh(ggeo, new THREE.MeshBasicMaterial({ color: 0x00ffff}));
    gmesh.position.set(-150, 0, -30);
    gmesh.visible = true;
    gmesh.updateMatrixWorld();
    scene.add(gmesh);

    // intersection
    var from = new THREE.Vector3(-10, 0, -10);
    var to = new THREE.Vector3(-1, 0, 0);
    var raycaster = new THREE.Raycaster();
    raycaster.set(from, to);
    var intersects = raycaster.intersectObjects(gmesh as any, true);
    if (intersects.length > 0) {
          // no interseection !
    }

这是一个小提琴:

https://jsfiddle.net/jek75fLg/

标签: three.js

解决方案


你的小提琴有两个问题:

  • 您没有在光线投射之前更新网格的世界矩阵。
  • 的第二个参数Raycaster.set()需要一个必须具有单位长度的方向向量。
  • 你必须使用intersectObject()not intersectObjects()

这是一个工作示例:

var camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 1000;

var scene = new THREE.Scene();
scene.background = new THREE.Color(0xf0f0f0);

var raycaster = new THREE.Raycaster();

renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const ggeo = new THREE.BoxBufferGeometry(50, 300, 260);
const gmesh = new THREE.Mesh(ggeo, new THREE.MeshBasicMaterial({
  color: 0x00ffff
}));
gmesh.position.set(-150, 0, -10);
gmesh.updateMatrixWorld();
scene.add(gmesh);

var from = new THREE.Vector3(0, 0, -20);
var wallvec = new THREE.Vector3(-1, 0, 0);

var raycaster = new THREE.Raycaster();
raycaster.set(from, wallvec);

//

const lineGeometry = new THREE.BufferGeometry().setFromPoints( [from, new THREE.Vector3(-10000, 0 -20)] );
const line = new THREE.Line(lineGeometry, new THREE.LineBasicMaterial( {color: 0xff0000}));
scene.add(line);
//

var intersects = raycaster.intersectObject(gmesh);
if (intersects.length > 0) {
  console.log('INTERSECTED');
}


renderer.render(scene, camera);
body {
      margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.134.0/build/three.min.js"></script>

它还可视化光线,因此可以看到光线实际击中网格的位置。

顺便说一句:您帖子中的代码片段和小提琴中的代码在某些方面有所不同。调查最好使两者保持同步。


推荐阅读