diff options
author | Kenneth Russel <[email protected]> | 2009-06-19 20:35:04 +0000 |
---|---|---|
committer | Kenneth Russel <[email protected]> | 2009-06-19 20:35:04 +0000 |
commit | d075bda489c425d7f1ccd45944db6a8696bb0fd2 (patch) | |
tree | 0d2c22bb410c0d116c60dfc0bb82888006653e72 | |
parent | 3ac44007a441db45e5ed45b901806dc5b0c2a6b6 (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
-rwxr-xr-x | src/demos/hdr/HDR.java | 4 | ||||
-rw-r--r-- | src/demos/hwShadowmapsSimple/HWShadowmapsSimple.java | 4 | ||||
-rw-r--r-- | src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java | 4 | ||||
-rw-r--r-- | src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java | 4 | ||||
-rw-r--r-- | src/demos/vertexProgRefract/VertexProgRefract.java | 4 | ||||
-rw-r--r-- | src/demos/vertexProgWarp/VertexProgWarp.java | 4 | ||||
-rw-r--r-- | src/gleem/ExaminerViewer.java | 136 | ||||
-rw-r--r-- | src/gleem/MouseButtonHelper.java | 75 | ||||
-rw-r--r-- | src/gleem/TestExaminerViewer.java | 3 | ||||
-rw-r--r-- | src/gleem/TestMultiWin.java | 3 | ||||
-rw-r--r-- | src/gleem/linalg/MathUtil.java | 9 |
11 files changed, 109 insertions, 141 deletions
diff --git a/src/demos/hdr/HDR.java b/src/demos/hdr/HDR.java index 2f71c3c..bd3f7d6 100755 --- a/src/demos/hdr/HDR.java +++ b/src/demos/hdr/HDR.java @@ -13,7 +13,6 @@ import gleem.BSphereProvider; import gleem.CameraParameters; import gleem.ExaminerViewer; import gleem.ManipManager; -import gleem.MouseButtonHelper; import gleem.linalg.Mat4f; import gleem.linalg.Rotf; import gleem.linalg.Vec3f; @@ -365,7 +364,8 @@ public class HDR extends Demo { manager.registerWindow((AWTGLAutoDrawable) drawable); this.drawable = drawable; - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer = new ExaminerViewer(); + viewer.setUpVector(Vec3f.Y_AXIS); viewer.setAutoRedrawMode(false); viewer.setNoAltKeyMode(true); viewer.attach((AWTGLAutoDrawable) drawable, new BSphereProvider() { diff --git a/src/demos/hwShadowmapsSimple/HWShadowmapsSimple.java b/src/demos/hwShadowmapsSimple/HWShadowmapsSimple.java index 1c7effe..3190778 100644 --- a/src/demos/hwShadowmapsSimple/HWShadowmapsSimple.java +++ b/src/demos/hwShadowmapsSimple/HWShadowmapsSimple.java @@ -44,7 +44,6 @@ import gleem.CameraParameters; import gleem.ExaminerViewer; import gleem.HandleBoxManip; import gleem.ManipManager; -import gleem.MouseButtonHelper; import gleem.linalg.Mat4f; import gleem.linalg.Rotf; import gleem.linalg.Vec3f; @@ -301,7 +300,8 @@ public class HWShadowmapsSimple extends Demo { spotlight.setRotation(new Rotf(Vec3f.X_AXIS, (float) Math.toRadians(-30.0f))); manager.showManipInWindow(spotlight, (AWTGLAutoDrawable) drawable); - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer = new ExaminerViewer(); + viewer.setUpVector(Vec3f.Y_AXIS); viewer.attach((AWTGLAutoDrawable) drawable, new BSphereProvider() { public BSphere getBoundingSphere() { return new BSphere(object.getTranslation(), 2.0f); diff --git a/src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java b/src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java index dde5135..c0feeb1 100644 --- a/src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java +++ b/src/demos/infiniteShadowVolumes/InfiniteShadowVolumes.java @@ -43,7 +43,6 @@ import gleem.CameraParameters; import gleem.ExaminerViewer; import gleem.HandleBoxManip; import gleem.ManipManager; -import gleem.MouseButtonHelper; import gleem.linalg.Mat4f; import gleem.linalg.Rotf; import gleem.linalg.Vec3f; @@ -260,7 +259,8 @@ public class InfiniteShadowVolumes extends Demo { lightManip.setTranslation(new Vec3f(0.5f, 0.5f, -1)); lightManip.setGeometryScale(new Vec3f(0.1f, 0.1f, 0.1f)); - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer = new ExaminerViewer(); + viewer.setUpVector(Vec3f.Y_AXIS); viewer.attach((AWTGLAutoDrawable) drawable, new BSphereProvider() { public BSphere getBoundingSphere() { return new BSphere(objectManip.getTranslation(), 1.0f); diff --git a/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java b/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java index 427d645..a813906 100644 --- a/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java +++ b/src/demos/proceduralTexturePhysics/ProceduralTexturePhysics.java @@ -40,7 +40,6 @@ import gleem.BSphereProvider; import gleem.CameraParameters; import gleem.ExaminerViewer; import gleem.ManipManager; -import gleem.MouseButtonHelper; import gleem.linalg.Vec3f; import java.awt.BorderLayout; import java.awt.Frame; @@ -195,7 +194,8 @@ public class ProceduralTexturePhysics extends Demo { manager.registerWindow((AWTGLAutoDrawable) drawable); this.drawable = drawable; - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer = new ExaminerViewer(); + viewer.setUpVector(Vec3f.Y_AXIS); viewer.setAutoRedrawMode(false); viewer.attach((AWTGLAutoDrawable) drawable, new BSphereProvider() { diff --git a/src/demos/vertexProgRefract/VertexProgRefract.java b/src/demos/vertexProgRefract/VertexProgRefract.java index edbef87..fa71f0c 100644 --- a/src/demos/vertexProgRefract/VertexProgRefract.java +++ b/src/demos/vertexProgRefract/VertexProgRefract.java @@ -45,7 +45,6 @@ import gleem.BSphere; import gleem.BSphereProvider; import gleem.ExaminerViewer; import gleem.ManipManager; -import gleem.MouseButtonHelper; import gleem.linalg.Rotf; import gleem.linalg.Vec3f; import java.awt.BorderLayout; @@ -332,7 +331,8 @@ public class VertexProgRefract extends Demo { manager.registerWindow((AWTGLAutoDrawable) drawable); this.drawable = drawable; - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer = new ExaminerViewer(); + viewer.setUpVector(Vec3f.Y_AXIS); viewer.setNoAltKeyMode(true); viewer.setAutoRedrawMode(false); viewer.attach((AWTGLAutoDrawable) drawable, new BSphereProvider() { diff --git a/src/demos/vertexProgWarp/VertexProgWarp.java b/src/demos/vertexProgWarp/VertexProgWarp.java index e6dbca7..8ab7166 100644 --- a/src/demos/vertexProgWarp/VertexProgWarp.java +++ b/src/demos/vertexProgWarp/VertexProgWarp.java @@ -43,7 +43,6 @@ import gleem.BSphere; import gleem.BSphereProvider; import gleem.ExaminerViewer; import gleem.ManipManager; -import gleem.MouseButtonHelper; import gleem.linalg.Vec3f; import java.awt.BorderLayout; import java.awt.Frame; @@ -231,7 +230,8 @@ public class VertexProgWarp extends Demo { manager.registerWindow((AWTGLAutoDrawable) drawable); this.drawable = drawable; - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer = new ExaminerViewer(); + viewer.setUpVector(Vec3f.Y_AXIS); viewer.setNoAltKeyMode(true); viewer.setAutoRedrawMode(false); viewer.attach((AWTGLAutoDrawable) drawable, new BSphereProvider() { 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 { diff --git a/src/gleem/MouseButtonHelper.java b/src/gleem/MouseButtonHelper.java deleted file mode 100644 index f682c53..0000000 --- a/src/gleem/MouseButtonHelper.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * gleem -- OpenGL Extremely Easy-To-Use Manipulators. - * Copyright (C) 1998-2003 Kenneth B. Russell ([email protected]) - * - * Copying, distribution and use of this software in source and binary - * forms, with or without modification, is permitted provided that the - * following conditions are met: - * - * Distributions of source code must reproduce the copyright notice, - * this list of conditions and the following disclaimer in the source - * code header files; and Distributions of binary code must reproduce - * the copyright notice, this list of conditions and the following - * disclaimer in the documentation, Read me file, license file and/or - * other materials provided with the software distribution. - * - * The names of Sun Microsystems, Inc. ("Sun") and/or the copyright - * holder may not be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED "AS IS," WITHOUT A WARRANTY OF ANY - * KIND. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND - * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, NON-INTERFERENCE, ACCURACY OF - * INFORMATIONAL CONTENT OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. THE - * COPYRIGHT HOLDER, SUN AND SUN'S LICENSORS SHALL NOT BE LIABLE FOR - * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL THE - * COPYRIGHT HOLDER, SUN OR SUN'S LICENSORS BE LIABLE FOR ANY LOST - * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, - * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND - * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR - * INABILITY TO USE THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGES. YOU ACKNOWLEDGE THAT THIS SOFTWARE IS NOT - * DESIGNED, LICENSED OR INTENDED FOR USE IN THE DESIGN, CONSTRUCTION, - * OPERATION OR MAINTENANCE OF ANY NUCLEAR FACILITY. THE COPYRIGHT - * HOLDER, SUN AND SUN'S LICENSORS DISCLAIM ANY EXPRESS OR IMPLIED - * WARRANTY OF FITNESS FOR SUCH USES. - */ - -package gleem; - -import java.security.*; - -/** Helper class for figuring out how many mouse buttons are - available. (Does not seem to be a way of figuring this out with - the AWT.) */ - -public class MouseButtonHelper { - /** Returns the number of buttons on the mouse device. This is only - a guess and the implementation may need to be extended to - support other operating systems (in particular, Mac OS). */ - public static int numMouseButtons() { - String osName = null; - if (System.getSecurityManager() != null) { - osName = (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty("os.name"); - } - }); - } else { - osName = System.getProperty("os.name"); - } - return mouseButtonsForOS(osName); - } - - private static int mouseButtonsForOS(String osName) { - if (osName.startsWith("Windows")) { - return 2; - } else { - // Assume X11 and a three-button mouse - return 3; - } - } -} diff --git a/src/gleem/TestExaminerViewer.java b/src/gleem/TestExaminerViewer.java index 03f4a00..aae755a 100644 --- a/src/gleem/TestExaminerViewer.java +++ b/src/gleem/TestExaminerViewer.java @@ -127,7 +127,8 @@ public class TestExaminerViewer { manager.showManipInWindow(manip, (AWTGLAutoDrawable) drawable); // Instantiate ExaminerViewer - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer = new ExaminerViewer(); + viewer.setUpVector(Vec3f.Y_AXIS); viewer.attach((AWTGLAutoDrawable) drawable, new HandleBoxManipBSphereProvider(manip)); viewer.viewAll(gl); } diff --git a/src/gleem/TestMultiWin.java b/src/gleem/TestMultiWin.java index ae78828..39fee6b 100644 --- a/src/gleem/TestMultiWin.java +++ b/src/gleem/TestMultiWin.java @@ -126,7 +126,8 @@ public class TestMultiWin { manager.showManipInWindow(manip, (AWTGLAutoDrawable) drawable); // Instantiate ExaminerViewer - viewer = new ExaminerViewer(MouseButtonHelper.numMouseButtons()); + viewer = new ExaminerViewer(); + viewer.setUpVector(Vec3f.Y_AXIS); viewer.attach((AWTGLAutoDrawable) drawable, new HandleBoxManipBSphereProvider(manip)); viewer.viewAll(gl); } diff --git a/src/gleem/linalg/MathUtil.java b/src/gleem/linalg/MathUtil.java index 7415953..fa3db3e 100644 --- a/src/gleem/linalg/MathUtil.java +++ b/src/gleem/linalg/MathUtil.java @@ -42,6 +42,15 @@ package gleem.linalg; /** Utility math routines. */ public class MathUtil { + /** A "close to zero" float epsilon value for use */ + public static final float FLT_EPSILON = 1.19209290e-07f; + + /** A "close to zero" double epsilon value for use */ + public static final double EPSILON = 2.220446049250313E-16d; + + /** A close, but not quite, zero float epsilon value for use */ + public static final float ZERO_TOLERANCE = 0.0001f; + /** Makes an arbitrary vector perpendicular to <B>src</B> and inserts it into <B>dest</B>. Returns false if the source vector was equal to (0, 0, 0). */ |