Reputation: 247
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
Upvotes: 3
Views: 5209
Reputation: 247
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
Upvotes: 5