1

I have this code that works well:

function onMouseMove( event ) {

        window.onmousedown = function() { 

            var canvasPosition =    renderer.domElement.getBoundingClientRect();

            var mouseX = event.clientX - canvasPosition.left;
            var mouseY = event.clientY - canvasPosition.top;

            var mouseVector = new THREE.Vector3 (
                            2 * (mouseX / window.innerWidth) - 1,
                    1 - 2 * (mouseY / window.innerHeight), 1);

            mouseVector.unproject( camera );
            var dir = mouseVector.sub( camera.position ).normalize();
            var distance = - camera.position.z / dir.z;
            var pos = camera.position.clone().add( dir.multiplyScalar( distance ) );


            camera.getWorldDirection();

            camera.lookAt( pos );
            // camera.updateMatrixWorld(true);

            console.log(mouseVector);
            console.log(mouseX);
            console.log(mouseY);

            // render();

        }
  }

But I would like to smooth the movement. So I found the following code from the tween example, but not sure how to use it. In the above code, I get current camera lookat from one place, one format, and put the new camera look at in camera.lookat in a different format - neither of which seem to be standard x,y,z.

In the below code, the tween would have me change an properties (x,y,z) on a single item. which the unprojecting and normalizing of the camera do not accommodate:

new TWEEN.Tween( intersects[ 0 ].object.position )
  .to( { 
    x: Math.random() * 800 - 400, 
    y: Math.random() * 800 - 400, 
    z: Math.random() * 800 - 400 
  }, 2000 )
  .easing( TWEEN.Easing.Elastic.Out)
  .start();

If there is a breakdown or something I can read, or actually work out problems to understand, I'd be grateful. I've read camera tutorials and matrix tutorials over and over for years, but my brain just can't comprehend it.

I've been digging around here quite a bit, but nothing addresses a camera tween - at least for a valid version of threejs

Thank you!

Martin Schuhfuß
  • 6,814
  • 1
  • 36
  • 44
edasac
  • 31
  • 1
  • 5
  • 1
    From the example it isn't really clear what you want to do. Could you add a paragraph to that effect? There seems to be something odd with how you compute that lookAt-position, but I can't tell what it is, because I don't know how it's supposed to work. – Martin Schuhfuß Jun 26 '17 at 21:23
  • I'm trying to smooth the transition of camera lookat. Regarding threejs, I'm using an orbit control example, but instead of the mouse movement changing what the camera is looking at, I click on an area and the camera looks at that area. I just want to smooth that action.But after the replies, I'm even not sure what camera.lookat really is. – edasac Jun 27 '17 at 12:42
  • That is quickly answered: `object3d.lookAt()` is a function that updates the object's rotation (more precisely it's `quaternion`) to make the object face the specified point while maintaining a specified up-direction. – Martin Schuhfuß Jun 28 '17 at 14:32

2 Answers2

4

I recommend you get acquainted with linear interpolation, or more commonly known as "lerp". The THREE.Vector3 class has a lerp function that you could use to interpolate between a starting point and an ending point:

var camPos = new THREE.Vector3(0, 0, 0);       // Holds current camera position
var targetPos = new THREE.Vector3(10, 10, -10);// Target position
var origin = new THREE.Vector3(0, 0, 0);       // Optional origin

function animate(){
    // Interpolate camPos toward targetPos
    camPos.lerp(targetPos, 0.05);

    // Apply new camPos to your camera
    camera.position.copy(camPos);

    // (Optional) have camera look at the origin after it's been moved
    camera.lookAt(origin);

    // render();
}

In the above example, your animate() function is called once per frame, and the camera will travel 5% towards targetPos per frame.

If you change targetPos, the camera will animate towards its new target value.

I recommend you first get acquainted with lerping before you start bringing in third-party libraries like TWEEN.js or others.

M -
  • 26,908
  • 11
  • 49
  • 81
  • Thank you Marco! I'm weak in all of this. In your example, you have camera target position. I don't think I need to move the camera for what I'm trying to do? I will later on, but does changing what the camera looks at require a position change? I will try LERP as that sounds like what I'm asking for. thank you again! – edasac Jun 27 '17 at 12:46
  • Sigh... So you do the interpolation, which is good. Then you move the camera to the new camPos - which seems to defeat the prior interpolation. – edasac Jun 27 '17 at 13:08
  • No, `camPos` is just a Vector3, it's not the camera. So, you first have to update the position of the Vector3 towards its target with `camPos.lerp()`, and then in the next line, you update the camera to that new position. If you don't update the camera's position on each frame, you won't see any animation. – M - Jun 27 '17 at 18:06
  • Can someone tell me why I get all of these crazy movements? [link](https://codepen.io/ndsp/pen/YQavxG). The smaller the interpolation factor, the crazier it gets. – edasac Jul 04 '17 at 14:37
  • Sorry, I can't help you there. I only see a black canvas, and there are too many things going on in your code to spend time trying to figure it out. I suggest you isolate the problem into a simple example, and then ask your question. – M - Jul 06 '17 at 00:59
0

just for smoothing the movement, this might already help you:

// keep this outside of the event-handler
var lookAtPosition = new THREE.Vector3();
var lookAtTween = new TWEEN.Tween(lookAtPosition);

// as lookAt is not a property we can assign to we need to 
// call it every time the tween was updated:
lookAtTween.onUpdate(function() {
  camera.lookAt(lookAtPosition);
});

window.onmousedown = function() { 
  // do your thing to compute pos
  // instead of `camera.lookAt(pos)`, do this:
  lookAtTween
    .stop() // just in case it's still animating
    .to(pos, 500) // set destination and duration
    .start(); // start the tween
};
Martin Schuhfuß
  • 6,814
  • 1
  • 36
  • 44