Search code examples
animationthree.jstranslate-animationlerp

Threejs lerp, lerpVectors work without animation


I am trying to move 10 meshes in different directions after some amount of time through functions lerp, lerpVectors. Both of them gave me the same result, they just teleported meshes in new positions without animation of moving there. Here is my code (with "lerp"):

 var newPos;
 var timer = 0;
 function render() {
  if (timer === 120) {
    for (var i = 0; i < count; i++) {
      mesh = meshes[i];
      newPos = new THREE.Vector3(Math.random() * 200 - 100, Math.random() * 200 - 100, Math.random() * 200 - 100);
      mesh.position.lerp(newPos, 0.5);
    }
  }

  timer++;
  renderer.render(scene, camera);
}

I am sure there is another way through calculated distances and then decreasing them to 0. But I suppose lerp and leprVectors do the same thing, so the question is what I do wrong?

r83

Maybe these both functions work not as I expect.


Solution

  • Okay, I've just figured out where was the problem. Lerp in the official documentation looks as .lerp(v3, alpha) and the value alpha should changing dynamically, so I added clock:

    var delta = clock.getDelta();
    

    and alpha now:

    alpha += delta;
    

    also I added boolean variable to the each mesh to check whether it's enough to do lerp or not, moreover, I set a new position during initiating for each of them as a parameter like so:

    mesh.newPosition = new THREE.Vector3(
          Math.random() * 200 - 100, Math.random() * 200 - 100, Math.random() * 200 - 100
        );
    

    and as a result I updated my render function:

    var timer = 0;
    var alpha = 0;
    var delta;
    var currentX, currentY, currentZ;
    
    function render() {
      delta = clock.getDelta();
      for (var i = 0; i < count; i++) {
        mesh = meshes[i];
    
        if (timer === 120) {
          mesh.endTransition = false;
        }
    
        if (!mesh.endTransition ) {
          currentX = Math.abs(mesh.newPosition.x - mesh.position.x);
          currentY = Math.abs(mesh.newPosition.y - mesh.position.y);
          currentZ = Math.abs(mesh.newPosition.z - mesh.position.z);
    
          if (currentX >= 1 || currentY >= 1 || currentZ >= 1) {
            alpha += delta;
            mesh.position.lerp(mesh.newPosition, alpha);
          } else {
            mesh.endTransition = true;
          }
        }
      }
    
      timer++;
      renderer.render(scene, camera);
    }
    

    Perhaps my solution can be improved.