Animating an object along a path in three.js

I am trying to animate a cube along a path in three.js.

enter image description here

CODE

 // Ellipse class, which extends the virtual base class Curve
    var curve = new THREE.EllipseCurve(
        0,  0,            // ax, aY
        16, 21.28,           // xRadius, yRadius
        0,  2 * Math.PI,  // aStartAngle, aEndAngle
        false,            // aClockwise
        0                 // aRotation
    );

    //defines the amount of points the path will have
    var path = new THREE.Path( curve.getPoints( 100 ) );
    var geometrycirc = path.createPointsGeometry( 100 );
    var materialcirc = new THREE.LineBasicMaterial( {
        color : 0xff0000
    } );

    // Create the final object to add to the scene
    var ellipse = new THREE.Line( geometrycirc, materialcirc );
    ellipse.position.set(0,1,0);
    this.scene.add( ellipse );

    // add the box to the scene
    this.scene.add(this.box);

      

I am doing some research on how this could be done and came across this animation script along the way This method uses the THREE.SplineCurve3 method to create points to use the window.

My question is: I need to convert my path to use THREE.SplineCurve3 method.

Or can I use the path as it is?

Any help or pointers would be appreciated.

many thanks

+3


source to share


1 answer


Object Animation along the way

Animating an object along the way

code

// GLOBALS - ALLOCATE THESE OUTSIDE OF THE RENDER LOOP - CHANGED
var cubes = [], marker, spline;
var matrix = new THREE.Matrix4();
var up = new THREE.Vector3( 0, 1, 0 );
var axis = new THREE.Vector3( );
var pt, radians, axis, tangent, path;

// the getPoint starting variable - !important - You get me ;)
var t = 0;

//This function generates the cube and chooses a random color for it 
//on initial load.

function getCube(){
// cube mats and cube
var mats = [];
for (var i = 0; i < 6; i ++) {
    mats.push(new 
THREE.MeshBasicMaterial({color:Math.random()*0xffffff}));
}

var cube = new THREE.Mesh(
    new THREE.CubeGeometry(2, 2, 2),
    new THREE.MeshFaceMaterial( mats )
);

return cube
}

// Ellipse class, which extends the virtual base class Curve
function Ellipse( xRadius, yRadius ) {

    THREE.Curve.call( this );

    // add radius as a property
    this.xRadius = xRadius;
    this.yRadius = yRadius;

 }

 Ellipse.prototype = Object.create( THREE.Curve.prototype );
 Ellipse.prototype.constructor = Ellipse;

 // define the getPoint function for the subClass
 Ellipse.prototype.getPoint = function ( t ) {

 var radians = 2 * Math.PI * t;

 return new THREE.Vector3( this.xRadius * Math.cos( radians ),
                          this.yRadius * Math.sin( radians ),
                          0 );

};

//

var mesh, renderer, scene, camera, controls;


function init() {

// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

// scene
scene = new THREE.Scene();

// camera
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 20, 20, 20 );

// controls
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render ); // use if there is no animation loop
controls.minDistance = 10;
controls.maxDistance = 50;

// light
var light = new THREE.PointLight( 0xffffff, 0.7 );
camera.add( light );
scene.add( camera ); // add to scene only because the camera  has a child

// axes
scene.add( new THREE.AxisHelper( 20 ) );


////////////////////////////////////////
//      Create the cube               //
////////////////////////////////////////

marker = getCube();
marker.position.set(0,0,0);
scene.add(marker);


////////////////////////////////////////
//      Create an Extruded shape      //
////////////////////////////////////////

// path
path = new Ellipse( 5, 10 );

// params
var pathSegments = 64;
var tubeRadius = 0.5;
var radiusSegments = 16;
var closed = true;

var geometry = new THREE.TubeBufferGeometry( path, pathSegments, tubeRadius, radiusSegments, closed );

// material
var material = new THREE.MeshPhongMaterial( {
    color: 0x0080ff, 
} );

// mesh
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

//////////////////////////////////////////////////////////////////////////
//       Create the path which is based on our shape above              //
//////////////////////////////////////////////////////////////////////////

//Please note that this red ellipse was only created has a guide so that I could  be certain that the square is true to the tangent and positioning.

// Ellipse class, which extends the virtual base class Curve
    var curve = new THREE.EllipseCurve(
        0,  0,            // ax, aY
        6, 11,           // xRadius, yRadius
        0,  2 * Math.PI,  // aStartAngle, aEndAngle
        false,            // aClockwise
        0                 // aRotation
    );

    //defines the amount of points the path will have
    var path2 = new THREE.Path( curve.getPoints( 100 ) );
     geometrycirc = path2.createPointsGeometry( 100 );
    var materialcirc = new THREE.LineBasicMaterial( {
        color : 0xff0000
    } );

    // Create the final object to add to the scene
    var ellipse = new THREE.Line( geometrycirc, materialcirc );
    ellipse.position.set(0,0,0);
    scene.add( ellipse );

    }

function animate() {
requestAnimationFrame(animate);

render();
}


function render() {

    // set the marker position
    pt = path.getPoint( t );

    // set the marker position
    marker.position.set( pt.x, pt.y, pt.z );

    // get the tangent to the curve
    tangent = path.getTangent( t ).normalize();

    // calculate the axis to rotate around
    axis.crossVectors( up, tangent ).normalize();

    // calcluate the angle between the up vector and the tangent
    radians = Math.acos( up.dot( tangent ) );

    // set the quaternion
    marker.quaternion.setFromAxisAngle( axis, radians );

    t = (t >= 1) ? 0 : t += 0.002;

    renderer.render( scene, camera );

}

init();
animate();
      

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/82/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
      

Run codeHide result




Conclusion

So I'm very lucky to stumble upon the answer. In my case, it was creating a subclass for my object that allowed me to use it as points so that the object could use it as a guide.

Yes, I know what you are thinking "What this guy is talking about , so I created a violin for you to watch and study."

Fiddle: Object Animation Along Path

+3


source







All Articles