Detect clicked object in THREE.js

后端 未结 4 2219
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-01 01:20

I have a THREE.js scene where a lot of elements appear, and I need to detect what object the user is clicking on.

What I have done so far is the following. The camer

相关标签:
4条回答
  • 2020-12-01 01:58

    I ran into problems trying to implement this for a canvas which does not take up the entire width and height of the screen. Here is the solution I found works quite well.

    Initialize everything on an existing canvas:

    var init = function() {
      var canvas_model = document.getElementById('model')
      var viewSize = 50 // Depending on object size, canvas size etc.
      var camera = new THREE.OrthographicCamera(-canvas_model.clientWidth/viewSize, canvas_model.clientWidth/viewSize, canvas_model.clientHeight/viewSize, -canvas_model.clientHeight/viewSize, 0.01, 2000),
    }
    

    Add an event listener to the canvas:

    canvas_model.addEventListener('click', function(event){
      var bounds = canvas_model.getBoundingClientRect()
      mouse.x = ( (event.clientX - bounds.left) / canvas_model.clientWidth ) * 2 - 1;
      mouse.y = - ( (event.clientY - bounds.top) / canvas_model.clientHeight ) * 2 + 1;
      raycaster.setFromCamera( mouse, camera );
      var intersects = raycaster.intersectObjects(scene.children, true);
      if (intersects.length > 0) {
         // Do stuff
      }
    }, false)
    

    Or for a 'touchstart' event, change the lines calculating the mouse.x and mouse.y into:

    mouse.x = ( (event.touches[0].clientX - bounds.left) / canvas_model.clientWidth ) * 2 - 1;
    mouse.y = - ( (event.touches[0].clientY - bounds.top) / canvas_model.clientHeight ) * 2 + 1;
    
    0 讨论(0)
  • 2020-12-01 02:12

    Depends on what kind of camera are you using.

    1) PerspectiveCamera: is ok link that Mr.doob provides.
    2) OrthographicCamera: is quite different:

    var init = function() {
      camera = new THREE.OrthographicCamera( SCREEN_WIDTH / - 2, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_HEIGHT / - 2, NEAR, FAR);
      document.addEventListener( 'mousedown', onDocumentMouseDown, false );
    }
    
    function onDocumentMouseDown( e ) {
      e.preventDefault();
      var mouseVector = new THREE.Vector3();
      mouseVector.x = 2 * (e.clientX / SCREEN_WIDTH) - 1;
      mouseVector.y = 1 - 2 * ( e.clientY / SCREEN_HEIGHT );
      var raycaster = projector.pickingRay( mouseVector.clone(), camera );
      var intersects = raycaster.intersectObject( TARGET );
      for( var i = 0; i < intersects.length; i++ ) {
        var intersection = intersects[ i ],
        obj = intersection.object;
        console.log("Intersected object", obj);
      }
    }
    
    0 讨论(0)
  • 2020-12-01 02:13

    Checks for intersection of the mouse and any of the Cubes in 3d space and alters it's color. Maybe this help you.

    0 讨论(0)
  • 2020-12-01 02:14

    Check out this one:

    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 5000);
    var object; //your object
    
    document.addEventListener('mousedown', onMouseDown, false);
    
    function onMouseDown(e) {
        var vectorMouse = new THREE.Vector3( //vector from camera to mouse
            -(window.innerWidth/2-e.clientX)*2/window.innerWidth,
            (window.innerHeight/2-e.clientY)*2/window.innerHeight,
            -1/Math.tan(22.5*Math.PI/180)); //22.5 is half of camera frustum angle 45 degree
        vectorMouse.applyQuaternion(camera.quaternion);
        vectorMouse.normalize();        
    
        var vectorObject = new THREE.Vector3(); //vector from camera to object
        vectorObject.set(object.x - camera.position.x,
                         object.y - camera.position.y,
                         object.z - camera.position.z);
        vectorObject.normalize();
        if (vectorMouse.angleTo(vectorObject)*180/Math.PI < 1) {
            //mouse's position is near object's position
    
        }
    }
    
    0 讨论(0)
提交回复
热议问题