Chap. 09 - The Camera

The Two Camera APIs

There are two different APIs for controlling the camera: class Camera, and class CameraBoom. You must choose one or the other. Do not try to use both, if you do, the results will be undefined.

Using Class CameraBoom

Class CameraBoom has the same non-physics movement-methods as class SceneObject. All the commands that manipulate the position or rotation of a SceneObject work equally well on the one object of class CameraBoom. If you use class CameraBoom to control the camera, you will be using commands like setPosition, setHeading, setHPR, and the like, and you can also use Path objects to manipulate the CameraBoom.

In order to use class CameraBoom, you must first completely disable class Camera. The code to do this is as follows:

Camera.setMode("manual") -- totally disable class Camera

Attempts to call methods of class Camera after disabling it will produce undefined results.

Once you have disabled the Camera class, you must do all camera manipulation and access via methods of the CameraBoom. To obtain the CameraBoom, use this:

local cameraboom = SceneManager.getCameraBoom()

The methods of CameraBoom are identical to the methods of SceneObject, and they will not be discussed further here. We suggest that for simpler methods to do more standard camera manipulation, use Class Camera.

Using Class Camera

The rest of this chapter is about using class Camera. If you are using class Camera, you should not obtain a handle to the CameraBoom. Use one class or the other, not both.

Class Camera: Basic Control

The Camera class in Wild Pockets contains various simple movement functions. The basic concept behind the camera is that it has an eye and a focus. The eye is where the camera is and the focus is what the camera is looking at.

Camera.setEye(vec(0,5,5))
Camera.setFocus(vec(0,0,0))

The Camera class includes smooth movement. When you set the eye or focus the camera will animate towards its new position. If you do not want this behavior you can call the following functions.

Camera.setExactEye(vec(0,5,5))
Camera.setExactFocus(vec(0,0,0))

This will instantly teleport the camera to the new location. With these basic controls you can program the camera to do specifically what your game requires. If you need even more control, see Advanced Camera Control below.

Note: Class Camera assumes the camera is always upright and only gives you access to pitch and heading.

Class Camera: Modes

The Camera class has a couple built in modes that make the most common camera behavior easier.

Class Camera: Sky Mode

The first mode is Sky mode. This mode has the camera orbiting around a single focus. This is useful for a birds eye view while focusing on an object or place. The builder uses this camera by default.

Camera.setMode("Sky")
Camera.setEye(vec(0,5,5))
Camera.setFocus(vec(0,0,0))

Once you've called setMode and positioned the eye and focus there are many simple functions that make moving the camera easy.

Camera.moveForward(3)
Camera.moveBackward(3)
Camera.moveLeft(3)
Camera.moveRight(3)
Camera.moveUp(3)
Camera.moveDown(3)

The move functions will slide the camera in the direction specified by the amount that is passed to them. One thing to note is that these functions are designed to not move you closer or farther from you focus, but instead slide both your eye and focus.

Camera.zoomIn(3)
Camera.zoomOut(3)

The Camera zoom functions will bring your eye closer to your focus.

Camera.rotateRight(10)
Camera.rotateLeft(10)
Camera.rotateUp(10)
Camera.rotateDown(10)

The rotate functions will orbit your camera around the focus. One example of this is:

Timer.every(
  function()
    Camera.rotateLeft(1)
  end
,0.01)

Where rotateLeft is called every 100 milliseconds, this will cause the camera to slowly orbit around the point specified in setFocus.

One other set of really useful functions for Sky mode are:

Camera.beginRotate(100)
Camera.endRotate()

When beginRotate is called the Camera class pushes an EventMap that tracks the mouse and orbits the camera based on mouse movement. endRotate pops this eventMap and halts this behavior. An example of how this can be used is below:

cameraMap = EventMap.new()
cameraMap:setEvent("keyPress-rightMouse",function() Camera.beginRotate(100) end)
cameraMap:setEvent("keyRelease-rightMouse",function() Camera.endRotate end)
EventHandler.push(cameraMap)

This example will wait for the right mouse, then have the Camera track the mouse and orbit as long as the right mouse is held down. Combine this with the previous functions and you have the camera controls that are used in the builder.

fpskeymap = EventMap.new()
fpskeymap:setEvent("scrollWheel",function(d) Camera.zoomIn(d/100) end)
fpskeymap:setEvent("keyPress-rightMouse",function() Camera.beginRotate(150) end)
fpskeymap:setEvent("keyRelease-rightMouse",function() Camera.endRotate() end)
fpskeymap:setEvent("keyDown-left",function() Camera.moveLeft(0.2) end)
fpskeymap:setEvent("keyDown-right",function() Camera.moveRight(0.2) end)
fpskeymap:setEvent("keyDown-up",function() Camera.moveForward(0.2) end)
fpskeymap:setEvent("keyDown-down",function() Camera.moveBackward(0.2) end)
fpskeymap:setEvent("keyDown-shift-up",function() Camera.moveUp(0.2) end)
fpskeymap:setEvent("keyDown-shift-down",function() Camera.moveDown(0.2) end)
EventHandler:push(fpskeymap)

Class Camera: 3rd Mode

Another useful mode is 3rd. When using this mode the camera will follow an object while maintianing the constraints you specify.

Camera.setMode("3rd")
Camera.attachObject(foo)

If you have a SceneObject foo, you can use the above commands to have the camera always keep foo in the center of its vision. If you just use these commands the cameras eye will not move, but only turn towards the object. If you would like the camera to stay within a certain distance of the object you can call the following.

Camera.setFollowDistance(10)

Now the camera will move to always stay 10 meters away from the object. If you want to constrain the heading or the pitch at which the camera stays you can call the following.

Camera.setFollowHeading(90)
Camera.setFollowPitch(30)

This will tell the camera to always maintain a global heading of 90 degrees and a pitch of 30 degrees. Passing nil to any of the above 3 functions will remove their constraint.

It is of note that some of the functions that worked for Sky mode will work here too. The rotate and zoom functions will rotate and zoom around the object. The move functions will not do anything in 3rd mode though.

In order to make 3rd mode a lot simpler there is a single function that will set up everything for you.

Camera.follow(foo,10,nil,30)

The above function will automatically put the camera in 3rd Mode and tell it to follow the object foo at a distance of 10, with no constraint to heading and to maintain a 30 degree pitch.

The only other function of interest when using this mode is setSpeed.

Camera.setSpeed(0.3)

This will control how fast the camera animates to its new location. If your object is outrunning the camera then a higher speed will help the camera keep up.

Class Camera: 1st Mode

Sorry, this is coming shortly.