Orthographic Camera and pickingRay?

1.3k views Asked by At

I tried to implement a function to select and move objects in a stage compound of an orthographic camera.

I'd like to get the same example as : http://threejs.org/examples/webgl_interactive_draggablecubes.html

but not with perspective camera.

I already replaced :

var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );

with :

var camera =  new THREE.OrthographicCamera(window.innerWidth / -zoom, window.innerWidth / zoom, window.innerHeight / zoom, window.innerHeight / -zoom, -1000, 1000);

and replaced this :

var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

by this :

var ray = projector.pickingRay( vector, camera );

But, it does not seem to be enough to run.

So, what's it lack ?

Is it possible to use Projector and Ray with OrthographicCamera ??

Thanks.

3

There are 3 answers

0
Ben On

In April 2022, the following works for me to detect clicks when using an orthographic camera.

Orthographic camera:

const camera = new THREE.OrthographicCamera(
    window.innerWidth / -2,
    window.innerWidth / 2,
    window.innerHeight / 2,
    window.innerHeight / -2,
    -1000,
    1000
);
camera.position.y = 20;
camera.zoom = 50;
camera.updateProjectionMatrix();

Click handler:

renderer.domElement.addEventListener('pointerdown', (event) => {

    const mouse = new THREE.Vector2();
    mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
    mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
    
    const raycaster = new THREE.Raycaster();
    raycaster.setFromCamera(mouse, camera);

    const intersects = raycaster.intersectObjects(scene.children);
    console.log("Intersects:", intersects);
});
1
NinhKu On

Please try this code in your sample:

event.preventDefault();
    if (event.button === 0) {

        var projector = new THREE.Projector();
        var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
        // use picking ray since it's an orthographic camera
        var raycaster = projector.pickingRay(vector, camera);
        //ditermine whether any of the supplied objects are hit by this ray    
        var intersertsObj = raycaster.intersectObjects(_entities);
        // _entities : is array entities you put to scence
        // you can store this list before you entity to scence: 
        // _entities.push(entity);
        // scene.add(entity);
        if (intersertsObj.length > 0) {           
            var pickedObject = intersertsObj[0];               
        }       
    }
    event = null;

it is works fine in my project.

0
Vidar On

There is a function Raycaster.setFromCamera() that was introduced after this question was originally asked. It handles orthographic cameras specifically, so I think that is now the preferred way to solve this issue.