PeasyCam+ extends the dead-simple mouse-driven camera for Processing created and maintained by Jonathan Feinberg. It is free for all uses, per the Apache 2.0 license.
To download the original distribution, and to see a demo, go to the PeasyCam home page.
PeasyCam camera; void setup() { // PeasyCam constructor: // PeasyCam(PApplet parent, // double lookAtX, double lookAtY, double lookAtZ, // double distance); camera = new PeasyCam(this, 0, 0, 0, 50); }
That’s it. Now a mouse left-drag will rotate the camera around the subject, a right drag will zoom in and out, and a middle-drag will pan. A double-click restores the camera to its original position.
The PeasyCam is positioned on a sphere whose radius is the given distance from the look-at point. Rotations are around axes that pass through the looked-at point.
PeasyCam(PApplet parent, double lookAtX, double lookAtY, double lookAtZ, double distance);
PeasyCam(PApplet parent, double distance); // look at 0,0,0
Bold methods indicate expanded functionality added in PeasyCam+
camera.setActive(boolean active); // false to make this camera stop responding to mouse
// returns if camera will respond to mouse
camera.isActive();
// By default, the camera is in “free rotation” mode, but you can
// constrain it to any axis, around the look-at point:
camera.setYawRotationMode(); // like spinning a globe
camera.setPitchRotationMode(); // like a somersault
camera.setRollRotationMode(); // like a radio knob
camera.setSuppressRollRotationMode(); // Permit pitch/yaw only.
camera.setSuppressYawRotationMode(); // Permit pitch/roll only.
camera.setSuppressPitchRotationMode(); // Permit roll/yaw only.
// Then you can set it back to its default mode:
camera.setFreeRotationMode();
// reassign particular drag gestures, or set them to null
camera.setLeftDragHandler(PeasyDragHandler handler);
camera.setCenterDragHandler(PeasyDragHandler handler);
camera.setRightDragHandler(PeasyDragHandler handler);
PeasyDragHandler getLeftDragHandler();
PeasyDragHandler getCenterDragHandler();
PeasyDragHandler getRightDragHandler();
PeasyDragHandler getPanDragHandler();
PeasyDragHandler getRotateDragHandler();
PeasyDragHandler getZoomDragHandler();
// mouse wheel zooms by default; set null, or make your own
camera.setWheelHandler(PeasyWheelHandler handler);
PeasyWheelHandler getZoomWheelHandler();
// change sensitivity of built-in mouse controls
camera.setWheelScale(double scale); // 1.0 by default
camera.setZoomScale(double scale); // 1.0 by default
camera.setRotationScale(double scale); // 1.0 by default
camera.setPanScale(double scale); // 1.0 by default
double getWheelScale();
double getZoomScale();
double getRotationScale();
double getPanScale();
// make your own!
public interface PeasyDragHandler {
public void handleDrag(final double dx, final double dy);
}
public interface PeasyWheelHandler {
public void handleWheel(final int delta);
}
camera.setResetOnDoubleClick(boolean resetOnDoubleClick); // default true
camera.setDamping(double rotate, double zoom, double pan); // default .84,.84,.84
camera.setPanOnScreenEdge(boolean panOnScreenEdge); //pans when mouse touches screen edge – default false
camera.setReversePan(boolean reverse); //reverses pan direction when true – default false
camera.setReverseZoom(boolean reverse); //reverses zoom direction when true – default false
camera.setReverseRotate(boolean reverse); //reverses rotate direction when true – default false
camera.setSpeedLock(boolean lock); //increases camera speed if framerate drops – default true
camera.setSpeedRate(double frameRate); //sets the SpeedLock to the target FrameRate – default 60
//lookAt sets the center of the camera – rotate around the lookAt
camera.lookAt(double x, double y, double z);
camera.lookAt(double x, double y, double z, long animationTimeInMillis);
camera.lookAt(double x, double y, double z, double distance);
camera.lookAt(double x, double y, double z, double distance, long animationTimeInMillis);
//lookThrough rotates the camera to look through a point at the lookAt
camera.lookThrough(double x, double y, double z);
camera.lookThrough(double x, double y, double z, long animationTimeInMillis);
camera.lookThrough(double x, double y, double z, double distance);
camera.lookThrough(double x, double y, double z, double distance, long animationTimeInMillis);
camera.rotateX(double angle); // rotate around the x-axis passing through the subject
camera.rotateY(double angle); // rotate around the y-axis passing through the subject
camera.rotateZ(double angle); // rotate around the z-axis passing through the subject
camera.setDistance(double d); // distance from looked-at point
camera.pan(double dx, double dy); // move the looked-at point relative to current orientation
double camera.getDistance(); // current distance
float[] camera.getLookAt(); // float[] { x, y, z }, looked-at point
camera.setMinimumDistance(double minimumDistance);
camera.setMaximumDistance(double maximumDistance); // clamp zooming
camera.getMinimumDistance();
camera.getMaximumDistance();
camera.setMaximumPanDistance(double maximumDistance); // clamp panning
camera.getMaximumPanDistance();
camera.reset();
camera.reset(long animationTimeInMillis); // reset camera to its starting settings
camera.isMoving(); // returns true or false
camera.stop(); // stops all camera damping and movement
CameraState state = camera.getState(); // get a serializable settings object for current state
camera.setState(CameraState state);
camera.setState(CameraState state, long animationTimeInMillis); // set the camera to the given saved state
float[] rotations = camera.getRotations(); // x, y, and z rotations required to face camera in model space
camera.setRotations(double pitch, double yaw, double roll); // rotations are applied in that order
camera.setRotations(double pitch, double yaw, double roll, long animationTimeInMillis);
float[] position = camera.getPosition(); // x, y, and z coordinates of camera in model space
// Utility methods to permit the use of a Heads-Up Display
camera.beginHUD();
// now draw things that you want relative to the camera’s position and orientation
camera.endHUD(); // always!
PeasyCam is impervious to gimbal lock, and has no known “singularities” or discontinuities in its behavior. It relies on the excellent Apache Commons Math geometry package for its rotations.
Thanks: Gennaro Senatore, Michael Kaufmann, Oori Shalev, Jeffrey Gentes, A.W. Martin, Yiannis Chatzikonstantinou, and Donald Ephraim Curtis for bug reports and feature suggestions.