title: Three.js Projector and Ray objects
body: <p>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.</p>
  
  <p><strong>What exactly is happening and what is the difference between Projector.projectVector() and Projector.unprojectVector()?</strong> 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. <strong>When would you use projectVector?</strong></p>
  
  <p>I am using the following code in this <strong><a href="http://cmg0030.zxq.net/threejs/acclDemo7/">demo</a></strong> to spin the cube when dragged on with the mouse. <strong>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()</strong></p>
  
  <pre><code>/** 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 &gt; 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 &gt; 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);
  }
  </code></pre>