Three.js 隐形平面不适用于 raycaster.intersectObject

Posted

技术标签:

【中文标题】Three.js 隐形平面不适用于 raycaster.intersectObject【英文标题】:Three.js invisible plane not working with raycaster.intersectObject 【发布时间】:2016-04-26 19:23:14 【问题描述】:

我正在尝试制作可拖动的对象,如下例所示:https://www.script-tutorials.com/demos/467/index.html

应该可拖动的对象在数组objectMoverLines中。

我已使用以下代码向我的场景中添加了一架飞机:

plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(500, 500, 8, 8), new THREE.MeshBasicMaterial(color: 0x248f24, alphaTest: 0));
plane.visible = false;
scene.add(plane);

问题出现在onDocumentMouseDown函数下。出于某种原因,如果平面可见性设置为 false (plane.visible = false),则在某个点上,不会填充 intersectsobjmovers。但是,如果将飞机的可见性设置为 true,它将正常工作(但显然,这会导致一架巨大的飞机妨碍一切):

function onDocumentMouseDown(event) 
    // Object position movers
    var vector = new THREE.Vector3(mouse.x, mouse.y, 1);
    vector.unproject(camera);

    raycaster.set( camera.position, vector.sub( camera.position ).normalize() );
    var intersectsobjmovers = raycaster.intersectObjects(objectMoverLines);
    if (intersectsobjmovers.length > 0) 
        console.log('clicking an object mover');
        // Disable the controls
        controls.enabled = false;
        // Set the selection - first intersected object
        objmoverselection = intersectsobjmovers[0].object;
        // Calculate the offset
        var intersectsobjmovers = raycaster.intersectObject(plane);

        // At this point, intersectsobjmovers does not include any items, even though
        // it should (but it does work when plane.visible is set to true...)

        offset.copy(intersectsobjmovers[0].point).sub(plane.position);
     else 
        controls.enabled = true;
    

另外,这是我目前在 onDocumentMouseMove 功能下拥有的:

function onDocumentMouseMove(event) 
    event.preventDefault();

    mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;

    // Get 3D vector from 3D mouse position using 'unproject' function
    var vector = new THREE.Vector3(mouse.x, mouse.y, 1);
    vector.unproject(camera);

    // Set the raycaster position
    raycaster.set( camera.position, vector.sub( camera.position ).normalize() );

    if (objmoverselection) 
        // Check the position where the plane is intersected
        var intersectsobjmovers = raycaster.intersectObject(plane);
        // Reposition the object based on the intersection point with the plane
        objmoverselection.position.copy(intersectsobjmovers[0].point.sub(offset));
     else 
        // Update position of the plane if need
        var intersectsobjmovers = raycaster.intersectObjects(objectMoverLines);
        if (intersectsobjmovers.length > 0) 
            // var lookAtVector = new THREE.Vector3(0,0, -1);
            // lookAtVector.applyQuaternion(camera.quaternion);
            plane.position.copy(intersectsobjmovers[0].object.position);
            plane.lookAt(camera.position);
        
    

    requestAnimationFrame( render );

【问题讨论】:

【参考方案1】:

试试这个:

plane = new THREE.Mesh(new THREE.PlaneBufferGeometry(500, 500, 8, 8), 
   new THREE.MeshBasicMaterial( 
       color: 0x248f24, alphaTest: 0, visible: false
));

scene.add(plane);

【讨论】:

哦,我明白了...我必须在材质上将可见性设置为 false,而不是在网格上...我应该知道

以上是关于Three.js 隐形平面不适用于 raycaster.intersectObject的主要内容,如果未能解决你的问题,请参考以下文章

three.js 给模型添加标注

Three.js 中的 Raycast,只有一个投影矩阵

Three.js Raycaster on WebWorker

Three.js raycaster 可以与组相交吗?

Three.js Raycaster 未检测到场景网格

Three.js raycaster 到底在做啥?