Hello, and welcome once more to a voxelent tutorial. In this tutorial we explore the concept of camera landmarks. Landmarks are features that simplify our life when we work in 3D environments. Instead of having to hard code and remember positions where our camera needs to be, we can save the position and orientation of the camera in a landmark and then tell the camera to go back to that landmark without having to pass along the position neither the orientation once again. So let’s dive right in!


In this tutorial we want to address the positioning of the camera programatically. This is, how our camera will react to a given event in our application. There are scenarios where we would like to move the camera to a specific point in space to see what it is going on there. For this we need to position the camera and tell it to look at the point we want it to focus on.

Coding the camera position and orientation

In a 3D scene there are so many positions where our camera can be. In fact there are as many possible positions as points in our 3D space. For instance if we want to position the camera at the point [2,3,4]:

var c = vxl.c.camera; //accessing the current vxlCamera
c.setPosition(2,3,4);

As in many other methods accross voxelent, we could also provide the position as a vector:

c.setPosition([2,3,4]);

Up to this point we have not aimed our camera to any specific orientation. By default the focal point of the camera is always the origin [0,0,0]. So, regardless of where we position our camera, the camera will always look to the origin. This is a default behavior that makes easier to explore objects when these are at the center of our space. However, this is not always the case and with a 3D camera we want to be able to look around and explore the 3D world. To accomplish this we use the vxlCamera.setFocalPoint method.

Following the previous example, if we are standing at [2,3,4] and we want the camera to look to an actor that is located at [10,3,4], we would write something like this:

var c = vxl.c.camera; 
c.setPosition([2,3,4]);
c.setFocalPoint([10,3,4]);//look right! (x-axis: right, y-axis:up, z-axiz: forward).

The following diagram shows this clearly:

camera_position_focalpoint

By setting the focal point we can aim the camera anywhere in the 3D world.

Using Landmarks

Now that we know how to move and aim the camera we could for instance create buttons to visit different places in our 3D world. However the only caveat is that we have to remember the coordinates for the position and the focal point associated with the desired camera pose.

Would it not be easier if we could instead tell the camera go to __blank__ where blank is a place?. Think for instance in a video game you could tell the camera: go to the entrance of the dragon’s cave. A more common example is when you type “New York” in google earth and voilá you are there!.

In voxelent, there are two ways to create landmarks. First, we can tell the camera to create a landmark using its current position and orientation. To do so we write:

var c = vxl.c.camera; 
c.setLandmark('the-cave');

Where ‘the-cave’ is the name we are giving the landmark (this of course can be any name given by you). If we now move around the world and want to go back to ‘the-cave’ we can do so by writing:

var c = vxl.c.camera; 
c.gotoLandmark('the-cave');

The second way to create landmarks is by referring to locations other than the current camera location. For that we use the method vxlCamera.createLandmark:

.createLandmark(landmark_name, position, focal_point);

So, for example, if we want to define a landmark for checkpoints in our game, we could write something like this:

var c = vxl.c.camera; 
c.createLandmark('checkpoint-1',[0,0,0],[0,0,1]); //first check point
c.createLandmark('checkpoint-2',[4,4,4],[0,0,2]); //second check point 
//etc ...

Jumping or Flying

When we go to a given landmark with gotoLandmark the camera jumps directly there. However, there are cases where we want to have a nice transitional effect and instead having the sense that we are actually flying to the landmark. To achieve this we can provide two optional parameters to the gotoLandmark method:

.gotoLandmark(landmark_name, animation_time, frames_per_second);

For example, if we want to fly to ‘checkpoint-2’in 3 seconds using an animation of 30 frames per second we would write something like this:

var c = vxl.c.camera; //accessing the current vxlCamera
c.gotoLandmark('checkpoint-2',3000,30); // 3000 = 3 seconds, 30 = fps

Flying through several landmarks

For more complicated camera animations where we want to fly over several landmarks we need to define the individual duration and frames-per-second for each step. Then we can pass this information to the vxlCamera.doLandmarkAnimation method. For example, if we have three checkpoints and we want to visit them all in one fly over, spending 3 seconds on each animation, with 30 frames per second, we would write something like this:

var c = vxl.c.camera; //accessing the current vxlCamera
steps = [
           ['checkpoint-1',3000,30],
           ['checkpoint-2',3000,30],
           ['checkpoint-3',3000,30]
        ];
c.doLandmarkAnimation(steps);

Summary and Demo

In this tutorial we explored the concept of camera landmarks and how it is implemented in Voxelent. We know now how to define and go to landmarks either jumping or flying to them.

In this tutorial we have learned how to use the following vxlCamera methods to operate with camera landmarks:
.setLandmark(name) //current position
.createLandmark(name,position,focal point) //anywhere
.gotoLandmark(name) //jumps
.gotoLandmark(name,duration,frames per second) //flies to
.doLandmarkAnimation(steps) //multi-step animation

 

Make sure you visit the camera landmarks demo which implements the ideas discussed here!

Camera Landmarks Demo

Camera Landmarks Demo