Provide a way to zoom the camera in and out programmatically, added keys

to roll the camera forward and back.


git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@3540 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
Michael Bayne
2005-05-03 23:45:01 +00:00
parent 2caef9416e
commit 4aa4419c9c
@@ -17,6 +17,7 @@ import com.jme.input.action.*;
import com.jme.input.action.InputActionEvent;
import com.threerings.jme.JmeApp;
import com.threerings.jme.Log;
/**
* Sets up camera controls for moving around from a top-down perspective,
@@ -34,11 +35,43 @@ public class GodViewHandler extends InputHandler
*/
public GodViewHandler (JmeApp app, Camera cam, String api)
{
_camera = cam;
setKeyBindings(api);
setMouse(cam);
setActions(cam, app);
}
/**
* Configures the minimum and maximum z-axis elevation allowed for the
* camera.
*/
public void setZoomLimits (float minZ, float maxZ)
{
_minZ = minZ;
_maxZ = maxZ;
}
/**
* Sets the camera zoom level to a value between zero (zoomed in
* maximally) and 1 (zoomed out maximally). Zoom limits must have
* already been set up via a call to {@link #setZoomLimits}.
*/
public void setZoomLevel (float level)
{
Log.info("Zoom " + level + " " + _camera.getLocation());
level = Math.max(0f, Math.min(level, 1f));
_camera.getLocation().z = _minZ + (_maxZ - _minZ) * level;
_camera.update();
}
/**
* Returns the current camera zoom level.
*/
public float getZoomLevel ()
{
return (_camera.getLocation().z - _minZ) / (_maxZ - _minZ);
}
protected void setKeyBindings (String api)
{
KeyBindingManager keyboard = KeyBindingManager.getKeyBindingManager();
@@ -53,6 +86,8 @@ public class GodViewHandler extends InputHandler
keyboard.set("zoomOut", KeyInput.KEY_DOWN);
keyboard.set("turnRight", KeyInput.KEY_RIGHT);
keyboard.set("turnLeft", KeyInput.KEY_LEFT);
keyboard.set("rollForward", KeyInput.KEY_HOME);
keyboard.set("rollBack", KeyInput.KEY_END);
keyboard.set("screenshot", KeyInput.KEY_F12);
keyboard.set("exit", KeyInput.KEY_ESCAPE);
@@ -111,7 +146,7 @@ public class GodViewHandler extends InputHandler
CameraAction left = new CameraAction(cam, 0.5f) {
public void performAction (InputActionEvent evt) {
Vector3f loc = _camera.getLocation();
loc.addLocal(_rxdir.mult(speed * evt.getTime(), _temp));
loc.subtractLocal(_rxdir.mult(speed * evt.getTime(), _temp));
_camera.setLocation(loc);
_camera.update();
}
@@ -122,7 +157,7 @@ public class GodViewHandler extends InputHandler
CameraAction right = new CameraAction(cam, 0.5f) {
public void performAction (InputActionEvent evt) {
Vector3f loc = _camera.getLocation();
loc.subtractLocal(_rxdir.mult(speed * evt.getTime(), _temp));
loc.addLocal(_rxdir.mult(speed * evt.getTime(), _temp));
_camera.setLocation(loc);
_camera.update();
}
@@ -130,48 +165,82 @@ public class GodViewHandler extends InputHandler
right.setKey("right");
addAction(right);
KeyForwardAction zoomIn = new KeyForwardAction(cam, 0.5f);
CameraAction zoomIn = new CameraAction(cam, 0.5f) {
public void performAction (InputActionEvent evt) {
Vector3f loc = _camera.getLocation();
if (loc.z > _minZ) {
_camera.getDirection().mult(speed * evt.getTime(), _temp);
loc.addLocal(_temp);
_camera.setLocation(loc);
_camera.update();
}
}
};
zoomIn.setKey("zoomIn");
addAction(zoomIn);
KeyBackwardAction zoomOut = new KeyBackwardAction(cam, 0.5f);
CameraAction zoomOut = new CameraAction(cam, 0.5f) {
public void performAction (InputActionEvent evt) {
Vector3f loc = _camera.getLocation();
if (loc.z < _maxZ) {
_camera.getDirection().mult(speed * evt.getTime(), _temp);
loc.subtractLocal(_temp);
_camera.setLocation(loc);
_camera.update();
}
}
};
zoomOut.setKey("zoomOut");
addAction(zoomOut);
// CameraAction lookUp = new CameraAction(cam, 0.5f) {
// public void performAction (InputActionEvent evt) {
// _incr.fromAxisAngle(_camera.getLeft(),
// -FastMath.PI * evt.getTime() / 2);
// _incr.mult(_camera.getLeft(), _camera.getLeft());
// _incr.mult(_camera.getDirection(), _camera.getDirection());
// _incr.mult(_camera.getUp(), _camera.getUp());
// _camera.update();
// }
// private Matrix3f _incr = new Matrix3f();
// };
// lookUp.setKey("lookUp");
// addAction(lookUp);
// CameraAction lookDown = new CameraAction(cam, 0.5f) {
// public void performAction (InputActionEvent evt) {
// _incr.fromAxisAngle(_camera.getLeft(),
// FastMath.PI * evt.getTime() / 2);
// _incr.mult(_camera.getLeft(), _camera.getLeft());
// _incr.mult(_camera.getDirection(), _camera.getDirection());
// _incr.mult(_camera.getUp(), _camera.getUp());
// _camera.update();
// }
// private Matrix3f _incr = new Matrix3f();
// };
// lookDown.setKey("lookDown");
// addAction(lookDown);
CameraAction orbitRight = new OrbitAction(cam, -FastMath.PI / 2);
OrbitAction orbitRight = new OrbitAction(-FastMath.PI / 2);
orbitRight.setKey("turnRight");
addAction(orbitRight);
CameraAction orbitLeft = new OrbitAction(cam, FastMath.PI / 2);
OrbitAction orbitLeft = new OrbitAction(FastMath.PI / 2);
orbitLeft.setKey("turnLeft");
addAction(orbitLeft);
RollAction rollForward = new RollAction(-FastMath.PI / 2);
rollForward.setKey("rollForward");
addAction(rollForward);
RollAction rollBack = new RollAction(FastMath.PI / 2);
rollBack.setKey("rollBack");
addAction(rollBack);
}
/**
* Locates the point on the ground at which the camera is "looking"
* and rotates the camera from that point around the specified vector
* by the specified angle.
*/
protected void rotateCamera (Vector3f around, float deltaAngle)
{
// locate the point at which the camera is "pointing" on
// the ground plane
Vector3f camloc = _camera.getLocation();
Vector3f center = groundPoint(_camera);
// get a vector from the camera's position to the point
// around which we're going to orbit
Vector3f direction = camloc.subtract(center);
// create a rotation matrix
_rotm.fromAxisAngle(around, deltaAngle);
// rotate the center to camera vector and the camera itself
_rotm.mult(direction, direction);
_rotm.mult(_camera.getUp(), _camera.getUp());
_rotm.mult(_camera.getLeft(), _camera.getLeft());
_rotm.mult(_camera.getDirection(), _camera.getDirection());
_rotm.mult(_rxdir, _rxdir);
_rotm.mult(_rydir, _rydir);
// and move the camera to its new location
_camera.setLocation(center.add(direction));
_camera.update();
}
protected static Vector3f groundPoint (Camera camera)
@@ -196,48 +265,40 @@ public class GodViewHandler extends InputHandler
protected Vector3f _temp = new Vector3f();
}
protected class OrbitAction extends CameraAction
protected class OrbitAction extends KeyInputAction
{
public OrbitAction (Camera camera, float radPerSec)
public OrbitAction (float radPerSec)
{
super(camera, 0f);
_radPerSec = radPerSec;
}
public void performAction (InputActionEvent evt)
{
// locate the point at which the camera is "pointing" on
// the ground plane
Vector3f camloc = _camera.getLocation();
Vector3f center = groundPoint(_camera);
// get a vector from the camera's position to the point
// around which we're going to orbit
Vector3f direction = camloc.subtract(center);
// compute the amount we wish to orbit
float deltaA = _radPerSec * evt.getTime();
// create a rotation matrix
_rotm.fromAxisAngle(_groundNormal, deltaA);
// rotate the center to camera vector and the camera itself
_rotm.mult(direction, direction);
_rotm.mult(_camera.getUp(), _camera.getUp());
_rotm.mult(_camera.getLeft(), _camera.getLeft());
_rotm.mult(_camera.getDirection(), _camera.getDirection());
_rotm.mult(_rxdir, _rxdir);
_rotm.mult(_rydir, _rydir);
// and move the camera to its new location
_camera.setLocation(center.add(direction));
_camera.update();
rotateCamera(_groundNormal, _radPerSec * evt.getTime());
}
protected float _radPerSec;
protected Matrix3f _rotm = new Matrix3f();
}
protected class RollAction extends KeyInputAction
{
public RollAction (float radPerSec)
{
_radPerSec = radPerSec;
}
public void performAction (InputActionEvent evt)
{
rotateCamera(_camera.getLeft(), _radPerSec * evt.getTime());
}
protected float _radPerSec;
}
protected Camera _camera;
protected Matrix3f _rotm = new Matrix3f();
protected float _minZ = Float.MIN_VALUE, _maxZ = Float.MAX_VALUE;
protected static final Vector3f _xdir = new Vector3f(1, 0, 0);
protected static final Vector3f _ydir = new Vector3f(0, 1, 0);