I would like to animate a bezier curve in ThreeJS. The start, end and control points will update. Eventually I will need to have many curves animating at once. What's the most efficient way to do this?
If you run the code snippet below, you'll see that I'm creating the Bezier object, Geometry and Line each time the frame renders. I'm removing the previous line from the scene and then adding the new, updated line. Is there a better way? Perhaps updating only the geometry and not adding the line again?
var camera, scene, renderer, geometry, material, mesh;
init();
animate();
/**
Create the scene, camera, renderer
*/
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);
addCurve();
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
/**
Add the initial bezier curve to the scene
*/
function addCurve() {
testPoint = 0;
curve = new THREE.CubicBezierCurve3(
new THREE.Vector3( testPoint, 0, 0 ),
new THREE.Vector3( -5, 150, 0 ),
new THREE.Vector3( 20, 150, 0 ),
new THREE.Vector3( 10, 0, 0 )
);
curveGeometry = new THREE.Geometry();
curveGeometry.vertices = curve.getPoints( 50 );
curveMaterial = new THREE.LineBasicMaterial( { color : 0xff0000 } );
curveLine = new THREE.Line( curveGeometry, curveMaterial );
scene.add(curveLine);
}
/**
On each frame render, remove the old line, create new curve, geometry and add the new line
*/
function updateCurve() {
testPoint ++;
scene.remove(curveLine);
curve = new THREE.CubicBezierCurve3(
new THREE.Vector3( testPoint, 0, 0 ),
new THREE.Vector3( -5, 150, 0 ),
new THREE.Vector3( 20, 150, 0 ),
new THREE.Vector3( 10, 0, 0 )
);
curveGeometry = new THREE.Geometry();
curveGeometry.vertices = curve.getPoints( 50 );
curveLine = new THREE.Line( curveGeometry, curveMaterial );
scene.add(curveLine);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
updateCurve();
renderer.render(scene, camera);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r83/three.min.js"></script>