18

I'm new in THREE.js.

I'm trying to get 3D coordinates of point on mouse click on the object (not simple objects: Box, Sphere,..) in Canvas.

In detail, I'm working with 3D objects viewer - I have camera (THREE.PerspectiveCamera), mouse controls (rotate, zoom, move), add/remove objects (my own object, loaded using loaders for THREE.js) in scene,.. And I want to add a function, which gets 3D coordinates for clicked point in 3D.

Exactly, I want coordinates of the end point of a ray - begining from mouse click on the camera_near_window and ending to the object's point, I've clicked on..

I tried a lot of ways to do it:

Can anyone show me the demo code which gets 3D point coords for clicked point of clicking object in 3D, please..?

Community
  • 1
  • 1
GuRAm
  • 711
  • 1
  • 6
  • 20
  • 2
    See [this answer](http://stackoverflow.com/a/18553739/1461008) for how to use `Raycaster`. In your case, you likely want to set the `recursiveFlag` to true: `raycaster.intersectObjects( objects, true );` – WestLangley Jan 09 '16 at 20:34
  • Oh, this is what I was looking for. `raycaster.intersectObjects(objects, true)` got me an array and the first record had a point parameter, which I needed, thanks.. – GuRAm Jan 10 '16 at 07:48
  • Use the pattern in the answer I linked to. Do not instantiate a new raycaster with each click. – WestLangley Jan 10 '16 at 16:38
  • Ok. As you said, I declared Raycaster (`var rayCaster = new THREE.Raycaster();`) next to camera declaration, and then I use *set* (`rayCaster.set(camera.position, vector.sub(camera.position).normalize());`) every mouse click; is it right? – GuRAm Jan 11 '16 at 05:55
  • I suggested you follow the pattern in the answer I linked to. You do not appear to have done that. But it is up to you. – WestLangley Jan 11 '16 at 16:05
  • At first, I didn't understand that pattern.. Now I changed my code with it and works fine. I changed my "Answer" too. Thanks. – GuRAm Jan 13 '16 at 05:54

1 Answers1

21

So, as I think this question is useful for someone, I'll answer it myself (I'll write my resolve):

var renderer, canvas, canvasPosition, camera, scene, rayCaster,  mousePosition;

function init() {
    renderer = new THREE.WebGLRenderer({ antialias: false });
    canvas = renderer.domElement;
    canvasPosition = $(canvas).position();
    camera = new THREE.PerspectiveCamera(20, $(canvas).width() / $(canvas).height(), 0.01, 1e10);
    scene = new THREE.Scene();
    rayCaster = new THREE.Raycaster();
    mousePosition = new THREE.Vector2();

    scene.add(camera);

    var myObjects = new THREE.Object3D();
    // myObjects.add( your object );
    // myObjects.add( your object );
    // myObjects.add( your object );
    myObjects.name = 'MyObj_s';
    scene.add(myObjects);
};

function getClicked3DPoint(evt) {
    evt.preventDefault();

    mousePosition.x = ((evt.clientX - canvasPosition.left) / canvas.width) * 2 - 1;
    mousePosition.y = -((evt.clientY - canvasPosition.top) / canvas.height) * 2 + 1;

    rayCaster.setFromCamera(mousePosition, camera);
    var intersects = rayCaster.intersectObjects(scene.getObjectByName('MyObj_s').children, true);

    if (intersects.length > 0)
        return intersects[0].point;
};
GuRAm
  • 711
  • 1
  • 6
  • 20