Click and zoom like google earth

Hi I’m using perspective camera and orbit control trying to double click and then zoom in like google earth. (It’s not like annotation which you know exactly where to move, just random click on anywhere)

I first have mouse click event listener and can find mouse position by:

var intersects = raycaster.intersectObjects(sceneObjects, true);
                if (intersects.length > 0) {
                    var p = intersects[ 0 ].point;
}

I think this intersects[ 0 ].point is camera position? but then how to find target position for camera to move accurately?

for moving I use Tween.js or setLookat() from camera-control it’s not a problem, the key is how to find camera position and target position? unless it doesn’t have to have these two points to achieve what I want.

Thanks

intersects[ 0 ].point is new target

try using Vector3.lerpVectors

newCameraPosition.lerpVectors(camera.position, intersects[ 0 ].point, 0.5) should give you the midway point

Thanks for your reply, I’m a bit unclear about newCameraPosition which has lerpVectors methods. I guess it’s part of my question, how do you find new camera position?

const newCameraPosition=new THREE.Vector3() is a reusable vector3 used for calculation purpose

after performing the lerpVectors thing the x,y,z will be updated , you can animate your camera to that location

the docs https://threejs.org/docs/#api/en/math/Vector3 contain everything you can do with a THREE.Vector 3

1 Like

Thank you so much! it works really well. Can I also ask why is new camera position the mid way of current camera position and target position? using vector3 lerp() never came cross my mind

You might like to check out my project here:

https://www.project-atlantis.com/wp-content/threejs-simulation/TetheredRing/index.html

The technique that I used triggers a state machine triggers when the user approaches the Earth’s surface. A transition then occurs which changes the orbit controls target and up direction. Reverse transition is also supported. (Note: I had to customize orbit controls to add “up direction” support)

the last 0.5 means halfway point,

by changing this value from 0 to 1 you are basically getting every point along the 2 points in 3d space, 0 is first point and 1 means last point

@orion_prime @paramfoo I am trying to achieve the same functionality using three js and tween js. The intersect[0].points is given me the right vector as well. I want to zoom to that specific/target point if user double clicks anywhere in the canvas. I am using a Perspective Camera.

This is what I tried:

 this.canvas.nativeElement.addEventListener("dblclick", (ev:MouseEvent) => {
      ev.preventDefault()
      const newCameraPosition=new THREE.Vector3()
    this.mouse.x = (ev.clientX / window.innerWidth) * 2 - 1
    this.mouse.y = -(ev.clientY / window.innerHeight) * 2 + 1

    
    this.raycaster.setFromCamera(this.mouse, this.camera)

    var intersects = this.raycaster.intersectObjects(this.scene.children, false)
   
    if (intersects.length > 0) {
      const p = newCameraPosition.lerpVectors(this.camera.position, intersects[0].point, 0.5) 
     
      var positionX = p.x
      var positionY = p.y
      var positionZ = p.z + 1000   
      var positionStart = this.camera.position
      var positionEnd = { x : positionX, y: positionY, z: positionZ }
      
      new TWEEN.Tween(positionStart).to(positionEnd, 2000).easing(TWEEN.Easing.Linear.None).start()
      
      var rotationX = p.x
      var rotationY = p.y
      var rotationZ = p.z

      var rotationStart = this.orbitControls.target
      var rotationEnd = { x : rotationX, y: rotationY, z: rotationZ }
      
      new TWEEN.Tween(rotationStart).to(rotationEnd, 2000).easing(TWEEN.Easing.Linear.None).onUpdate(()=>{
        this.camera.lookAt( newCameraPosition )
        this.render()
      }).
      start()
    }
 
    });

Not sure what am I doing wrong. I am loading a PCD file and the output is below:


Your help on this is appreciated.