Three.js - 获取鼠标点击的 X、Y 和 Z 坐标

Posted

技术标签:

【中文标题】Three.js - 获取鼠标点击的 X、Y 和 Z 坐标【英文标题】:Three.js - Getting the X, Y, and Z coordinates of mouse click 【发布时间】:2014-12-02 15:33:20 【问题描述】:

我正在使用 version 68 of three.js。

我想单击某处并获取 X、Y 和 Z 坐标。我按照此处的步骤操作,但它们给我的 Z 值为 0:Mouse / Canvas X, Y to Three.js World X, Y, Z

基本上,如果我在场景中有一个网格,并且我单击它的中间,我希望能够计算出与该网格的位置相同的值。 这只是一个例子。我知道我可以使用光线投射,看看我是否与网格碰撞,然后检查它的位置。但是,即使我没有单击网格,我也希望它能够工作。

这可能吗?这是一个 jsfiddle:http://jsfiddle.net/j9ydgyL3/

在那个 jsfiddle 中,如果我能设法单击该正方形的中心,我希望分别计算 X、Y 和 Z 值的 10、10、10,因为这些是正方形位置的坐标.以下是关注的两个函数:

function getMousePosition(clientX, clientY) 
    var mouse2D = new THREE.Vector3();
    var mouse3D = new THREE.Vector3();
    mouse2D.x = (clientX / window.innerWidth) * 2 - 1;
    mouse2D.y = -(clientY / window.innerHeight) * 2 + 1;
    mouse2D.z = 0.5;
    mouse3D = projector.unprojectVector(mouse2D.clone(), camera);
    return mouse3D;
    //var vector = new THREE.Vector3(
    //( clientX / window.innerWidth ) * 2 - 1,
    //- ( clientY / window.innerHeight ) * 2 + 1,
    //0.5 );

    //projector.unprojectVector( vector, camera );
    //var dir = vector.sub( camera.position ).normalize();
    //var distance = - camera.position.z / dir.z;
    //var pos = camera.position.clone().add( dir.multiplyScalar( distance ) );
    //return pos;


function onDocumentMouseUp(event) 
    event.preventDefault();

    var mouse3D = getMousePosition(event.clientX, event.clientY);
    console.log(mouse3D.x + ' ' + mouse3D.y + ' ' + mouse3D.z);

我留下了一些我尝试过的其他代码注释掉了。请注意,这个被注释掉的代码在 jsfiddle 网站上不起作用,可能是因为他们仍在使用 54 版的three.js。它在我的 68 版机器上运行良好。

编辑:澄清一下,无论鼠标在哪里,我都希望能够获得坐标。我只是在这个例子中使用了一个网格,因为通过查看计算的坐标是否与网格的相同,很容易验证它是否有效。我真正想要的是它可以在不使用网格的光线投射的情况下工作。例如,我们可以让它总是在每次鼠标移动时将计算出的坐标打印到控制台,无论场景中有什么。

【问题讨论】:

如果没有类似网格的东西可以点击,你如何找到 Z 坐标?它可以是从-Inf 到+Inf 的任何地方。你真的需要一些东西来提供坐标来测试,根据答案你会使用光线投射器来检查。 @Leeft 我不确定,这就是我问是否可能的原因。如果确实不可能,请随时将其发布为答案,我会接受=) 【参考方案1】:

您应该为此使用THREE.Raycaster。当您设置intersectObjects 列表时,您将能够获得与射线相交的对象数组。因此,您可以从返回列表中的“单击”对象中获取位置。 Check the updated fiddle here。 我还将您的 Three.js 更改为 R68 版本

有关THREE.RayCaster 的更高级用法,请查看Threejs.org/examples 中的示例,例如this example with interactive cubes。

来自updated fiddle的相关代码:

function getMousePosition(clientX, clientY) 
    var mouse2D = new THREE.Vector3();
    var mouse3D = new THREE.Vector3();
    mouse2D.x = (clientX / window.innerWidth) * 2 - 1;
    mouse2D.y = -(clientY / window.innerHeight) * 2 + 1;
    mouse2D.z = 0.5;
    mouse3D = projector.unprojectVector(mouse2D.clone(), camera);
    return mouse3D;
    var vector = new THREE.Vector3(
    (clientX / window.innerWidth) * 2 - 1, -(clientY / window.innerHeight) * 2 + 1,
    0.5);

    projector.unprojectVector(vector, camera);
    var dir = vector.sub(camera.position).normalize();
    var distance = -camera.position.z / dir.z;
    var pos = camera.position.clone().add(dir.multiplyScalar(distance));
    return pos;


function onDocumentMouseUp(event) 
    event.preventDefault();

    var mouse3D = getMousePosition(event.clientX, event.clientY);
    console.log(mouse3D.x + ' ' + mouse3D.y + ' ' + mouse3D.z);

var vector = new THREE.Vector3( mouse3D.x, mouse3D.y, 1 );    
    raycaster.set( camera.position, vector.sub( camera.position ).normalize() );

    var intersects = raycaster.intersectObjects(scene.children );
    if(intersects.length > 0)
        console.log(intersects[0].object.position);
    


function animate() 
    requestAnimationFrame(animate);
    render();


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

【讨论】:

小提琴似乎不起作用,因为立方体几何函数似乎给出了错误?

以上是关于Three.js - 获取鼠标点击的 X、Y 和 Z 坐标的主要内容,如果未能解决你的问题,请参考以下文章

使用正交相机从鼠标位置获取 Three.js 世界坐标

Three.js案例从0到1对象跟随鼠标动起来

鼠标移动时旋转Three.js场景

35three.js鼠标控制物体旋转缩放

使用 Projection 在 Three.js 中将世界坐标转换为屏幕坐标

three.js 2D 鼠标点击到 3d 坐标使用 raycaster