Three.js Projector 和 Ray 对象 [英] Three.js Projector and Ray objects

查看:42
本文介绍了Three.js Projector 和 Ray 对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试使用 Projector 和 Ray 类来进行一些碰撞检测演示.我开始只是尝试使用鼠标来选择对象或拖动它们.我查看了使用这些对象的示例,但它们似乎都没有解释 Projector 和 Ray 的某些方法究竟在做什么的评论.我有几个问题希望有人能轻松回答.

I have been trying to work with the Projector and Ray classes in order to do some collision detection demos. I have started just trying to use the mouse to select objects or to drag them. I have looked at examples that use the objects, but none of them seem to have comments explaining what exactly some of the methods of Projector and Ray are doing. I have a couple questions that I am hoping will be easy for someone to answer.

到底发生了什么,Projector.projectVector() 和 Projector.unprojectVector() 之间有什么区别?我注意到在所有使用投影仪和射线对象的示例中似乎都使用了 unproject 方法在创建射线之前调用.什么时候使用 projectVector?

What exactly is happening and what is the difference between Projector.projectVector() and Projector.unprojectVector()? I notice that it seems in all the examples using both projector and ray objects the unproject method is called before the ray is created. When would you use projectVector?

我在这个演示中使用以下代码在拖动时旋转立方体用鼠标.有人可以简单地解释一下当我使用 mouse3D 和相机取消投影然后创建光线时到底发生了什么.射线是否依赖于对 unprojectVector() 的调用

/** Event fired when the mouse button is pressed down */
function onDocumentMouseDown(event) {
    event.preventDefault();
    mouseDown = true;
    mouse3D.x = mouse2D.x = mouseDown2D.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse3D.y = mouse2D.y = mouseDown2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
    mouse3D.z = 0.5;

    /** Project from camera through the mouse and create a ray */
    projector.unprojectVector(mouse3D, camera);
    var ray = new THREE.Ray(camera.position, mouse3D.subSelf(camera.position).normalize());
    var intersects = ray.intersectObject(crateMesh); // store intersecting objects

    if (intersects.length > 0) {
        SELECTED = intersects[0].object;
        var intersects = ray.intersectObject(plane);
    }

}

/** This event handler is only fired after the mouse down event and
    before the mouse up event and only when the mouse moves */
function onDocumentMouseMove(event) {
    event.preventDefault();

    mouse3D.x = mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse3D.y = mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
    mouse3D.z = 0.5;
    projector.unprojectVector(mouse3D, camera);

    var ray = new THREE.Ray(camera.position, mouse3D.subSelf(camera.position).normalize());

    if (SELECTED) {
        var intersects = ray.intersectObject(plane);
        dragVector.sub(mouse2D, mouseDown2D);
        return;
    }

    var intersects = ray.intersectObject(crateMesh);

    if (intersects.length > 0) {
        if (INTERSECTED != intersects[0].object) {
            INTERSECTED = intersects[0].object;
        }
    }
    else {
        INTERSECTED = null;
    }
}

/** Removes event listeners when the mouse button is let go */
function onDocumentMouseUp(event) {
    event.preventDefault();

    /** Update mouse position */
    mouse3D.x = mouse2D.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse3D.y = mouse2D.y = -(event.clientY / window.innerHeight) * 2 + 1;
    mouse3D.z = 0.5;

    if (INTERSECTED) {
        SELECTED = null;
    }

    mouseDown = false;
    dragVector.set(0, 0);
}

/** Removes event listeners if the mouse runs off the renderer */
function onDocumentMouseOut(event) {
    event.preventDefault();

    if (INTERSECTED) {
        plane.position.copy(INTERSECTED.position);
        SELECTED = null;
    }
    mouseDown = false;
    dragVector.set(0, 0);
}

推荐答案

基本上,您需要从 3D 世界空间和 2D 屏幕空间进行投影.

Basically, you need to project from the 3D world space and the 2D screen space.

渲染器使用 projectVector 将 3D 点转换为 2D 屏幕.unprojectVector 基本上是用来做相反的事情,将 2D 点取消投影到 3D 世界中.对于这两种方法,您都传递了您正在查看场景的相机.

Renderers use projectVector for translating 3D points to the 2D screen. unprojectVector is basically for doing the inverse, unprojecting 2D points into the 3D world. For both methods you pass the camera you're viewing the scene through.

因此,在此代码中,您将在 2D 空间中创建归一化向量.老实说,我对 z = 0.5 逻辑从来不太确定.

So, in this code you're creating a normalised vector in 2D space. To be honest, I was never too sure about the z = 0.5 logic.

mouse3D.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse3D.y = -(event.clientY / window.innerHeight) * 2 + 1;
mouse3D.z = 0.5;

然后,此代码使用相机投影矩阵将其转换为我们的 3D 世界空间.

Then, this code uses the camera projection matrix to transform it to our 3D world space.

projector.unprojectVector(mouse3D, camera);

将 mouse3D 点转换为 3D 空间后,我们现在可以使用它来获取方向,然后使用相机位置从中投射光线.

With the mouse3D point converted into the 3D space, we can now use it for getting the direction and then use the camera position to throw a ray from.

var ray = new THREE.Ray(camera.position, mouse3D.subSelf(camera.position).normalize());
var intersects = ray.intersectObject(plane);

这篇关于Three.js Projector 和 Ray 对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