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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user