首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Raycaster.intersectObjects()不返回任何内容吗?

Raycaster.intersectObjects()不返回任何内容吗?
EN

Stack Overflow用户
提问于 2015-06-26 20:03:55
回答 3查看 4.7K关注 0票数 2

我将我的场景设置如下:

代码语言:javascript
复制
document.addEventListener('mousedown', onDocumentMouseDown, false);

var container = document.getElementById("myCanvas");

scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth*0.99, window.innerHeight*0.99 );
container.appendChild( renderer.domElement );

room_material = new THREE.MeshBasicMaterial({color: 0x00ff00});
room_material.side = THREE.DoubleSide;

objects = [];

camera.position.z = 19;
camera.position.x = 5;
camera.position.y = 30;

我有一个对象数组,我正在尝试检测单击是否与它们相交,定义如下:

代码语言:javascript
复制
var thing0 = new THREE.Shape();
thing0.moveTo(-12.1321728566, 35.3935535858);
thing0.lineTo(7.10021556487,35.3935535858);
thing0.lineTo(7.10021556487,19.7039735578);
thing0.lineTo(5.12636517425,19.7166264449);
thing0.lineTo(5.12636517425,33.6221493891);
thing0.lineTo(-12.1377356984,33.6439534769);
var thing0Geom = new THREE.ShapeGeometry(thing0);
var thing0Mesh = new THREE.Mesh( thing0Geom, room_material );
thing0Mesh.name = "abcd";
scene.add(thing0Mesh);
objects.push(thing0Mesh);

然后我用下面的代码渲染场景:

代码语言:javascript
复制
renderer.render(scene, camera);
requestAnimationFrame(render);

最后,我为鼠标单击事件使用了以下代码:

代码语言:javascript
复制
function onDocumentMouseDown(event) {
    var vector = new THREE.Vector3(( event.clientX / window.innerWidth ) * 2 - 1, -( event.clientY / window.innerHeight ) * 2 + 1, 0.5);
    vector = vector.unproject(camera);
    var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
    var intersects = raycaster.intersectObjects(objects, true);
    alert("well, you clicked!");
    if (intersects.length > 0) {
        alert("wow, it worked");
    }
}

然而,无论我怎么做,当它跟随raycaster.intersectObjects(objects, true);时,它永远不会被调用,但是当它被放在它之前的任何地方时,它都会被调用。在这种情况下,raycaster.intersectObjects(objects, true);似乎是一个有点黑洞?

我假设我只是在我的设置中有什么问题?任何帮助都将不胜感激!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-02-09 03:27:51

我想我找到问题所在了。我必须将网格添加到一个额外的数组中。scene.children上的intersectObjects不起作用,因为网格中还有其他对象。

因此,当我给intersectObjects( mesh[] )一个网格数组时,它就会工作。

有关更多代码详细信息,请参阅https://github.com/mrdoob/three.js/issues/8081

票数 4
EN

Stack Overflow用户

发布于 2018-08-08 06:13:15

有两个我尝试过的方法是有效的:

1)如果网格面没有指向光线的原点,请确保使用Three.DoubleSide。这是直接从documentation

“请注意,对于网格,面必须指向光线的原点才能被检测到;穿过面背面的光线的交点将不会被检测到。要对对象的两个面进行光线投射,您需要将材质的side属性设置为THREE.DoubleSide。”

2)在光线投射之前使用mesh.updateMatrixWorld()。这来自另一个stackoverflow帖子:threejs raycasting does not work

代码语言:javascript
复制
mesh.updateMatrixWorld(); // add this

raycaster.set(from, direction);
票数 9
EN

Stack Overflow用户

发布于 2017-06-14 00:11:43

这是一个古老的问题,但我遇到了类似的问题,我认为我学到的东西可能会对其他人有所帮助。我的代码设置与JohnnyDevNull的非常相似,所以我不再重复。

问题所在

在我的例子中,使用scene.children调用intersectObjects是不起作用的,因为它会拾取其他对象,如ambientLighting等。我相信这就是OP在他自己的答案中提到的。

我的解决方案

下面的函数接受一个空数组(intersects)。它在场景中的每个子对象中搜索三个组对象和网格对象,并将网格对象添加到数组中。对于组,它将recursive设置为true,这将对每个子级应用.intersectObject。一旦数组构建完成,它就会调用数组上提供的回调函数。

代码语言:javascript
复制
function raycastMeshes(intersects, callback, theScene, theRaycaster) {
  var scene = theScene || scene || new THREE.Scene();
  var raycaster = theRaycaster || raycaster || new THREE.Raycaster();

  for (var i in scene.children) {
    if (scene.children[i] instanceof THREE.Group) {
      intersects = raycaster.intersectObjects(scene.children[i].children, true);
    } else if (scene.children[i] instanceof THREE.Mesh) {
      intersects.push(raycaster.intersectObject(scene.children[i]));
    }
  }

  if (intersects.length > 0) {
    return callback(intersects);
  } else {
    return null;
  }
}

适应您的用例

这显然是一个相当幼稚和具体的用例,但如果你遇到类似的问题,应该作为一个跳板。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31072742

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档