New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Camera animation [startPos - endPos] with THREE.PathControls #1689

Closed
libe opened this Issue Apr 11, 2012 · 6 comments

Comments

Projects
None yet
6 participants
@libe

libe commented Apr 11, 2012

Hi,

I am trying to understand if I can use THREE.PathControls to animate camera position in this scenario: basically I have a startPosition and an endPosition and the animation should be on a straight line without changing the orientation of the camera.

I also need to be notified when the animation ends with an event in order to set up a few other things.

Is THREE.PathControls the right component to use or three.js has something which is a better fit for this task?

Thanks

@worldswidestweb

This comment has been minimized.

Show comment
Hide comment
@worldswidestweb

worldswidestweb commented Apr 11, 2012

@libe

This comment has been minimized.

Show comment
Hide comment
@libe

libe Apr 11, 2012

Thanks for the great tip, worked really well. Below how I did it:

View3D.prototype.onCameraAnimUpdate = function ()
{
    var currentPos = Util.lerp(this.startPos, this.endPos, this.param.t);
    var currentLookAt = Util.lerp(this.startLookAt, this.endLookAt, this.param.t);
    this.camera.position.set(currentPos.x, currentPos.y, currentPos.z);
    this.camera.lookAt(currentLookAt);      
}

View3D.prototype.onCameraAnimComplete = function ()
{
    this.createControlsForCamera();
    this.controls.target = this.endLookAt;
}


View3D.prototype.fitAll = function (viewToFit, center, radius, animate)
{               
    var radius = radius;
    var aabbCenter = center;

    // Compute offset needed to move the camera back that much needed to center AABB (approx: better if from BB front face)
    var offset = radius / Math.tan(Math.PI / 180.0 * 25 * 0.5); 

    // Compute new camera direction and position
    var dir = new THREE.Vector3(0.0, 0.0, 1.0);
    if (this.camera != undefined)
        dir = this.camera.matrix.getColumnZ();
    dir.multiplyScalar(offset); 
    var newPos = new THREE.Vector3();
    newPos.add(aabbCenter, dir);

    // Update camera
    if (!animate)
    {
        this.camera.position.set(newPos.x, newPos.y, newPos.z);
        this.camera.lookAt(aabbCenter);                     
        this.createControlsForCamera();
        this.controls.target = aabbCenter;
    }
    else
    {
        this.startPos = this.camera.position.clone();
        this.startLookAt = this.controls.target;
        this.endPos = newPos;
        this.endLookAt = aabbCenter;

        this.param = {t: 0};
        this.anim = new TWEEN.Tween(this.param).to({t: 1.0}, 500 ).easing( TWEEN.Easing.Sinusoidal.EaseInOut);

        this.anim.onUpdate(Util.bind(this, this.onCameraAnimUpdate));
        this.anim.onComplete(Util.bind(this, this.onCameraAnimComplete));
        this.anim.start();
    } 
}

libe commented Apr 11, 2012

Thanks for the great tip, worked really well. Below how I did it:

View3D.prototype.onCameraAnimUpdate = function ()
{
    var currentPos = Util.lerp(this.startPos, this.endPos, this.param.t);
    var currentLookAt = Util.lerp(this.startLookAt, this.endLookAt, this.param.t);
    this.camera.position.set(currentPos.x, currentPos.y, currentPos.z);
    this.camera.lookAt(currentLookAt);      
}

View3D.prototype.onCameraAnimComplete = function ()
{
    this.createControlsForCamera();
    this.controls.target = this.endLookAt;
}


