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.jme.input.action.InputActionEvent;
|
||||||
|
|
||||||
import com.threerings.jme.JmeApp;
|
import com.threerings.jme.JmeApp;
|
||||||
|
import com.threerings.jme.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets up camera controls for moving around from a top-down perspective,
|
* 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)
|
public GodViewHandler (JmeApp app, Camera cam, String api)
|
||||||
{
|
{
|
||||||
|
_camera = cam;
|
||||||
setKeyBindings(api);
|
setKeyBindings(api);
|
||||||
setMouse(cam);
|
setMouse(cam);
|
||||||
setActions(cam, app);
|
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)
|
protected void setKeyBindings (String api)
|
||||||
{
|
{
|
||||||
KeyBindingManager keyboard = KeyBindingManager.getKeyBindingManager();
|
KeyBindingManager keyboard = KeyBindingManager.getKeyBindingManager();
|
||||||
@@ -53,6 +86,8 @@ public class GodViewHandler extends InputHandler
|
|||||||
keyboard.set("zoomOut", KeyInput.KEY_DOWN);
|
keyboard.set("zoomOut", KeyInput.KEY_DOWN);
|
||||||
keyboard.set("turnRight", KeyInput.KEY_RIGHT);
|
keyboard.set("turnRight", KeyInput.KEY_RIGHT);
|
||||||
keyboard.set("turnLeft", KeyInput.KEY_LEFT);
|
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("screenshot", KeyInput.KEY_F12);
|
||||||
keyboard.set("exit", KeyInput.KEY_ESCAPE);
|
keyboard.set("exit", KeyInput.KEY_ESCAPE);
|
||||||
|
|
||||||
@@ -111,7 +146,7 @@ public class GodViewHandler extends InputHandler
|
|||||||
CameraAction left = new CameraAction(cam, 0.5f) {
|
CameraAction left = new CameraAction(cam, 0.5f) {
|
||||||
public void performAction (InputActionEvent evt) {
|
public void performAction (InputActionEvent evt) {
|
||||||
Vector3f loc = _camera.getLocation();
|
Vector3f loc = _camera.getLocation();
|
||||||
loc.addLocal(_rxdir.mult(speed * evt.getTime(), _temp));
|
loc.subtractLocal(_rxdir.mult(speed * evt.getTime(), _temp));
|
||||||
_camera.setLocation(loc);
|
_camera.setLocation(loc);
|
||||||
_camera.update();
|
_camera.update();
|
||||||
}
|
}
|
||||||
@@ -122,7 +157,7 @@ public class GodViewHandler extends InputHandler
|
|||||||
CameraAction right = new CameraAction(cam, 0.5f) {
|
CameraAction right = new CameraAction(cam, 0.5f) {
|
||||||
public void performAction (InputActionEvent evt) {
|
public void performAction (InputActionEvent evt) {
|
||||||
Vector3f loc = _camera.getLocation();
|
Vector3f loc = _camera.getLocation();
|
||||||
loc.subtractLocal(_rxdir.mult(speed * evt.getTime(), _temp));
|
loc.addLocal(_rxdir.mult(speed * evt.getTime(), _temp));
|
||||||
_camera.setLocation(loc);
|
_camera.setLocation(loc);
|
||||||
_camera.update();
|
_camera.update();
|
||||||
}
|
}
|
||||||
@@ -130,48 +165,82 @@ public class GodViewHandler extends InputHandler
|
|||||||
right.setKey("right");
|
right.setKey("right");
|
||||||
addAction(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");
|
zoomIn.setKey("zoomIn");
|
||||||
addAction(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");
|
zoomOut.setKey("zoomOut");
|
||||||
addAction(zoomOut);
|
addAction(zoomOut);
|
||||||
|
|
||||||
// CameraAction lookUp = new CameraAction(cam, 0.5f) {
|
OrbitAction orbitRight = new OrbitAction(-FastMath.PI / 2);
|
||||||
// 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);
|
|
||||||
orbitRight.setKey("turnRight");
|
orbitRight.setKey("turnRight");
|
||||||
addAction(orbitRight);
|
addAction(orbitRight);
|
||||||
|
|
||||||
CameraAction orbitLeft = new OrbitAction(cam, FastMath.PI / 2);
|
OrbitAction orbitLeft = new OrbitAction(FastMath.PI / 2);
|
||||||
orbitLeft.setKey("turnLeft");
|
orbitLeft.setKey("turnLeft");
|
||||||
addAction(orbitLeft);
|
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)
|
protected static Vector3f groundPoint (Camera camera)
|
||||||
@@ -196,48 +265,40 @@ public class GodViewHandler extends InputHandler
|
|||||||
protected Vector3f _temp = new Vector3f();
|
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;
|
_radPerSec = radPerSec;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void performAction (InputActionEvent evt)
|
public void performAction (InputActionEvent evt)
|
||||||
{
|
{
|
||||||
// locate the point at which the camera is "pointing" on
|
rotateCamera(_groundNormal, _radPerSec * evt.getTime());
|
||||||
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float _radPerSec;
|
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 _xdir = new Vector3f(1, 0, 0);
|
||||||
protected static final Vector3f _ydir = new Vector3f(0, 1, 0);
|
protected static final Vector3f _ydir = new Vector3f(0, 1, 0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user