Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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.

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?

I am using the following code in this demo to spin the cube when dragged on with the mouse. Can someone explain in simple terms what exactly is happening when I unproject with the mouse3D and camera and then create the Ray. Does the ray depend on the call to 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);
}
question from:https://stackoverflow.com/questions/11036106/three-js-projector-and-ray-objects

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
146 views
Welcome To Ask or Share your Answers For Others

1 Answer

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

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.

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;

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

projector.unprojectVector(mouse3D, camera);

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...