Skip to main content
Rewordings for more clarity
Source Link
Chaosed0
  • 773
  • 5
  • 17

With this knowledge, we move on to solving problem #1: what pointground position is the mouse is over? First, we get the location of the mouse in world-space:

Then we obtain the direction of the ray under the mouse by adding a bit of depth to get a point a bit "more under" the mouse, and subtracting that from the world position:

Now, we solve problem #2: how much to move the camera? This ends up being fairly easy nownow that we have the above formula for obtaining the ground position under the mouse. The algorithm goes like this:

  • When mouse down is detected:
    • Record mouseDownPosition, the current ground position under the mouse (calculated above)
    • Record mouseDownCameraPosition, the current position of the camera
  • When a mouse move is detected:
    • Obtain the new ground position under the mouse and subtract it from mouseDownPosition.
    • Subtract this resultthat from mouseDownCameraPosition.
    • Set camera.position fromto this newfinal result.

With this knowledge, we move on to solving problem #1: what point the mouse is over? First, we get the location of the mouse in world-space:

Then we obtain the direction of the ray under the mouse by adding a bit of depth to get a point a bit "more under" the mouse, and subtracting that from the world position:

Now, we solve problem #2: how much to move the camera? This ends up being fairly easy now that we have the above formula. The algorithm goes like this:

  • When mouse down is detected:
    • Record mouseDownPosition, the position under the mouse (calculated above)
    • Record mouseDownCameraPosition, the current position of the camera
  • When a mouse move is detected:
    • Obtain the new position under the mouse and subtract it from mouseDownPosition.
    • Subtract this result from mouseDownCameraPosition.
    • Set camera.position from this new result.

With this knowledge, we move on to solving problem #1: what ground position is the mouse is over? First, we get the location of the mouse in world-space:

Then we obtain the direction of the ray under the mouse by adding a bit of depth to get a point "more under" the mouse, and subtracting that from the world position:

Now, we solve problem #2: how much to move the camera? This ends up being fairly easy now that we have the above formula for obtaining the ground position under the mouse. The algorithm goes like this:

  • When mouse down is detected:
    • Record mouseDownPosition, the current ground position under the mouse
    • Record mouseDownCameraPosition, the current position of the camera
  • When a mouse move is detected:
    • Obtain the new ground position under the mouse and subtract it from mouseDownPosition.
    • Subtract that from mouseDownCameraPosition.
    • Set camera.position to this final result.
Bounty Awarded with 100 reputation awarded by Lucien
Clarification
Source Link
Chaosed0
  • 773
  • 5
  • 17

With this knowledge, we move on to solving problem #1: what point the mouse is over? This is where the Raycaster might come in handy, but if you have variable-height terrain it won't work - it will break our first constraint above. With that in mind, I've chosen to calculate the intersection point myself.

First, we get the location of the mouse in world-space:


As a final note, I think the Raycaster can aid in the case where there's variable-height terrain, i.e. where we don't know what planeY above should be upon mousedown. However, we still need to calculate the ray/plane intersection when the mouse moves, with planeY set to the Y of the point the raycaster found. Otherwise, our first constraint (keep camera at constant height) will be broken.

With this knowledge, we move on to solving problem #1: what point the mouse is over? This is where the Raycaster might come in handy, but if you have variable-height terrain it won't work - it will break our first constraint above. With that in mind, I've chosen to calculate the intersection point myself.

First, we get the location of the mouse in world-space:

With this knowledge, we move on to solving problem #1: what point the mouse is over? First, we get the location of the mouse in world-space:


As a final note, I think the Raycaster can aid in the case where there's variable-height terrain, i.e. where we don't know what planeY above should be upon mousedown. However, we still need to calculate the ray/plane intersection when the mouse moves, with planeY set to the Y of the point the raycaster found. Otherwise, our first constraint (keep camera at constant height) will be broken.

Source Link
Chaosed0
  • 773
  • 5
  • 17

Here is a fiddle hopefully demonstrating the effect you want to achieve. It can get quite jittery on different machines - likely because of javascript nuances I'm not familiar with - but I think it's close to what you're looking for.

https://jsfiddle.net/chaosed0/b4cqktan/37/


Here is an explanation of the math involved. We have two constraints:

  • Keep the camera at a constant height.
  • While the mouse cursor is down, "move" the ground to keep the same location under the cursor at all times.

"Move" is in quotes because we don't want to move the ground, we want to move the camera. Thing is, moving the camera in the opposite direction we would move the ground has the exact same effect, and I find it more intuitive to picture it as if the ground were moving.

With this knowledge, we move on to solving problem #1: what point the mouse is over? This is where the Raycaster might come in handy, but if you have variable-height terrain it won't work - it will break our first constraint above. With that in mind, I've chosen to calculate the intersection point myself.

First, we get the location of the mouse in world-space:

var mouseScreenPos = new THREE.Vector3();
mouseScreenPos.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouseScreenPos.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

var rayOrigin = (new THREE.Vector3(mouseScreenPos.x, mouseScreenPos.y, 0.0)).unproject(camera);

Then we obtain the direction of the ray under the mouse by adding a bit of depth to get a point a bit "more under" the mouse, and subtracting that from the world position:

var rayPos1 = (new THREE.Vector3(mouseScreenPos.x, mouseScreenPos.y, 1.0)).unproject(camera);
var rayDirection = rayPos1.sub(rayOrigin);

Finally, we can use these two points to get the location in space we want to hold constant. For my purposes I'm calculating where the ray intersects the XZ plane at y = -5, but this may differ for you depending on where your objects are located.

var ySlope = (planeY - rayOrigin.y) / rayDirection.y;
var xIntersect = rayDirection.x * ySlope + rayOrigin.x;
var zIntersect = rayDirection.z * ySlope + rayOrigin.z;
  
return new THREE.Vector3(xIntersect, planeY, zIntersect);

Now, we solve problem #2: how much to move the camera? This ends up being fairly easy now that we have the above formula. The algorithm goes like this:

  • When mouse down is detected:
    • Record mouseDownPosition, the position under the mouse (calculated above)
    • Record mouseDownCameraPosition, the current position of the camera
  • When a mouse move is detected:
    • Obtain the new position under the mouse and subtract it from mouseDownPosition.
    • Subtract this result from mouseDownCameraPosition.
    • Set camera.position from this new result.