2
votes

Example JSfiddle

I can get my cone to point at each target sphere in turn (red,green,yellow,blue) using the THREE.js "lookAt" function.

// Initialisation

c_geometry = new THREE.CylinderGeometry(3, 40, 120, 40, 10, false);
c_geometry.applyMatrix( new THREE.Matrix4().makeRotationX( Math.PI / 2 ) );
c_material = new THREE.MeshNormalMaterial()
myCone = new THREE.Mesh(c_geometry, c_material);
scene.add(myCone);

// Application (within the Animation loop)

myCone.lookAt(target.position); 

But now I want the cone to pan smoothly and slowly from the old target to the new target. I guess that I can do it by computing intermediate points on the circular arc which is centred at the cone centre Cxyz and which passes from the previous target position Pxyz to the new target position Nxyz.

Please can someone point me to suitable: (a) utilities or (b) trigonometry algorithms or (c) code examples for calculating the xyz coordinates of the intermediate points on such an arc? (I will supply the angular increment between points based on desired sweep rate and time interval between frames).

2

2 Answers

3
votes

If you want to smoothly transition from one orientation to another, you can use THREE.Quaternion.slerp().

In your case, you would pre-calculate the target quaternions:

myCone.lookAt( s1.position ); 
q1 = new THREE.Quaternion().copy( myCone.quaternion );

myCone.lookAt( s2.position );
q2 = new THREE.Quaternion().copy( myCone.quaternion );

Then, in you render loop you use slerp():

THREE.Quaternion.slerp( q1, q2, myCone.quaternion, time ); // 0 < time < 1

Modified fiddle to demonstrate the concept: http://jsfiddle.net/1dtx78bj/22/.

three.js r.71

0
votes

For those of you looking to lerp position and lookAt, you can create a initial lookAt target from the current look direction and lerp that towards the final target:

function MoveWhileLookingAt(object: Object3D, destination: Vector3, lookAt: Vector3){
  const fromPosition = object.position.clone();
  const fromLookAt = new Vector3(
    0,
    .1, // To avoid initial camera flip on certain starting points (like top down view)
    -object.position.distanceTo(lookAt) // THREE.Camera looks down negative Z. Remove the minus if working with a regular object.
  );
  object.localToWorld(fromLookAt);
  const tempTarget = fromLookAt.clone();
  function LookAtLerp(alpha: number){
    // This goes in your render loop
    object.position.lerpVectors(fromPosition, destination, alpha);
    tempTarget.lerpVectors(fromLookAt, lookAt, alpha);
    object.lookAt(tempTarget);
  }
}