【问题标题】:Raycaster.intersectObjects() not returning anything?Raycaster.intersectObjects() 没有返回任何东西?
【发布时间】:2018-08-08 06:13:14
【问题描述】:

我的场景设置如下:

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;

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

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);

然后我使用以下代码渲染场景:

renderer.render(scene, camera);
requestAnimationFrame(render);

最后我为鼠标点击事件使用下面的代码:

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); 似乎有点像黑洞?

我认为我的设置有问题?任何帮助将不胜感激!

【问题讨论】:

    标签: three.js


    【解决方案1】:

    有两件事我试过了:

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

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

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

    mesh.updateMatrixWorld(); // add this
    
    raycaster.set(from, direction);
    

    【讨论】:

      【解决方案2】:

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

      所以当我给 intersectObjects(mesh[]) 一个网格数组时,它会起作用。

      更多代码详情见https://github.com/mrdoob/three.js/issues/8081

      【讨论】:

        【解决方案3】:

        这是一个老问题,但我遇到了类似的问题,并认为我学到的东西可能对其他人有所帮助。我的代码设置和 JohnnyDevNull 的很相似,所以不再赘述。

        问题

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

        我的解决方案

        下面的函数接受一个空数组 (intersects)。它在场景中的每个子对象中搜索三个 Group 对象和 Mesh 对象,并将 Mesh 对象添加到数组中。对于组,它将递归设置为true,它将.intersectObject 应用于每个孩子。一旦建立了数组,它就会在数组上调用您提供的回调函数。

        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;
          }
        }

        适应您的用例

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

        【讨论】:

        • intersects.push(raycaster.intersectObject(scene.children[i]));需要 intersects.push(...raycaster.intersectObject(scene.children[i]));
        猜你喜欢
        • 2015-02-11
        • 2012-04-05
        • 1970-01-01
        • 1970-01-01
        • 2020-05-17
        • 2019-04-22
        • 1970-01-01
        • 2014-04-28
        • 2011-05-04
        相关资源
        最近更新 更多