Thursday, September 19, 2013

Moving the Camera

In addition to animating the game objects such as our green cube, we can also move and rotate the camera (or eye position) in the game world.  We'll get into camera rotation in a future blog post, because that is slightly more involved.  For now we will focus on camera position movement, which is a little easier to grasp right away.

Remember when we picked up the camera and moved it back along the positive z-axis (going behind you) so that we could step back and see more of our scene?  In case you need a refresher, that line of code looks like:
camera.position.z = 5;
We typed the name of our camera, 'camera' and then used the dot (.) and then the 'position' property, followed by another dot (.) and finally the axis that we wanted, which is 'z' in this case.  Then we filled this property using the = sign followed by the number value that we would like to assign to it, which was '5'. 

What will happen if this number value changes every animation frame?  Let's find out!  First, we will try something that we already know how to do, which is add to it every frame so that the 'position.z' value keeps growing larger and larger.  Here's how that would look:
camera.position.z = camera.position.z + 0.1;
Here again, we have to first set the position equal to itself and then add a number to that.  Each time the program reads this line (60 times a second!), it will add to itself 0.1 units, (which is 5 initially, 5.1, 5.2, 5.3, 5.4, 5.5, etc.), thus becoming larger and larger over time.  
Let's try adding this line and see what happens to our view of the game world.  Remember that we have to add any animating or moving code inside the animate() function.

Here is the newly updated animate() function with our added line of code:

function animate(){
   
   requestAnimationFrame(animate);

   cube.rotation.x = cube.rotation.x + 0.02;
   cube.rotation.y = cube.rotation.y + 0.03;
  
   camera.position.z = camera.position.z + 0.1;

   renderer.render( scene, camera );

}

Can you guess what this will look like before we run it?  I'll give you a hint: the z axis represents how close or far we are to the cube, which is located at the very center of the game world.  And every loop this distance from us to the cube keeps growing and growing, getting farther.  Here is the entire updated tempGame.js file with our new line of code inserted inside the animate() function:


var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);

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

var geometry = new THREE.CubeGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial({ color:'rgb(0,255,0)' });
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);

camera.position.z = 5;
animate();

function animate(){
   
   requestAnimationFrame(animate);

   cube.rotation.x = cube.rotation.x + 0.02;
   cube.rotation.y = cube.rotation.y + 0.03;
  
   camera.position.z = camera.position.z + 0.1;

   renderer.render( scene, camera );

}
Save this as tempGame.js, overwriting the old file, and then go to example01.html and open with your Chrome browser.

Is it what you expected?  The cube starts out where it did last time, pretty close to us.  But this time, it appears to recede into the distance as we wave bye-bye to it.  Actually it is not the cube that is moving, but us, the camera, that is moving quickly backwards (how 'special relativity' Einsteinian of us!).  So it appears if the cube is vanishing into the distance.  This same effect can be achieved by instead moving the cube.position.z along the negative z-axis every animation frame (negative z goes into your computer screen) while keeping us, the observer, absolutely still.

Now let's try moving the camera in the opposite direction - instead of backing up away from the cube, let's move forwards and meet it head-on.  Can you guess how we would do that with just one little change to our code?  Here's the answer: 
camera.position.z = camera.position.z - 0.1;
Turns out we just have to change the '+' to a '-'.  Now, every frame, the camera.position.z value will get smaller and smaller (5 initially, 4.9, 4.8, 4.7, 4.6, etc) and thus the distance between us and the green cube will get smaller as well.  It will look like it is moving towards us, but we know better!  The cube is actually still, while we keep moving our camera closer to it.  Eventually we will pass right through the cube and it will be behind us.  
Change the '+' to a '-' like I did above, then Save the new tempGame.js over the old one, and try running your example01.html file in the Chrome browser again.

Did you flinch?  Come on, be honest!  After we pass right through the cube, it seems to disappear, but it is actually still in the game world - it's just behind us so we can't see it.  In a future post, I will demonstrate how to look around (rotate) with our camera so that we can confirm that the green cube is indeed still there. 

Up, next... Moving the camera back and forth, 1970's style!