summaryrefslogtreecommitdiffstats
path: root/src/gleem/ExaminerViewer.java
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2009-06-19 20:35:04 +0000
committerKenneth Russel <[email protected]>2009-06-19 20:35:04 +0000
commitd075bda489c425d7f1ccd45944db6a8696bb0fd2 (patch)
tree0d2c22bb410c0d116c60dfc0bb82888006653e72 /src/gleem/ExaminerViewer.java
parent3ac44007a441db45e5ed45b901806dc5b0c2a6b6 (diff)
Improved interaction in ExaminerViewer to match Maya's camera
controls. Added optional up vector. Simplified logic by using MouseEvent.getModifiersEx(). MouseButtonHelper is no longer necessary and has been removed. Updated demos. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/../svn-server-sync/jogl-demos/trunk@357 3298f667-5e0e-4b4a-8ed4-a3559d26a5f4
Diffstat (limited to 'src/gleem/ExaminerViewer.java')
-rw-r--r--src/gleem/ExaminerViewer.java136
1 files changed, 84 insertions, 52 deletions
diff --git a/src/gleem/ExaminerViewer.java b/src/gleem/ExaminerViewer.java
index d21579a..a99e555 100644
--- a/src/gleem/ExaminerViewer.java
+++ b/src/gleem/ExaminerViewer.java
@@ -84,8 +84,7 @@ public class ExaminerViewer {
/** Simple state machine for computing distance dragged */
private boolean button1Down;
private boolean button2Down;
- private int numMouseButtons;
- private int oldNumMouseButtons;
+ private boolean button3Down;
private int lastX;
private int lastY;
@@ -94,6 +93,7 @@ public class ExaminerViewer {
private Vec3f dolly = new Vec3f(0, 0, 10); // Amount we have "backed up" from focal point
private Vec3f center = new Vec3f(0, 0, 0); // Position of focal point in world coordinates
private Rotf orientation = new Rotf();
+ private Vec3f upVector = null;
private float rotateSpeed = 1.0f;
private float minRotateSpeed = 0.0001f;
private float dollySpeed = 2.0f;
@@ -112,17 +112,23 @@ public class ExaminerViewer {
}
public void mouseMoved(MouseEvent e) {
- passiveMotionMethod(e);
+ if (interactionUnderway && iOwnInteraction) {
+ // Hack for AWT behavior where Ctrl + Alt + Left mouse button is treated
+ // as motion instead of drag
+ motionMethod(e, e.getX(), e.getY());
+ } else {
+ passiveMotionMethod(e);
+ }
}
};
private MouseAdapter mouseListener = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
- mouseMethod(e, e.getModifiers(), true, e.getX(), e.getY());
+ mouseMethod(e, e.getModifiersEx(), true, e.getX(), e.getY());
}
public void mouseReleased(MouseEvent e) {
- mouseMethod(e, e.getModifiers(), false, e.getX(), e.getY());
+ mouseMethod(e, e.getModifiersEx(), false, e.getX(), e.getY());
}
};
@@ -136,11 +142,7 @@ public class ExaminerViewer {
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {}
};
- /** The constructor takes the number of mouse buttons on this system
- (couldn't figure out how to determine this internally) */
- public ExaminerViewer(int numMouseButtons) {
- this.numMouseButtons = numMouseButtons;
- oldNumMouseButtons = numMouseButtons;
+ public ExaminerViewer() {
}
/** <P> Attaches this ExaminerViewer to the given GLAutoDrawable. This
@@ -287,18 +289,20 @@ public class ExaminerViewer {
this.orientation.set(orientation);
}
- public void setNoAltKeyMode(boolean noAltKeyMode) {
- this.noAltKeyMode = noAltKeyMode;
- if (noAltKeyMode) {
- // FIXME: this is a hack to work around Windows' apparently
- // conflating the alt/meta key with one of the mouse buttons
- oldNumMouseButtons = numMouseButtons;
- numMouseButtons = 3;
+ /** Sets the preferred up vector of this ExaminerViewer. The default
+ is null. */
+ public void setUpVector(Vec3f up) {
+ if (up == null) {
+ upVector = null;
} else {
- numMouseButtons = oldNumMouseButtons;
+ upVector = up.copy();
}
}
+ public void setNoAltKeyMode(boolean noAltKeyMode) {
+ this.noAltKeyMode = noAltKeyMode;
+ }
+
public boolean getNoAltKeyMode() {
return noAltKeyMode;
}
@@ -354,17 +358,16 @@ public class ExaminerViewer {
private boolean modifiersMatch(MouseEvent e, int mods) {
if (noAltKeyMode) {
- if ((mods & MouseEvent.BUTTON1_MASK) != 0 &&
- (mods & MouseEvent.BUTTON2_MASK) == 0 &&
- (mods & MouseEvent.BUTTON3_MASK) == 0) {
+ if ((mods & MouseEvent.BUTTON1_DOWN_MASK) != 0 &&
+ (mods & MouseEvent.BUTTON2_DOWN_MASK) == 0 &&
+ (mods & MouseEvent.BUTTON3_DOWN_MASK) == 0) {
return (!e.isAltDown() && !e.isMetaDown() && !e.isControlDown() && !e.isShiftDown());
} else {
// At least on Windows, meta seems to be declared to be down on right button presses
return !e.isControlDown() && !e.isShiftDown();
}
} else {
- return ((e.isAltDown() || e.isMetaDown()) &&
- (!e.isControlDown() && !e.isShiftDown()));
+ return (e.isAltDown() || e.isMetaDown());
}
}
@@ -396,7 +399,30 @@ public class ExaminerViewer {
lastX = x;
lastY = y;
- if ((button1Down && (!button2Down))) {
+ // The intent is to match Maya's camera controls, which are the de facto standard:
+ // - Alt + Left = rotation
+ // - Alt + Right = zoom
+ // - Alt + Middle = translation
+ // With the hack that Ctrl + Alt + Right on a trackpad be the same as translation,
+ // so that gesture can be done without a 3-button mouse hooked up.
+
+ boolean doRotation =
+ (button1Down && !button2Down && !button3Down);
+ boolean doTranslation =
+ (button2Down && !button1Down && !button3Down);
+ boolean doZoom =
+ (button3Down && !button1Down && !button2Down);
+
+ // Hack to allow us to use Ctrl + Alt + LMB to translate so
+ // that we can do that gesture on the trackpad
+ if (e.isControlDown() && (doRotation || doZoom ||
+ (button1Down && button2Down))) {
+ doRotation = false;
+ doZoom = false;
+ doTranslation = true;
+ }
+
+ if (doRotation) {
// Rotation functionality
float xRads = (float) Math.PI * -1.0f * dy * rotateSpeed / 1000.0f;
@@ -406,7 +432,23 @@ public class ExaminerViewer {
Rotf newRot = yRot.times(xRot);
orientation = orientation.times(newRot);
- } else if (button2Down && (!button1Down)) {
+ if (upVector != null) {
+ // FIXME: has degenerate behavior when pointing parallel to up vector
+ Vec3f cameraUp = orientation.rotateVector(Vec3f.Y_AXIS);
+ float dotp = cameraUp.dot(upVector);
+ if (Math.abs(dotp) > MathUtil.ZERO_TOLERANCE) {
+ // Form orthonormal basis
+ Vec3f back = orientation.rotateVector(Vec3f.Z_AXIS);
+ Vec3f right = upVector.cross(back);
+ right.normalize();
+ cameraUp.cross(back, right);
+ Mat4f mat = new Mat4f();
+ mat.setRotation(right, cameraUp, back);
+ orientation.fromMatrix(mat);
+ }
+ }
+
+ } else if (doTranslation) {
// Translate functionality
// Compute the local coordinate system's difference vector
@@ -418,9 +460,10 @@ public class ExaminerViewer {
// Add on to center
center.add(worldDiff);
- } else if (button1Down && button2Down) {
+ } else if (doZoom) {
- float diff = dollySpeed * -1.0f * dy / 100.0f;
+ // FIXME: implement this in terms of mouse wheel
+ float diff = dollySpeed * (-1.0f * dy - dx) / 100.0f;
float newDolly = dolly.z() + diff;
if (newDolly < minFocalDist) {
newDolly = minFocalDist;
@@ -451,37 +494,26 @@ public class ExaminerViewer {
ManipManager.getManipManager().mouseReleased(e);
}
} else {
- if ((mods & MouseEvent.BUTTON1_MASK) != 0) {
- if (press) {
- button1Down = true;
- } else {
- button1Down = false;
- }
+ if ((mods & MouseEvent.BUTTON1_DOWN_MASK) != 0) {
+ button1Down = true;
} else {
- if (numMouseButtons != 3) {
- if ((mods & MouseEvent.BUTTON2_MASK) != 0) {
- if (press) {
- button2Down = true;
- } else {
- button2Down = false;
- }
- }
- } else {
- // FIXME: must test this on 3-button system
- if ((mods & MouseEvent.BUTTON3_MASK) != 0) {
- if (press) {
- button2Down = true;
- } else {
- button2Down = false;
- }
- }
- }
+ button1Down = false;
+ }
+ if ((mods & MouseEvent.BUTTON2_DOWN_MASK) != 0) {
+ button2Down = true;
+ } else {
+ button2Down = false;
+ }
+ if ((mods & MouseEvent.BUTTON3_DOWN_MASK) != 0) {
+ button3Down = true;
+ } else {
+ button3Down = false;
}
lastX = x;
lastY = y;
- if (button1Down || button2Down) {
+ if (button1Down || button2Down || button3Down) {
interactionUnderway = true;
iOwnInteraction = true;
} else {