Question

How can I move the camera along a simple path (created by an array of vertices/points)? I need to move it automatically, not by keyboard/mouse events, like in a first person shoter game?

Looked for this example: http://threejs.org/examples/webgl_geometry_extrude_splines.html and it's realy good (and complex), but I need something simple, as a person who is just starting to learn Three.js

Was it helpful?

Solution

So, the best and simplest solution (based on my errors and researches - maybe you can find even a simpler solution) is to use PathControls; you can find the library here: https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PathControls.js

This simple solution is based on the book: Learning Three.js: "The JavaScript 3D Library for WebGL"; it's very good to learn something on Three and I recommend you to read it; First we add the PathControls.js to our document:

<script src="js/PathControls.js"></script>

then we add some variables, before out init() function:

var controls;
var clock = new THREE.Clock();
var pathControls;

now we need some work to do on our init() function, after creating the scene, camera, lights, etc:

controls = new function () {
this.numberOfPoints = 5;
this.segments = 64;
this.radius = 3;
this.radiusSegments = 5;
this.closed = false;
this.points = getPoints();

//you can take out this last one: it shows you the path on which the camera is moving
generatePoints(this.points, this.segments, this.radius, this.radiusSegments, this.closed);
}
pathControls = new THREE.PathControls(camera);

// configure the controller
pathControls.duration = 70

//speed, so you will not have the dash effect on a curve
pathControls.useConstantSpeed = true;
pathControls.lookSpeed = 0.1;
pathControls.lookVertical = true;
pathControls.lookHorizontal = true;
pathControls.verticalAngleMap = {srcRange: [ 0, 2 * Math.PI ], dstRange: [ 1.1, 3.8 ]};
pathControls.horizontalAngleMap = {srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0.3, Math.PI - 0.3 ]};
pathControls.lon = 300;
pathControls.lat = 40;

// add the path
controls.points.forEach(function(e) {
  pathControls.waypoints.push([e.x, e.y, e.z]) });

// when done configuring init the control
pathControls.init();

// add the animationParent to the scene and start the animation
scene.add(pathControls.animationParent);
pathControls.animation.play(true, 0 );

Lastly you need this 3 lines in you animate() function so the camera actually will move based on time:

var delta = clock.getDelta();
THREE.AnimationHandler.update(delta);
pathControls.update(delta);

As regards the support functions (I have this one that is just an array on 5 points, but you can use many more and more complex: it's up to you):

function getPoints() {
    var points = [];
    points.push(new THREE.Vector3(0, 20, 0));
    points.push(new THREE.Vector3(100, 25, 0));
    points.push(new THREE.Vector3(100, 20, 100));
    points.push(new THREE.Vector3(0, 25, 100));
    points.push(new THREE.Vector3(0, 20, 0));
    return points;
}

And those are the functions to show/draw a tube on the path you picked so you can see how actually the camera is moving (not needed for the whole code to work):

function generatePoints(points, segments, radius, radiusSegments, closed) {
  var tube = new THREE.TubeGeometry(new THREE.SplineCurve3(points), segments, radius, radiusSegments, false, closed);
  var tubeMesh = createMesh(tube);
  scene.add(tubeMesh);
}

function createMesh(geom) {
  mesh = THREE.SceneUtils.createMultiMaterialObject( geom, [
    new THREE.MeshLambertMaterial({color: 0x00ff00, transparent: true}),
    new THREE.MeshBasicMaterial({color: 0x000000, opacity: 0.3, wireframe: true, transparent: true})]);
 return mesh;
}

Hope it will be useful to someone; for the whole code, you'll find it here: https://github.com/MarcinKwiatkowski1988/learningThreeJs/blob/master/movingCameraOnPath/myTry1_simply.html

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top