View3D.prototype.fitAll = function (viewToFit, center, radius, animate)
{               
    var radius = radius;
    var aabbCenter = center;

    // Compute offset needed to move the camera back that much needed to center AABB (approx: better if from BB front face)
    var offset = radius / Math.tan(Math.PI / 180.0 * 25 * 0.5); 

    // Compute new camera direction and position
    var dir = new THREE.Vector3(0.0, 0.0, 1.0);
    if (this.camera != undefined)
        dir = this.camera.matrix.getColumnZ();
    dir.multiplyScalar(offset); 
    var newPos = new THREE.Vector3();
    newPos.add(aabbCenter, dir);

    // Update camera
    if (!animate)
    {
        this.camera.position.set(newPos.x, newPos.y, newPos.z);
        this.camera.lookAt(aabbCenter);                     
        this.createControlsForCamera();
        this.controls.target = aabbCenter;
    }
    else
    {
        this.startPos = this.camera.position.clone();
        this.startLookAt = this.controls.target;
        this.endPos = newPos;
        this.endLookAt = aabbCenter;

        this.param = {t: 0};
        this.anim = new TWEEN.Tween(this.param).to({t: 1.0}, 500 ).easing( TWEEN.Easing.Sinusoidal.EaseInOut);

        this.anim.onUpdate(Util.bind(this, this.onCameraAnimUpdate));
        this.anim.onComplete(Util.bind(this, this.onCameraAnimComplete));
        this.anim.start();
    } 
}
@mrdoob

This comment has been minimized.

Show comment
Hide comment
@mrdoob

mrdoob Apr 11, 2012

Owner

Yay! ^^

Owner

mrdoob commented Apr 11, 2012

Yay! ^^

@mrdoob mrdoob closed this Apr 11, 2012

@refset

This comment has been minimized.

Show comment
Hide comment
@refset

refset Nov 3, 2012

libe - thanks so much for leaving the code!!

It only took me a few minutes to get it all working perfectly :)

....

function lerp (a,b,f)
{
ret = new THREE.Vector3();
ret.x = a.x + f * (b.x - a.x);
ret.y = a.y + f * (b.y - a.y);
ret.z = a.z + f * (b.z - a.z);
return ret;
}

refset commented Nov 3, 2012

libe - thanks so much for leaving the code!!

It only took me a few minutes to get it all working perfectly :)

....

function lerp (a,b,f)
{
ret = new THREE.Vector3();
ret.x = a.x + f * (b.x - a.x);
ret.y = a.y + f * (b.y - a.y);
ret.z = a.z + f * (b.z - a.z);
return ret;
}

@nordicskiah

This comment has been minimized.

Show comment
Hide comment
@nordicskiah

nordicskiah Nov 3, 2012

There are a number of nice options with tween 😃 Using the elastic easing is pretty crazy on a camera, haha

var position = new THREE.Vector3(0,0*CNspacing+350,600);
var target = new THREE.Vector3(0,0*CNspacing,0);
function tweenCamera(position, target){
new TWEEN.Tween( camera.position ).to( {
        x: position.x,
        y: position.y,
        z: position.z}, 600 )
    .easing( TWEEN.Easing.Sinusoidal.EaseInOut).start();
new TWEEN.Tween( controls.target ).to( {
        x: target.x,
        y: target.y,
        z: target.z}, 600 )
    .easing( TWEEN.Easing.Sinusoidal.EaseInOut).start();
}

nordicskiah commented Nov 3, 2012

There are a number of nice options with tween 😃 Using the elastic easing is pretty crazy on a camera, haha

var position = new THREE.Vector3(0,0*CNspacing+350,600);
var target = new THREE.Vector3(0,0*CNspacing,0);
function tweenCamera(position, target){
new TWEEN.Tween( camera.position ).to( {
        x: position.x,
        y: position.y,
        z: position.z}, 600 )
    .easing( TWEEN.Easing.Sinusoidal.EaseInOut).start();
new TWEEN.Tween( controls.target ).to( {
        x: target.x,
        y: target.y,
        z: target.z}, 600 )
    .easing( TWEEN.Easing.Sinusoidal.EaseInOut).start();
}
@bevlison

This comment has been minimized.

Show comment
Hide comment
@bevlison

bevlison Feb 24, 2016

a changed TWEEN function name delivers error :

Uncaught TypeError: _easingFunction is not a function

using the above sample code.

The cause is the fact that TWEEN.Easing.Sinusoidal.EaseInOut is renamed to TWEEN.Easing.Sinusoidal.InOut

Easy one, but knowing this may help...

bevlison commented Feb 24, 2016

a changed TWEEN function name delivers error :

Uncaught TypeError: _easingFunction is not a function

using the above sample code.

The cause is the fact that TWEEN.Easing.Sinusoidal.EaseInOut is renamed to TWEEN.Easing.Sinusoidal.InOut

Easy one, but knowing this may help...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment