0001: /*
0002: * $RCSfile: OrbitBehavior.java,v $
0003: *
0004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * Redistribution and use in source and binary forms, with or without
0007: * modification, are permitted provided that the following conditions
0008: * are met:
0009: *
0010: * - Redistribution of source code must retain the above copyright
0011: * notice, this list of conditions and the following disclaimer.
0012: *
0013: * - Redistribution in binary form must reproduce the above copyright
0014: * notice, this list of conditions and the following disclaimer in
0015: * the documentation and/or other materials provided with the
0016: * distribution.
0017: *
0018: * Neither the name of Sun Microsystems, Inc. or the names of
0019: * contributors may be used to endorse or promote products derived
0020: * from this software without specific prior written permission.
0021: *
0022: * This software is provided "AS IS," without a warranty of any
0023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
0024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
0025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
0026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
0027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
0028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
0029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
0030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
0031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
0032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
0033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
0034: * POSSIBILITY OF SUCH DAMAGES.
0035: *
0036: * You acknowledge that this software is not designed, licensed or
0037: * intended for use in the design, construction, operation or
0038: * maintenance of any nuclear facility.
0039: *
0040: * $Revision: 1.6 $
0041: * $Date: 2007/10/08 23:08:02 $
0042: * $State: Exp $
0043: */
0044:
0045: package com.sun.j3d.utils.behaviors.vp;
0046:
0047: import java.awt.event.MouseEvent;
0048: import java.awt.AWTEvent;
0049:
0050: import javax.media.j3d.Transform3D;
0051: import javax.media.j3d.Canvas3D;
0052:
0053: import javax.vecmath.Vector3d;
0054: import javax.vecmath.Point3d;
0055: import javax.vecmath.Matrix3d;
0056:
0057: import com.sun.j3d.utils.universe.ViewingPlatform;
0058:
0059: import com.sun.j3d.internal.J3dUtilsI18N;
0060:
0061: /**
0062: * Moves the View around a point of interest when the mouse is dragged with
0063: * a mouse button pressed. Includes rotation, zoom, and translation
0064: * actions. Zooming can also be obtained by using mouse wheel.
0065: * <p>
0066: * This behavior must be added to the ViewingPlatform
0067: * using the <code>ViewingPlatform.setViewPlatformBehavior</code> method.
0068: * <p>
0069: * The rotate action rotates the ViewPlatform around the point of interest
0070: * when the mouse is moved with the main mouse button pressed. The
0071: * rotation is in the direction of the mouse movement, with a default
0072: * rotation of 0.01 radians for each pixel of mouse movement.
0073: * <p>
0074: * The zoom action moves the ViewPlatform closer to or further from the
0075: * point of interest when the mouse is moved with the middle mouse button
0076: * pressed (or Alt-main mouse button on systems without a middle mouse button).
0077: * The default zoom action is to translate the ViewPlatform 0.01 units for each
0078: * pixel of mouse movement. Moving the mouse up moves the ViewPlatform closer,
0079: * moving the mouse down moves the ViewPlatform further away.
0080: * <p>
0081: * By default, the zoom action allows the ViewPlatform to move through
0082: * the center of rotation to orbit at a negative radius.
0083: * The <code>STOP_ZOOM</code> constructor flag will stop the ViewPlatform at
0084: * a minimum radius from the center. The default minimum radius is 0.0
0085: * and can be set using the <code>setMinRadius</code> method.
0086: * <p>
0087: * The <code>PROPORTIONAL_ZOOM</code> constructor flag changes the zoom action
0088: * to move the ViewPlatform proportional to its distance from the center
0089: * of rotation. For this mode, the default action is to move the ViewPlatform
0090: * by 1% of its distance from the center of rotation for each pixel of
0091: * mouse movement.
0092: * <p>
0093: * The translate action translates the ViewPlatform when the mouse is moved
0094: * with the right mouse button pressed (Shift-main mouse button on systems
0095: * without a right mouse button). The translation is in the direction of the
0096: * mouse movement, with a default translation of 0.01 units for each pixel
0097: * of mouse movement.
0098: * <p>
0099: * The sensitivity of the actions can be scaled using the
0100: * <code>set</code><i>Action</i><code>Factor()</code> methods which scale
0101: * the default movement by the factor. The rotate and translate actions
0102: * have separate factors for x and y.
0103: * <p>
0104: * The actions can be reversed using the <code>REVERSE_</code><i>ACTION</i>
0105: * constructor flags. The default action moves the ViewPlatform around the
0106: * objects in the scene. The <code>REVERSE_</code><i>ACTION</i> flags can
0107: * make the objects in the scene appear to be moving in the direction
0108: * of the mouse movement.
0109: * <p>
0110: * The actions can be disabled by either using the
0111: * <code>DISABLE_</code><i>ACTION</i> constructor flags or the
0112: * <code>set</code><i>Action</i><code>Enable</code> methods.
0113: * <p>
0114: * The default center of rotation is (0, 0, 0) and can be set using the
0115: * <code>setRotationCenter()</code> method.
0116: *
0117: * @since Java 3D 1.2.1
0118: */
0119: public class OrbitBehavior extends ViewPlatformAWTBehavior {
0120:
0121: private Transform3D longditudeTransform = new Transform3D();
0122: private Transform3D latitudeTransform = new Transform3D();
0123: private Transform3D rotateTransform = new Transform3D();
0124:
0125: // needed for integrateTransforms but don't want to new every time
0126: private Transform3D temp1 = new Transform3D();
0127: private Transform3D temp2 = new Transform3D();
0128: private Transform3D translation = new Transform3D();
0129: private Vector3d transVector = new Vector3d();
0130: private Vector3d distanceVector = new Vector3d();
0131: private Vector3d centerVector = new Vector3d();
0132: private Vector3d invertCenterVector = new Vector3d();
0133:
0134: private double longditude = 0.0;
0135: private double latitude = 0.0;
0136: private double startDistanceFromCenter = 20.0;
0137: private double distanceFromCenter = 20.0;
0138: private Point3d rotationCenter = new Point3d();
0139: private Matrix3d rotMatrix = new Matrix3d();
0140: private Transform3D currentXfm = new Transform3D();
0141:
0142: private int mouseX = 0;
0143: private int mouseY = 0;
0144:
0145: private double rotXFactor = 1.0;
0146: private double rotYFactor = 1.0;
0147: private double transXFactor = 1.0;
0148: private double transYFactor = 1.0;
0149: private double zoomFactor = 1.0;
0150:
0151: private double xtrans = 0.0;
0152: private double ytrans = 0.0;
0153: private double ztrans = 0.0;
0154:
0155: private boolean zoomEnabled = true;
0156: private boolean rotateEnabled = true;
0157: private boolean translateEnabled = true;
0158: private boolean reverseRotate = false;
0159: private boolean reverseTrans = false;
0160: private boolean reverseZoom = false;
0161: private boolean stopZoom = false;
0162: private boolean proportionalZoom = false;
0163: private double minRadius = 0.0;
0164: private int leftButton = ROTATE;
0165: private int rightButton = TRANSLATE;
0166: private int middleButton = ZOOM;
0167:
0168: // the factor to be applied to wheel zooming so that it does not
0169: // look much different with mouse movement zooming.
0170: // This is a totally subjective factor.
0171: private float wheelZoomFactor = 50.0f;
0172:
0173: /**
0174: * Constructor flag to reverse the rotate behavior
0175: */
0176: public static final int REVERSE_ROTATE = 0x010;
0177:
0178: /**
0179: * Constructor flag to reverse the translate behavior
0180: */
0181: public static final int REVERSE_TRANSLATE = 0x020;
0182:
0183: /**
0184: * Constructor flag to reverse the zoom behavior
0185: */
0186: public static final int REVERSE_ZOOM = 0x040;
0187:
0188: /**
0189: * Constructor flag to reverse all the behaviors
0190: */
0191: public static final int REVERSE_ALL = (REVERSE_ROTATE
0192: | REVERSE_TRANSLATE | REVERSE_ZOOM);
0193:
0194: /**
0195: * Constructor flag that indicates zoom should stop when it reaches
0196: * the minimum orbit radius set by setMinRadius(). The minimus
0197: * radius default is 0.0.
0198: */
0199: public static final int STOP_ZOOM = 0x100;
0200:
0201: /**
0202: * Constructor flag to disable rotate
0203: */
0204: public static final int DISABLE_ROTATE = 0x200;
0205:
0206: /**
0207: * Constructor flag to disable translate
0208: */
0209: public static final int DISABLE_TRANSLATE = 0x400;
0210:
0211: /**
0212: * Constructor flag to disable zoom
0213: */
0214: public static final int DISABLE_ZOOM = 0x800;
0215:
0216: /**
0217: * Constructor flag to use proportional zoom, which determines
0218: * how much you zoom based on view's distance from the center of
0219: * rotation. The percentage of distance that the viewer zooms
0220: * is determined by the zoom factor.
0221: */
0222: public static final int PROPORTIONAL_ZOOM = 0x1000;
0223:
0224: /**
0225: * Used to set the fuction for a mouse button to Rotate
0226: */
0227: private static final int ROTATE = 0;
0228:
0229: /**
0230: * Used to set the function for a mouse button to Translate
0231: */
0232: private static final int TRANSLATE = 1;
0233:
0234: /**
0235: * Used to set the function for a mouse button to Zoom
0236: */
0237: private static final int ZOOM = 2;
0238:
0239: private static final double NOMINAL_ZOOM_FACTOR = .01;
0240: private static final double NOMINAL_PZOOM_FACTOR = 1.0;
0241: private static final double NOMINAL_ROT_FACTOR = .01;
0242: private static final double NOMINAL_TRANS_FACTOR = .01;
0243:
0244: private double rotXMul = NOMINAL_ROT_FACTOR * rotXFactor;
0245: private double rotYMul = NOMINAL_ROT_FACTOR * rotYFactor;
0246: private double transXMul = NOMINAL_TRANS_FACTOR * transXFactor;
0247: private double transYMul = NOMINAL_TRANS_FACTOR * transYFactor;
0248: private double zoomMul = NOMINAL_ZOOM_FACTOR * zoomFactor;
0249:
0250: /**
0251: * Parameterless constructor for this behavior. This is intended for use
0252: * by ConfiguredUniverse, which requires such a constructor for
0253: * configurable behaviors. The Canvas3D used to listen for mouse and
0254: * mouse motion events is obtained from the superclass
0255: * setViewingPlatform() method.
0256: * @since Java 3D 1.3
0257: */
0258: public OrbitBehavior() {
0259: super (MOUSE_LISTENER | MOUSE_MOTION_LISTENER
0260: | MOUSE_WHEEL_LISTENER);
0261: }
0262:
0263: /**
0264: * Creates a new OrbitBehavior
0265: *
0266: * @param c The Canvas3D to add the behavior to
0267: */
0268: public OrbitBehavior(Canvas3D c) {
0269: this (c, 0);
0270: }
0271:
0272: /**
0273: * Creates a new OrbitBehavior
0274: *
0275: * @param c The Canvas3D to add the behavior to
0276: * @param flags The option flags
0277: */
0278: public OrbitBehavior(Canvas3D c, int flags) {
0279: super (c, MOUSE_LISTENER | MOUSE_MOTION_LISTENER
0280: | MOUSE_WHEEL_LISTENER | flags);
0281:
0282: if ((flags & DISABLE_ROTATE) != 0)
0283: rotateEnabled = false;
0284: if ((flags & DISABLE_ZOOM) != 0)
0285: zoomEnabled = false;
0286: if ((flags & DISABLE_TRANSLATE) != 0)
0287: translateEnabled = false;
0288: if ((flags & REVERSE_TRANSLATE) != 0)
0289: reverseTrans = true;
0290: if ((flags & REVERSE_ROTATE) != 0)
0291: reverseRotate = true;
0292: if ((flags & REVERSE_ZOOM) != 0)
0293: reverseZoom = true;
0294: if ((flags & STOP_ZOOM) != 0)
0295: stopZoom = true;
0296: if ((flags & PROPORTIONAL_ZOOM) != 0) {
0297: proportionalZoom = true;
0298: zoomMul = NOMINAL_PZOOM_FACTOR * zoomFactor;
0299: }
0300: }
0301:
0302: protected synchronized void processAWTEvents(final AWTEvent[] events) {
0303: motion = false;
0304: for (int i = 0; i < events.length; i++)
0305: if (events[i] instanceof MouseEvent)
0306: processMouseEvent((MouseEvent) events[i]);
0307: }
0308:
0309: protected void processMouseEvent(final MouseEvent evt) {
0310:
0311: if (evt.getID() == MouseEvent.MOUSE_PRESSED) {
0312: mouseX = evt.getX();
0313: mouseY = evt.getY();
0314: motion = true;
0315: } else if (evt.getID() == MouseEvent.MOUSE_DRAGGED) {
0316: int xchange = evt.getX() - mouseX;
0317: int ychange = evt.getY() - mouseY;
0318: // rotate
0319: if (rotate(evt)) {
0320: if (reverseRotate) {
0321: longditude -= xchange * rotXMul;
0322: latitude -= ychange * rotYMul;
0323: } else {
0324: longditude += xchange * rotXMul;
0325: latitude += ychange * rotYMul;
0326: }
0327: }
0328: // translate
0329: else if (translate(evt)) {
0330: if (reverseTrans) {
0331: xtrans -= xchange * transXMul;
0332: ytrans += ychange * transYMul;
0333: } else {
0334: xtrans += xchange * transXMul;
0335: ytrans -= ychange * transYMul;
0336: }
0337: }
0338: // zoom
0339: else if (zoom(evt)) {
0340: doZoomOperations(ychange);
0341: }
0342: mouseX = evt.getX();
0343: mouseY = evt.getY();
0344: motion = true;
0345: } else if (evt.getID() == MouseEvent.MOUSE_RELEASED) {
0346: } else if (evt.getID() == MouseEvent.MOUSE_WHEEL) {
0347: if (zoom(evt)) {
0348: // if zooming is done through mouse wheel,
0349: // the amount of increments the wheel changed,
0350: // multiplied with wheelZoomFactor is used,
0351: // so that zooming speed looks natural compared to mouse movement zoom.
0352: if (evt instanceof java.awt.event.MouseWheelEvent) {
0353: // I/O differenciation is made between
0354: // java.awt.event.MouseWheelEvent.WHEEL_UNIT_SCROLL or
0355: // java.awt.event.MouseWheelEvent.WHEEL_BLOCK_SCROLL so
0356: // that behavior remains stable and not dependent on OS settings.
0357: // If getWheelRotation() was used for calculating the zoom,
0358: // the zooming speed could act differently on different platforms,
0359: // if, for example, the user sets his mouse wheel to jump 10 lines
0360: // or a block.
0361: int zoom = ((int) (((java.awt.event.MouseWheelEvent) evt)
0362: .getWheelRotation() * wheelZoomFactor));
0363: doZoomOperations(zoom);
0364: motion = true;
0365: }
0366: }
0367: }
0368: }
0369:
0370: /*extraction of the zoom algorithms so that there is no code duplication or source 'uglyfication'.
0371: */
0372: private void doZoomOperations(int ychange) {
0373: if (proportionalZoom) {
0374: if (reverseZoom) {
0375: if ((distanceFromCenter - (zoomMul * ychange
0376: * distanceFromCenter / 100.0)) > minRadius) {
0377: distanceFromCenter -= (zoomMul * ychange
0378: * distanceFromCenter / 100.0);
0379: } else {
0380: distanceFromCenter = minRadius;
0381: }
0382: } else {
0383: if ((distanceFromCenter + (zoomMul * ychange
0384: * distanceFromCenter / 100.0)) > minRadius) {
0385: distanceFromCenter += (zoomMul * ychange
0386: * distanceFromCenter / 100.0);
0387: } else {
0388: distanceFromCenter = minRadius;
0389: }
0390: }
0391: } else {
0392: if (stopZoom) {
0393: if (reverseZoom) {
0394: if ((distanceFromCenter - ychange * zoomMul) > minRadius) {
0395: distanceFromCenter -= ychange * zoomMul;
0396: } else {
0397: distanceFromCenter = minRadius;
0398: }
0399: } else {
0400: if ((distanceFromCenter + ychange * zoomMul) > minRadius) {
0401: distanceFromCenter += ychange * zoomMul;
0402: } else {
0403: distanceFromCenter = minRadius;
0404: }
0405: }
0406: } else {
0407: if (reverseZoom) {
0408: distanceFromCenter -= ychange * zoomMul;
0409: } else {
0410: distanceFromCenter += ychange * zoomMul;
0411: }
0412: }
0413: }
0414: }
0415:
0416: /**
0417: * Sets the ViewingPlatform for this behavior. This method is
0418: * called by the ViewingPlatform.
0419: * If a sub-calls overrides this method, it must call
0420: * super.setViewingPlatform(vp).
0421: * NOTE: Applications should <i>not</i> call this method.
0422: */
0423: @Override
0424: public void setViewingPlatform(ViewingPlatform vp) {
0425: super .setViewingPlatform(vp);
0426:
0427: if (vp != null) {
0428: resetView();
0429: integrateTransforms();
0430: }
0431: }
0432:
0433: /**
0434: * Reset the orientation and distance of this behavior to the current
0435: * values in the ViewPlatform Transform Group
0436: */
0437: private void resetView() {
0438: Vector3d centerToView = new Vector3d();
0439:
0440: targetTG.getTransform(targetTransform);
0441:
0442: targetTransform.get(rotMatrix, transVector);
0443: centerToView.sub(transVector, rotationCenter);
0444: distanceFromCenter = centerToView.length();
0445: startDistanceFromCenter = distanceFromCenter;
0446:
0447: targetTransform.get(rotMatrix);
0448: rotateTransform.set(rotMatrix);
0449:
0450: // compute the initial x/y/z offset
0451: temp1.set(centerToView);
0452: rotateTransform.invert();
0453: rotateTransform.mul(temp1);
0454: rotateTransform.get(centerToView);
0455: xtrans = centerToView.x;
0456: ytrans = centerToView.y;
0457: ztrans = centerToView.z;
0458:
0459: // reset rotMatrix
0460: rotateTransform.set(rotMatrix);
0461: }
0462:
0463: protected synchronized void integrateTransforms() {
0464: // Check if the transform has been changed by another
0465: // behavior
0466: targetTG.getTransform(currentXfm);
0467: if (!targetTransform.equals(currentXfm))
0468: resetView();
0469:
0470: longditudeTransform.rotY(longditude);
0471: latitudeTransform.rotX(latitude);
0472: rotateTransform.mul(rotateTransform, latitudeTransform);
0473: rotateTransform.mul(rotateTransform, longditudeTransform);
0474:
0475: distanceVector.z = distanceFromCenter - startDistanceFromCenter;
0476:
0477: temp1.set(distanceVector);
0478: temp1.mul(rotateTransform, temp1);
0479:
0480: // want to look at rotationCenter
0481: transVector.x = rotationCenter.x + xtrans;
0482: transVector.y = rotationCenter.y + ytrans;
0483: transVector.z = rotationCenter.z + ztrans;
0484:
0485: translation.set(transVector);
0486: targetTransform.mul(temp1, translation);
0487:
0488: // handle rotationCenter
0489: temp1.set(centerVector);
0490: temp1.mul(targetTransform);
0491:
0492: invertCenterVector.x = -centerVector.x;
0493: invertCenterVector.y = -centerVector.y;
0494: invertCenterVector.z = -centerVector.z;
0495:
0496: temp2.set(invertCenterVector);
0497: targetTransform.mul(temp1, temp2);
0498:
0499: targetTG.setTransform(targetTransform);
0500:
0501: // reset yaw and pitch angles
0502: longditude = 0.0;
0503: latitude = 0.0;
0504: }
0505:
0506: /**
0507: * Sets the center around which the View rotates.
0508: * The default is (0,0,0).
0509: * @param center The Point3d to set the center of rotation to
0510: */
0511: public synchronized void setRotationCenter(Point3d center) {
0512: Point3d centerDelta = new Point3d();
0513: centerDelta.sub(centerVector, center);
0514: Transform3D invRot = new Transform3D(rotateTransform);
0515: invRot.invert();
0516: invRot.transform(centerDelta);
0517: xtrans += centerDelta.x;
0518: ytrans += centerDelta.y;
0519: ztrans += centerDelta.z;
0520: rotationCenter.x = center.x;
0521: rotationCenter.y = center.y;
0522: rotationCenter.z = center.z;
0523: centerVector.set(rotationCenter);
0524: }
0525:
0526: /**
0527: * Property which sets the center around which the View rotates.
0528: * Used by ConfiguredUniverse.
0529: * @param center array of length 1 containing an instance of Point3d
0530: * @since Java 3D 1.3
0531: */
0532: public void RotationCenter(Object[] center) {
0533: if (!(center.length == 1 && center[0] instanceof Point3d))
0534: throw new IllegalArgumentException(
0535: "RotationCenter must be a single Point3d");
0536:
0537: setRotationCenter((Point3d) center[0]);
0538: }
0539:
0540: /**
0541: * Places the value of the center around which the View rotates
0542: * into the Point3d.
0543: * @param center The Point3d
0544: */
0545: public void getRotationCenter(Point3d center) {
0546: center.x = rotationCenter.x;
0547: center.y = rotationCenter.y;
0548: center.z = rotationCenter.z;
0549: }
0550:
0551: // TODO
0552: // Need to add key factors for Rotate, Translate and Zoom
0553: // Method calls should just update MAX_KEY_ANGLE, KEY_TRANSLATE and
0554: // KEY_ZOOM
0555: //
0556: // Methods also need to correctly set sign of variables depending on
0557: // the Reverse settings.
0558:
0559: /**
0560: * Sets the rotation x and y factors. The factors are used to determine
0561: * how many radians to rotate the view for each pixel of mouse movement.
0562: * The view is rotated factor * 0.01 radians for each pixel of mouse
0563: * movement. The default factor is 1.0.
0564: * @param xfactor The x movement multiplier
0565: * @param yfactor The y movement multiplier
0566: **/
0567: public synchronized void setRotFactors(double xfactor,
0568: double yfactor) {
0569: rotXFactor = xfactor;
0570: rotYFactor = yfactor;
0571: rotXMul = NOMINAL_ROT_FACTOR * xfactor;
0572: rotYMul = NOMINAL_ROT_FACTOR * yfactor;
0573: }
0574:
0575: /**
0576: * Property which sets the rotation x and y factors.
0577: * Used by ConfiguredUniverse.
0578: * @param factors array of length 2 containing instances of Double
0579: * @since Java 3D 1.3
0580: */
0581: public void RotFactors(Object[] factors) {
0582: if (!(factors.length == 2 && factors[0] instanceof Double && factors[1] instanceof Double))
0583: throw new IllegalArgumentException(
0584: "RotFactors must be two Doubles");
0585:
0586: setRotFactors(((Double) factors[0]).doubleValue(),
0587: ((Double) factors[1]).doubleValue());
0588: }
0589:
0590: /**
0591: * Sets the rotation x factor. The factors are used to determine
0592: * how many radians to rotate the view for each pixel of mouse movement.
0593: * The view is rotated factor * 0.01 radians for each pixel of mouse
0594: * movement. The default factor is 1.0.
0595: * @param xfactor The x movement multiplier
0596: **/
0597: public synchronized void setRotXFactor(double xfactor) {
0598: rotXFactor = xfactor;
0599: rotXMul = NOMINAL_ROT_FACTOR * xfactor;
0600: }
0601:
0602: /**
0603: * Property which sets the rotation x factor.
0604: * Used by ConfiguredUniverse.
0605: * @param xFactor array of length 1 containing instance of Double
0606: * @since Java 3D 1.3
0607: */
0608: public void RotXFactor(Object[] xFactor) {
0609: if (!(xFactor.length == 1 && xFactor[0] instanceof Double))
0610: throw new IllegalArgumentException(
0611: "RotXFactor must be a Double");
0612:
0613: setRotXFactor(((Double) xFactor[0]).doubleValue());
0614: }
0615:
0616: /**
0617: * Sets the rotation y factor. The factors are used to determine
0618: * how many radians to rotate the view for each pixel of mouse movement.
0619: * The view is rotated factor * 0.01 radians for each pixel of mouse
0620: * movement. The default factor is 1.0.
0621: * @param yfactor The y movement multiplier
0622: **/
0623: public synchronized void setRotYFactor(double yfactor) {
0624: rotYFactor = yfactor;
0625: rotYMul = NOMINAL_ROT_FACTOR * yfactor;
0626: }
0627:
0628: /**
0629: * Property which sets the rotation y factor.
0630: * Used by ConfiguredUniverse.
0631: * @param yFactor array of length 1 containing instance of Double
0632: * @since Java 3D 1.3
0633: */
0634: public void RotYFactor(Object[] yFactor) {
0635: if (!(yFactor.length == 1 && yFactor[0] instanceof Double))
0636: throw new IllegalArgumentException(
0637: "RotYFactor must be a Double");
0638:
0639: setRotYFactor(((Double) yFactor[0]).doubleValue());
0640: }
0641:
0642: /**
0643: * Sets the translation x and y factors. The factors are used to determine
0644: * how many units to translate the view for each pixel of mouse movement.
0645: * The view is translated factor * 0.01 units for each pixel of mouse
0646: * movement. The default factor is 1.0.
0647: * @param xfactor The x movement multiplier
0648: * @param yfactor The y movement multiplier
0649: **/
0650: public synchronized void setTransFactors(double xfactor,
0651: double yfactor) {
0652: transXFactor = xfactor;
0653: transYFactor = yfactor;
0654: transXMul = NOMINAL_TRANS_FACTOR * xfactor;
0655: transYMul = NOMINAL_TRANS_FACTOR * yfactor;
0656: }
0657:
0658: /**
0659: * Property which sets the translation x and y factors.
0660: * Used by ConfiguredUniverse.
0661: * @param factors array of length 2 containing instances of Double
0662: * @since Java 3D 1.3
0663: */
0664: public void TransFactors(Object[] factors) {
0665: if (!(factors.length == 2 && factors[0] instanceof Double && factors[1] instanceof Double))
0666: throw new IllegalArgumentException(
0667: "TransFactors must be two Doubles");
0668:
0669: setTransFactors(((Double) factors[0]).doubleValue(),
0670: ((Double) factors[1]).doubleValue());
0671: }
0672:
0673: /**
0674: * Sets the translation x factor. The factors are used to determine
0675: * how many units to translate the view for each pixel of mouse movement.
0676: * The view is translated factor * 0.01 units for each pixel of mouse
0677: * movement. The default factor is 1.0.
0678: * @param xfactor The x movement multiplier
0679: **/
0680: public synchronized void setTransXFactor(double xfactor) {
0681: transXFactor = xfactor;
0682: transXMul = NOMINAL_TRANS_FACTOR * xfactor;
0683: }
0684:
0685: /**
0686: * Property which sets the translation x factor.
0687: * Used by ConfiguredUniverse.
0688: * @param xFactor array of length 1 containing instance of Double
0689: * @since Java 3D 1.3
0690: */
0691: public void TransXFactor(Object[] xFactor) {
0692: if (!(xFactor.length == 1 && xFactor[0] instanceof Double))
0693: throw new IllegalArgumentException(
0694: "TransXFactor must be a Double");
0695:
0696: setTransXFactor(((Double) xFactor[0]).doubleValue());
0697: }
0698:
0699: /**
0700: * Sets the translation y factor. The factors are used to determine
0701: * how many units to translate the view for each pixel of mouse movement.
0702: * The view is translated factor * 0.01 units for each pixel of mouse
0703: * movement. The default factor is 1.0.
0704: * @param yfactor The y movement multiplier
0705: **/
0706: public synchronized void setTransYFactor(double yfactor) {
0707: transYFactor = yfactor;
0708: transYMul = NOMINAL_TRANS_FACTOR * yfactor;
0709: }
0710:
0711: /**
0712: * Property which sets the translation y factor.
0713: * Used by ConfiguredUniverse.
0714: * @param yFactor array of length 1 containing instance of Double
0715: * @since Java 3D 1.3
0716: */
0717: public void TransYFactor(Object[] yFactor) {
0718: if (!(yFactor.length == 1 && yFactor[0] instanceof Double))
0719: throw new IllegalArgumentException(
0720: "TransYFactor must be a Double");
0721:
0722: setTransYFactor(((Double) yFactor[0]).doubleValue());
0723: }
0724:
0725: /**
0726: * Sets the zoom factor. The factor is used to determine how many
0727: * units to zoom the view for each pixel of mouse movement.
0728: * The view is zoomed factor * 0.01 units for each pixel of mouse
0729: * movement. For proportional zoom, the view is zoomed factor * 1%
0730: * of the distance from the center of rotation for each pixel of
0731: * mouse movement. The default factor is 1.0.
0732: * @param zfactor The movement multiplier
0733: */
0734: public synchronized void setZoomFactor(double zfactor) {
0735: zoomFactor = zfactor;
0736: if (proportionalZoom) {
0737: zoomMul = NOMINAL_PZOOM_FACTOR * zfactor;
0738: } else {
0739: zoomMul = NOMINAL_ZOOM_FACTOR * zfactor;
0740: }
0741: }
0742:
0743: /**
0744: * Property which sets the zoom factor.
0745: * Used by ConfiguredUniverse.
0746: * @param zFactor array of length 1 containing instance of Double
0747: * @since Java 3D 1.3
0748: */
0749: public void ZoomFactor(Object[] zFactor) {
0750: if (!(zFactor.length == 1 && zFactor[0] instanceof Double))
0751: throw new IllegalArgumentException(
0752: "ZoomFactor must be a Double");
0753:
0754: setZoomFactor(((Double) zFactor[0]).doubleValue());
0755: }
0756:
0757: /**
0758: * Returns the x rotation movement multiplier
0759: * @return The movement multiplier for x rotation
0760: */
0761: public double getRotXFactor() {
0762: return rotXFactor;
0763: }
0764:
0765: /**
0766: * Returns the y rotation movement multiplier
0767: * @return The movement multiplier for y rotation
0768: */
0769: public double getRotYFactor() {
0770: return rotYFactor;
0771: }
0772:
0773: /**
0774: * Returns the x translation movement multiplier
0775: * @return The movement multiplier for x translation
0776: */
0777: public double getTransXFactor() {
0778: return transXFactor;
0779: }
0780:
0781: /**
0782: * Returns the y translation movement multiplier
0783: * @return The movement multiplier for y translation
0784: */
0785: public double getTransYFactor() {
0786: return transYFactor;
0787: }
0788:
0789: /**
0790: * Returns the zoom movement multiplier
0791: * @return The movement multiplier for zoom
0792: */
0793: public double getZoomFactor() {
0794: return zoomFactor;
0795: }
0796:
0797: /**
0798: * Enables or disables rotation. The default is true.
0799: * @param enabled true or false to enable or disable rotate
0800: */
0801: public synchronized void setRotateEnable(boolean enabled) {
0802: rotateEnabled = enabled;
0803: }
0804:
0805: /**
0806: * Property which enables or disables rotation.
0807: * Used by ConfiguredUniverse.
0808: * @param enabled array of length 1 containing instance of Boolean
0809: * @since Java 3D 1.3
0810: */
0811: public void RotateEnable(Object[] enabled) {
0812: if (!(enabled.length == 1 && enabled[0] instanceof Boolean))
0813: throw new IllegalArgumentException(
0814: "RotateEnable must be Boolean");
0815:
0816: setRotateEnable(((Boolean) enabled[0]).booleanValue());
0817: }
0818:
0819: /**
0820: * Enables or disables zoom. The default is true.
0821: * @param enabled true or false to enable or disable zoom
0822: */
0823: public synchronized void setZoomEnable(boolean enabled) {
0824: zoomEnabled = enabled;
0825: }
0826:
0827: /**
0828: * Property which enables or disables zoom.
0829: * Used by ConfiguredUniverse.
0830: * @param enabled array of length 1 containing instance of Boolean
0831: * @since Java 3D 1.3
0832: */
0833: public void ZoomEnable(Object[] enabled) {
0834: if (!(enabled.length == 1 && enabled[0] instanceof Boolean))
0835: throw new IllegalArgumentException(
0836: "ZoomEnable must be Boolean");
0837:
0838: setZoomEnable(((Boolean) enabled[0]).booleanValue());
0839: }
0840:
0841: /**
0842: * Enables or disables translate. The default is true.
0843: * @param enabled true or false to enable or disable translate
0844: */
0845: public synchronized void setTranslateEnable(boolean enabled) {
0846: translateEnabled = enabled;
0847: }
0848:
0849: /**
0850: * Property which enables or disables translate.
0851: * Used by ConfiguredUniverse.
0852: * @param enabled array of length 1 containing instance of Boolean
0853: * @since Java 3D 1.3
0854: */
0855: public void TranslateEnable(Object[] enabled) {
0856: if (!(enabled.length == 1 && enabled[0] instanceof Boolean))
0857: throw new IllegalArgumentException(
0858: "TranslateEnable must be Boolean");
0859:
0860: setTranslateEnable(((Boolean) enabled[0]).booleanValue());
0861: }
0862:
0863: /**
0864: * Retrieves the state of rotate enabled
0865: * @return the rotate enable state
0866: */
0867: public boolean getRotateEnable() {
0868: return rotateEnabled;
0869: }
0870:
0871: /**
0872: * Retrieves the state of zoom enabled
0873: * @return the zoom enable state
0874: */
0875: public boolean getZoomEnable() {
0876: return zoomEnabled;
0877: }
0878:
0879: /**
0880: * Retrieves the state of translate enabled
0881: * @return the translate enable state
0882: */
0883: public boolean getTranslateEnable() {
0884: return translateEnabled;
0885: }
0886:
0887: boolean rotate(MouseEvent evt) {
0888: if (rotateEnabled) {
0889: if ((leftButton == ROTATE)
0890: && (!evt.isAltDown() && !evt.isMetaDown())) {
0891: return true;
0892: }
0893: if ((middleButton == ROTATE)
0894: && (evt.isAltDown() && !evt.isMetaDown())) {
0895: return true;
0896: }
0897: if ((rightButton == ROTATE)
0898: && (!evt.isAltDown() && evt.isMetaDown())) {
0899: return true;
0900: }
0901: }
0902: return false;
0903: }
0904:
0905: boolean zoom(MouseEvent evt) {
0906: if (zoomEnabled) {
0907: if (evt instanceof java.awt.event.MouseWheelEvent) {
0908: return true;
0909: }
0910: if ((leftButton == ZOOM)
0911: && (!evt.isAltDown() && !evt.isMetaDown())) {
0912: return true;
0913: }
0914: if ((middleButton == ZOOM)
0915: && (evt.isAltDown() && !evt.isMetaDown())) {
0916: return true;
0917: }
0918: if ((rightButton == ZOOM)
0919: && (!evt.isAltDown() && evt.isMetaDown())) {
0920: return true;
0921: }
0922: }
0923: return false;
0924: }
0925:
0926: boolean translate(MouseEvent evt) {
0927: if (translateEnabled) {
0928: if ((leftButton == TRANSLATE)
0929: && (!evt.isAltDown() && !evt.isMetaDown())) {
0930: return true;
0931: }
0932: if ((middleButton == TRANSLATE)
0933: && (evt.isAltDown() && !evt.isMetaDown())) {
0934: return true;
0935: }
0936: if ((rightButton == TRANSLATE)
0937: && (!evt.isAltDown() && evt.isMetaDown())) {
0938: return true;
0939: }
0940: }
0941: return false;
0942: }
0943:
0944: /**
0945: * Sets the minimum radius for the OrbitBehavior. The zoom will
0946: * stop at this distance from the center of rotation. The default
0947: * is 0.0. The minimum will have no affect if the STOP_ZOOM constructor
0948: * flag is not set.
0949: * @param r the minimum radius
0950: * @exception IllegalArgumentException if the radius is less than 0.0
0951: */
0952: public synchronized void setMinRadius(double r) {
0953: if (r < 0.0) {
0954: throw new IllegalArgumentException(J3dUtilsI18N
0955: .getString("OrbitBehavior1"));
0956: }
0957: minRadius = r;
0958: }
0959:
0960: /**
0961: * Property which sets the minimum radius for the OrbitBehavior.
0962: * Used by ConfiguredUniverse.
0963: * @param r array of length 1 containing instance of Double
0964: * @since Java 3D 1.3
0965: */
0966: public void MinRadius(Object[] r) {
0967: if (!(r.length == 1 && r[0] instanceof Double))
0968: throw new IllegalArgumentException(
0969: "MinRadius must be a Double");
0970:
0971: setMinRadius(((Double) r[0]).doubleValue());
0972: }
0973:
0974: /**
0975: * Returns the minimum orbit radius. The zoom will stop at this distance
0976: * from the center of rotation if the STOP_ZOOM constructor flag is set.
0977: * @return the minimum radius
0978: */
0979: public double getMinRadius() {
0980: return minRadius;
0981: }
0982:
0983: /**
0984: * Set reverse translate behavior. The default is false.
0985: * @param state if true, reverse translate behavior
0986: * @since Java 3D 1.3
0987: */
0988: public void setReverseTranslate(boolean state) {
0989: reverseTrans = state;
0990: }
0991:
0992: /**
0993: * Property which sets reverse translate behavior.
0994: * Used by ConfiguredUniverse.
0995: * @param state array of length 1 containing instance of Boolean
0996: * @since Java 3D 1.3
0997: */
0998: public void ReverseTranslate(Object[] state) {
0999: if (!(state.length == 1 && state[0] instanceof Boolean))
1000: throw new IllegalArgumentException(
1001: "ReverseTranslate must be Boolean");
1002:
1003: setReverseTranslate(((Boolean) state[0]).booleanValue());
1004: }
1005:
1006: /**
1007: * Set reverse rotate behavior. The default is false.
1008: * @param state if true, reverse rotate behavior
1009: * @since Java 3D 1.3
1010: */
1011: public void setReverseRotate(boolean state) {
1012: reverseRotate = state;
1013: }
1014:
1015: /**
1016: * Property which sets reverse rotate behavior.
1017: * Used by ConfiguredUniverse.
1018: * @param state array of length 1 containing instance of Boolean
1019: * @since Java 3D 1.3
1020: */
1021: public void ReverseRotate(Object[] state) {
1022: if (!(state.length == 1 && state[0] instanceof Boolean))
1023: throw new IllegalArgumentException(
1024: "ReverseRotate must be Boolean");
1025:
1026: setReverseRotate(((Boolean) state[0]).booleanValue());
1027: }
1028:
1029: /**
1030: * Set reverse zoom behavior. The default is false.
1031: * @param state if true, reverse zoom behavior
1032: * @since Java 3D 1.3
1033: */
1034: public void setReverseZoom(boolean state) {
1035: reverseZoom = state;
1036: }
1037:
1038: /**
1039: * Property which sets reverse zoom behavior.
1040: * Used by ConfiguredUniverse.
1041: * @param state array of length 1 containing instance of Boolean
1042: * @since Java 3D 1.3
1043: */
1044: public void ReverseZoom(Object[] state) {
1045: if (!(state.length == 1 && state[0] instanceof Boolean))
1046: throw new IllegalArgumentException(
1047: "ReverseZoom must be Boolean");
1048:
1049: setReverseZoom(((Boolean) state[0]).booleanValue());
1050: }
1051:
1052: /**
1053: * Set proportional zoom behavior. The default is false.
1054: * @param state if true, use proportional zoom behavior
1055: * @since Java 3D 1.3
1056: */
1057: public synchronized void setProportionalZoom(boolean state) {
1058: proportionalZoom = state;
1059:
1060: if (state) {
1061: zoomMul = NOMINAL_PZOOM_FACTOR * zoomFactor;
1062: } else {
1063: zoomMul = NOMINAL_ZOOM_FACTOR * zoomFactor;
1064: }
1065: }
1066:
1067: /**
1068: * Property which sets proportional zoom behavior.
1069: * Used by ConfiguredUniverse.
1070: * @param state array of length 1 containing instance of Boolean
1071: * @since Java 3D 1.3
1072: */
1073: public void ProportionalZoom(Object[] state) {
1074: if (!(state.length == 1 && state[0] instanceof Boolean))
1075: throw new IllegalArgumentException(
1076: "ProportionalZoom must be Boolean");
1077:
1078: setProportionalZoom(((Boolean) state[0]).booleanValue());
1079: }
1080: }
|