diff --git a/src/java/com/threerings/jme/JmeApp.java b/src/java/com/threerings/jme/JmeApp.java index c8b006a2b..b2a6c5d4e 100644 --- a/src/java/com/threerings/jme/JmeApp.java +++ b/src/java/com/threerings/jme/JmeApp.java @@ -51,8 +51,7 @@ import com.jme.light.PointLight; import com.jme.math.Vector3f; import com.jme.util.Timer; -import com.threerings.jme.camera.CameraPath; -import com.threerings.jme.camera.GodViewHandler; +import com.threerings.jme.camera.CameraHandler; /** * Defines a basic application framework providing integration with the @@ -181,27 +180,6 @@ public class JmeApp } } - /** - * Starts the camera moving along a path which will be updated every tick - * until it is complete. - */ - public void moveCamera (CameraPath path) - { - if (_campath != null) { - _campath.abort(); - } - _campath = path; - } - - /** - * Returns true if the camera is currently animating along a path, false if - * it is not. - */ - public boolean cameraIsMoving () - { - return (_campath != null); - } - /** * Instructs the application to stop the main loop, cleanup and exit. */ @@ -293,16 +271,26 @@ public class JmeApp */ protected void initInput () { - _input = createInputHandler(_camera, _properties.getRenderer()); + _camhand = createCameraHandler(_camera); + _input = createInputHandler(_camhand, _properties.getRenderer()); } /** - * Creates the input handler used to control our camera and manage - * non-UI keyboard input. + * Creates the camera handler which provides various camera manipulation + * functionality. */ - protected InputHandler createInputHandler (Camera camera, String api) + protected CameraHandler createCameraHandler (Camera camera) { - return new GodViewHandler(camera, api); + return new CameraHandler(camera); + } + + /** + * Creates the input handler used to control our camera and manage non-UI + * keyboard input. + */ + protected InputHandler createInputHandler (CameraHandler camhand, String api) + { + return new InputHandler(); } /** @@ -416,12 +404,8 @@ public class JmeApp float timePerFrame = _timer.getTimePerFrame(); _root.updateGeometricState(timePerFrame, true); - // if there's a camera path, update that as well - if (_campath != null) { - if (_campath.tick(timePerFrame)) { - _campath = null; - } - } + // update the camera handler + _camhand.update(timePerFrame); // update our stats display if we have one if (_stats != null) { @@ -538,7 +522,7 @@ public class JmeApp protected PropertiesIO _properties; protected DisplaySystem _display; protected Camera _camera; - protected CameraPath _campath; + protected CameraHandler _camhand; protected InputHandler _input; protected BRootNode _rnode; diff --git a/src/java/com/threerings/jme/camera/CameraHandler.java b/src/java/com/threerings/jme/camera/CameraHandler.java new file mode 100644 index 000000000..16d49da2c --- /dev/null +++ b/src/java/com/threerings/jme/camera/CameraHandler.java @@ -0,0 +1,274 @@ +// +// $Id$ +// +// Narya library - tools for developing networked games +// Copyright (C) 2002-2005 Three Rings Design, Inc., All Rights Reserved +// http://www.threerings.net/code/narya/ +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Lesser General Public License as published +// by the Free Software Foundation; either version 2.1 of the License, or +// (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +package com.threerings.jme.camera; + +import com.jme.math.FastMath; +import com.jme.math.Matrix3f; +import com.jme.math.Vector3f; +import com.jme.renderer.Camera; + +/** + * Provides various useful mechanisms for manipulating the camera. + */ +public class CameraHandler +{ + /** + * Creates a new camera handler. The camera begins life at the origin, + * facing in the negative z direction (pointing at the ground). + */ + public CameraHandler (Camera camera) + { + camera.setDirection(new Vector3f(0, 0, -1)); + camera.setLeft(new Vector3f(-1, 0, 0)); + camera.setUp(new Vector3f(0, 1, 0)); + camera.update(); + _camera = camera; + } + + /** + * Configures limits on the camera tilt. + */ + public void setTiltLimits (float minAngle, float maxAngle) + { + _minTilt = minAngle; + _maxTilt = maxAngle; + } + + /** + * Configures limits on the distance the camera can be panned. + */ + public void setPanLimits (float minX, float minY, float maxX, float maxY) + { + _minX = minX; + _minY = minY; + _maxX = maxX; + _maxY = maxY; + } + + /** + * 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); + } + + /** + * Starts the camera moving along a path which will be updated every tick + * until it is complete. + */ + public void moveCamera (CameraPath path) + { + if (_campath != null) { + _campath.abort(); + } + _campath = path; + } + + /** + * Returns true if the camera is currently animating along a path, false if + * it is not. + */ + public boolean cameraIsMoving () + { + return (_campath != null); + } + + /** + * This is called by the {@link JmeApp} on every frame to allow the handler + * to update the camera as necessary. + */ + public void update (float frameTime) + { + if (_campath != null) { + if (_campath.tick(frameTime)) { + _campath = null; + } + } + } + + /** + * Returns the camera being manipulated by this handler. + */ + public Camera getCamera () + { + return _camera; + } + + /** + * Adjusts the camera's location. The specified location will be bounded + * within the current pan and zoom limits. + */ + public void setLocation (Vector3f location) + { + _camera.setLocation(bound(location)); + _camera.update(); + } + + /** + * Pans the camera the specified distance in the x and y directions. These + * distances will be multiplied by the current "view" x and y axes and + * added to the camera's position. + */ + public void panCamera (float x, float y) + { + Vector3f loc = _camera.getLocation(); + loc.addLocal(_rxdir.mult(x, _temp)); + loc.addLocal(_rydir.mult(y, _temp)); + setLocation(loc); + } + + /** + * Zooms the camera in (distance < 0) and out (distance > 0) by the + * specified amount. The distance is multiplied by the camera's current + * direction and added to its current position, which is then bounded into + * the pan and zoom volume. + */ + public void zoomCamera (float distance) + { + Vector3f loc = _camera.getLocation(); + loc.subtractLocal(_camera.getDirection().mult(distance, _temp)); + setLocation(loc); + } + + /** + * 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. Additionally zooms the camera in (deltaZoom < 0) or out + * (deltaZoom > 0) along its direction of view by the specified amount. + */ + public void rotateCamera ( + Vector3f spot, Vector3f axis, float deltaAngle, float deltaZoom) + { + // get a vector from the camera's current position to the point around + // which we're going to orbit + Vector3f direction = _camera.getLocation().subtract(spot); + + // create a rotation matrix + _rotm.fromAxisAngle(axis, deltaAngle); + + // rotate the direction 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()); + + // if we're rotating around the ground normal, we need to update our + // notion of side-to-side and forward for panning + if (axis == _groundNormal) { + _rotm.mult(_rxdir, _rxdir); + _rotm.mult(_rydir, _rydir); + } + + // finally move the camera to its new location, zooming in or out in + // the process + float scale = 1 + (deltaZoom / direction.length()); + direction.scaleAdd(scale, spot); + setLocation(direction); + } + + /** + * Swings the camera perpendicular to the ground normal, around the point + * on the ground at which it is looking. + */ + public void orbitCamera (float deltaAngle) + { + rotateCamera(getGroundPoint(), _groundNormal, deltaAngle, 0); + } + + /** + * Swings the camera perpendicular to its left vector around the point on + * the ground at which it is looking. + */ + public void tiltCamera (float deltaAngle) + { + rotateCamera(getGroundPoint(), _camera.getLeft(), deltaAngle, 0); + } + + /** + * Returns the point on the ground (z = 0) at which the camera is looking. + */ + public Vector3f getGroundPoint () + { + float dist = -1f * _groundNormal.dot(_camera.getLocation()) / + _groundNormal.dot(_camera.getDirection()); + return _camera.getLocation().add(_camera.getDirection().mult(dist)); + } + + /** + * Returns the ground normal. Z is the default ground plane and the normal + * points in the positive z direction. + */ + public Vector3f getGroundNormal () + { + return _groundNormal; + } + + protected Vector3f bound (Vector3f loc) + { + loc.x = Math.max(Math.min(loc.x, _maxX), _minX); + loc.y = Math.max(Math.min(loc.y, _maxY), _minY); + loc.z = Math.max(Math.min(loc.z, _maxZ), _minZ); + return loc; + } + + protected Camera _camera; + protected CameraPath _campath; + protected Matrix3f _rotm = new Matrix3f(); + protected Vector3f _temp = new Vector3f(); + + protected float _minX = Float.MIN_VALUE, _maxX = Float.MAX_VALUE; + protected float _minY = Float.MIN_VALUE, _maxY = Float.MAX_VALUE; + protected float _minZ = Float.MIN_VALUE, _maxZ = Float.MAX_VALUE; + protected float _minTilt = Float.MIN_VALUE, _maxTilt = Float.MAX_VALUE; + + protected Vector3f _rxdir = new Vector3f(1, 0, 0); + protected Vector3f _rydir = new Vector3f(0, 1, 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 _groundNormal = new Vector3f(0, 0, 1); +} diff --git a/src/java/com/threerings/jme/camera/CameraPath.java b/src/java/com/threerings/jme/camera/CameraPath.java index f573174d0..38d4ffae5 100644 --- a/src/java/com/threerings/jme/camera/CameraPath.java +++ b/src/java/com/threerings/jme/camera/CameraPath.java @@ -45,10 +45,10 @@ public abstract class CameraPath { } - protected CameraPath (Camera camera) + protected CameraPath (CameraHandler camhand) { - _camera = camera; + _camhand = camhand; } - protected Camera _camera; + protected CameraHandler _camhand; } diff --git a/src/java/com/threerings/jme/camera/GodViewHandler.java b/src/java/com/threerings/jme/camera/GodViewHandler.java index 4edc78342..36938ed19 100644 --- a/src/java/com/threerings/jme/camera/GodViewHandler.java +++ b/src/java/com/threerings/jme/camera/GodViewHandler.java @@ -20,8 +20,8 @@ import com.threerings.jme.Log; /** * Sets up camera controls for moving around from a top-down perspective, - * suitable for strategy games and their ilk. The "ground" is assumed to - * be the XY plane. + * suitable for strategy games and their ilk. The "ground" is assumed to be the + * XY plane. */ public class GodViewHandler extends InputHandler { @@ -31,108 +31,11 @@ public class GodViewHandler extends InputHandler * @param cam The camera to move with this handler. * @param api The API from which to create a KeyBindingManager. */ - public GodViewHandler (Camera cam, String api) + public GodViewHandler (CameraHandler camhand, String api) { - _camera = cam; + _camhand = camhand; setKeyBindings(api); - addActions(cam); - } - - /** - * Configures the minimum and maximum z-axis elevation allowed for the - * camera. - */ - public void setZoomLimits (float minZ, float maxZ) - { - _minZ = minZ; - _maxZ = maxZ; - } - - /** - * Configures limits on the camera roll. - */ - public void setRollLimits (float minAngle, float maxAngle) - { - _minRoll = minAngle; - _maxRoll = maxAngle; - } - - /** - * Configures limits on the distance the camera can be panned. - */ - public void setPanLimits (float minX, float minY, float maxX, float maxY) - { - _minX = minX; - _minY = minY; - _maxX = maxX; - _maxY = maxY; - } - - /** - * 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); - } - - /** - * Configures the rotational velocity of the camera, which is used to - * smoothly slide the camera to its new position following a call to - * {@link #rotateCamera}. - */ - public void setRotateVelocity (float radiansPerSecond) - { - _rotateVelocity = radiansPerSecond; - } - - /** - * Swings the camera around the point on the ground at which it is - * "looking", by the requested angle (in radians). The camera does not - * jump by the specified angle but rather smoothly rotates there. - */ - public void rotateCamera (float deltaAngle) - { - _rotateDelta += deltaAngle; - } - - /** - * Returns true if the camera is still rotating due to a previous call - * to {@link #rotateCamera}. - */ - public boolean isRotating () - { - return _rotateDelta != 0; - } - - // documentation inherited - public void update (float time) - { - super.update(time); - - float deltaAngle = 0; - if (_rotateDelta < 0) { - deltaAngle = Math.min(time * _rotateVelocity, -_rotateDelta); - } else if (_rotateDelta > 0) { - deltaAngle = Math.max(-1f * time * _rotateVelocity, -_rotateDelta); - } - if (deltaAngle != 0) { - _rotateDelta += deltaAngle; - rotateCamera(_groundNormal, deltaAngle); - } + addActions(); } protected void setKeyBindings (String api) @@ -153,184 +56,101 @@ public class GodViewHandler extends InputHandler keyboard.set("turnRight", KeyInput.KEY_RIGHT); keyboard.set("turnLeft", KeyInput.KEY_LEFT); - // the key bindings for the roll actions - keyboard.set("rollForward", KeyInput.KEY_HOME); - keyboard.set("rollBack", KeyInput.KEY_END); + // the key bindings for the tilt actions + keyboard.set("tiltForward", KeyInput.KEY_HOME); + keyboard.set("tiltBack", KeyInput.KEY_END); keyboard.set("screenshot", KeyInput.KEY_F12); } - protected void addActions (Camera cam) + protected void addActions () { addAction(new KeyScreenShotAction(), "screenshot", false); - - addPanActions(cam); - addZoomActions(cam); - addOrbitActions(cam); - addRollActions(cam); + addPanActions(); + addZoomActions(); + addOrbitActions(); + addTiltActions(); } /** * Adds actions for panning the camera around the scene. */ - protected void addPanActions (Camera cam) + protected void addPanActions () { - CameraAction forward = new CameraAction(cam, 0.5f) { + InputAction forward = new InputAction() { public void performAction (InputActionEvent evt) { - Vector3f loc = _camera.getLocation(); - loc.addLocal(_rydir.mult(speed * evt.getTime(), _temp)); - _camera.setLocation(boundPan(loc)); - _camera.update(); + _camhand.panCamera(0, speed * evt.getTime()); } }; + forward.setSpeed(0.5f); addAction(forward, "forward", true); - CameraAction backward = new CameraAction(cam, 0.5f) { + InputAction backward = new InputAction() { public void performAction (InputActionEvent evt) { - Vector3f loc = _camera.getLocation(); - loc.subtractLocal(_rydir.mult(speed * evt.getTime(), _temp)); - _camera.setLocation(boundPan(loc)); - _camera.update(); + _camhand.panCamera(0, -speed * evt.getTime()); } }; + backward.setSpeed(0.5f); addAction(backward, "backward", true); - CameraAction left = new CameraAction(cam, 0.5f) { + InputAction left = new InputAction() { public void performAction (InputActionEvent evt) { - Vector3f loc = _camera.getLocation(); - loc.subtractLocal(_rxdir.mult(speed * evt.getTime(), _temp)); - _camera.setLocation(boundPan(loc)); - _camera.update(); + _camhand.panCamera(-speed * evt.getTime(), 0); } }; + left.setSpeed(0.5f); addAction(left, "left", true); - CameraAction right = new CameraAction(cam, 0.5f) { + InputAction right = new InputAction() { public void performAction (InputActionEvent evt) { - Vector3f loc = _camera.getLocation(); - loc.addLocal(_rxdir.mult(speed * evt.getTime(), _temp)); - _camera.setLocation(boundPan(loc)); - _camera.update(); + _camhand.panCamera(speed * evt.getTime(), 0); } }; + right.setSpeed(0.5f); addAction(right, "right", true); } /** * Adds actions for zooming the camaera in and out. */ - protected void addZoomActions (Camera cam) + protected void addZoomActions () { - CameraAction zoomIn = new CameraAction(cam, 0.5f) { + InputAction zoomIn = new InputAction() { 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(boundPan(loc)); - _camera.update(); - } + _camhand.zoomCamera(-speed * evt.getTime()); } }; + zoomIn.setSpeed(0.5f); addAction(zoomIn, "zoomIn", true); - CameraAction zoomOut = new CameraAction(cam, 0.5f) { + InputAction zoomOut = new InputAction() { 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(boundPan(loc)); - _camera.update(); - } + _camhand.zoomCamera(speed * evt.getTime()); } }; + zoomOut.setSpeed(0.5f); addAction(zoomOut, "zoomOut", true); } /** * Adds actions for orbiting the camera around the viewpoint. */ - protected void addOrbitActions (Camera cam) + protected void addOrbitActions () { addAction(new OrbitAction(-FastMath.PI / 2), "turnRight", true); addAction(new OrbitAction(FastMath.PI / 2), "turnLeft", true); } /** - * Adds actions for rolling the camera around the yaw axis. + * Adds actions for tilting the camera (rotating around the yaw axis). */ - protected void addRollActions (Camera cam) + protected void addTiltActions () { - addAction(new RollAction(-FastMath.PI / 2), "rollForward", true); - addAction(new RollAction(FastMath.PI / 2), "rollBack", true); + addAction(new TiltAction(-FastMath.PI / 2), "tiltForward", true); + addAction(new TiltAction(FastMath.PI / 2), "tiltBack", true); } - /** - * 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()); - if (around == _groundNormal) { - _rotm.mult(_rxdir, _rxdir); - _rotm.mult(_rydir, _rydir); - } - - // and move the camera to its new location - _camera.setLocation(boundPan(center.add(direction))); - - _camera.update(); - } - - protected static Vector3f groundPoint (Camera camera) - { - float dist = -1f * _groundNormal.dot(camera.getLocation()) / - _groundNormal.dot(camera.getDirection()); - return camera.getLocation().add(camera.getDirection().mult(dist)); - } - - protected Vector3f boundPan (Vector3f loc) - { - loc.x = Math.max(Math.min(loc.x, _maxX), _minX); - loc.y = Math.max(Math.min(loc.y, _maxY), _minY); - return loc; - } - - protected abstract class CameraAction extends KeyInputAction - { - public CameraAction (Camera camera, float speed) - { - _camera = camera; - this.speed = speed; - } - - /** The camera to manipulate. */ - protected Camera _camera; - - /** A temporary vector. */ - protected Vector3f _temp = new Vector3f(); - } - - protected class OrbitAction extends KeyInputAction + protected class OrbitAction extends InputAction { public OrbitAction (float radPerSec) { @@ -339,42 +159,26 @@ public class GodViewHandler extends InputHandler public void performAction (InputActionEvent evt) { - rotateCamera(_groundNormal, _radPerSec * evt.getTime()); + _camhand.orbitCamera(_radPerSec * evt.getTime()); } protected float _radPerSec; } - protected class RollAction extends KeyInputAction + protected class TiltAction extends InputAction { - public RollAction (float radPerSec) + public TiltAction (float radPerSec) { _radPerSec = radPerSec; } public void performAction (InputActionEvent evt) { - rotateCamera(_camera.getLeft(), _radPerSec * evt.getTime()); + _camhand.tiltCamera(_radPerSec * evt.getTime()); } protected float _radPerSec; } - protected Camera _camera; - protected Matrix3f _rotm = new Matrix3f(); - - protected float _rotateVelocity = FastMath.PI, _rotateDelta; - - protected float _minX = Float.MIN_VALUE, _maxX = Float.MAX_VALUE; - protected float _minY = Float.MIN_VALUE, _maxY = Float.MAX_VALUE; - protected float _minZ = Float.MIN_VALUE, _maxZ = Float.MAX_VALUE; - protected float _minRoll = Float.MIN_VALUE, _maxRoll = Float.MAX_VALUE; - - protected Vector3f _rxdir = new Vector3f(1, 0, 0); - protected Vector3f _rydir = new Vector3f(0, 1, 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 _groundNormal = new Vector3f(0, 0, 1); + protected CameraHandler _camhand; } diff --git a/src/java/com/threerings/jme/camera/SwingPath.java b/src/java/com/threerings/jme/camera/SwingPath.java index 45a9799ce..a19f5cff6 100644 --- a/src/java/com/threerings/jme/camera/SwingPath.java +++ b/src/java/com/threerings/jme/camera/SwingPath.java @@ -22,7 +22,6 @@ package com.threerings.jme.camera; import com.jme.math.FastMath; -import com.jme.math.Matrix3f; import com.jme.math.Vector3f; import com.jme.renderer.Camera; @@ -48,10 +47,10 @@ public class SwingPath extends CameraPath * @param zoom the distance to zoom along the camera's view axis (negative * = in, positive = out). */ - public SwingPath (Camera camera, Vector3f spot, Vector3f axis, + public SwingPath (CameraHandler camhand, Vector3f spot, Vector3f axis, float angle, float angvel, float zoom) { - super(camera); + super(camhand); if (angle == 0) { Log.warning("Requested to swing camera through zero degrees " + @@ -97,25 +96,8 @@ public class SwingPath extends CameraPath done = true; } - // get a vector from the camera's position to the point around which - // we're going to orbit - Vector3f camloc = _camera.getLocation(); - Vector3f direction = camloc.subtract(_spot); - - // create a rotation matrix - _rotm.fromAxisAngle(_axis, 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()); - - // and move the camera to its new location (accounting for the zoom) - float scale = 1 + (deltaZoom / direction.length()); - direction.scaleAdd(scale, _spot); - _camera.setLocation(direction); - _camera.update(); + // have the camera handler do the necessary rotating and zooming + _camhand.rotateCamera(_spot, _axis, deltaAngle, deltaZoom); return done; } @@ -123,5 +105,4 @@ public class SwingPath extends CameraPath protected Vector3f _spot, _axis; protected float _angle, _angvel, _rotated; protected float _zoom, _zoomvel, _zoomed; - protected Matrix3f _rotm = new Matrix3f(); }