View Javadoc

    1   /*
    2    * @(#)RotateXYMouseBehavior.java 1.5 02/04/01 15:04:09
    3    *
    4    * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
    5    *
    6    * Redistribution and use in source and binary forms, with or without
    7    * modification, are permitted provided that the following conditions are met: -
    8    * Redistributions of source code must retain the above copyright notice, this
    9    * list of conditions and the following disclaimer. - Redistribution in binary
    10   * form must reproduce the above copyright notice, this list of conditions and
    11   * the following disclaimer in the documentation and/or other materials provided
    12   * with the distribution.
    13   *
    14   * Neither the name of Sun Microsystems, Inc. or the names of contributors may
    15   * be used to endorse or promote products derived from this software without
    16   * specific prior written permission.
    17   *
    18   * This software is provided "AS IS," without a warranty of any kind. ALL
    19   * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
    20   * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
    21   * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
    22   * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
    23   * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
    24   * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
    25   * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
    26   * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
    27   * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY
    28   * OF SUCH DAMAGES.
    29   *
    30   * You acknowledge that Software is not designed,licensed or intended for use in
    31   * the design, construction, operation or maintenance of any nuclear facility.
    32   */
    33  /*
    34   * Modified to rotate along two axis: x and y. Copyright (c) 2002-2005 Delft
    35   * University of Technology Jaffalaan 5, 2628 BX Delft, the Netherlands All
    36   * rights reserved.
    37   */
    38  package nl.tudelft.simulation.dsol.gui.animation3D.mouse;
    39
    40  import java.awt.AWTEvent;
    41  import java.awt.event.MouseEvent;
    42  import java.util.Enumeration;
    43
    44  import javax.media.j3d.TransformGroup;
    45  import javax.media.j3d.WakeupCriterion;
    46  import javax.media.j3d.WakeupOnAWTEvent;
    47  import javax.vecmath.Matrix4d;
    48  import javax.vecmath.Vector3d;
    49
    50  import com.sun.j3d.utils.behaviors.mouse.MouseBehavior;
    51
    52  /***
    53   * RotateXYMouseBehavior is a Java3D behavior object that lets users control the
    54   * rotation of an object via a mouse.
    55   * <p>
    56   * To use this utility, first create a transform group that this rotate behavior
    57   * will operate on. Then, <blockquote>
    58   *
    59   * <pre>
    60   *
    61   *
    62   *
    63   *
    64   *
    65   *
    66   * RotateXYMouseBehavior behavior = new RotateXYMouseBehavior();
    67   * behavior.setTransformGroup(objTrans);
    68   * objTrans.addChild(behavior);
    69   * behavior.setSchedulingBounds(bounds);
    70   *
    71   *
    72   *
    73   *
    74   *
    75   *
    76   * </pre>
    77   *
    78   * </blockquote> The above code will add the rotate behavior to the transform
    79   * group. The user can rotate any object attached to the objTrans.
    80   */
    81
    82  public class RotateXYMouseBehavior extends MouseBehavior
    83  {
    84  	/*** y angle */
    85  	private double yAngle;
    86
    87  	/*** y factor */
    88  	private double yFactor;
    89
    90  	/*** x angle */
    91  	private double xAngle;
    92
    93  	/*** x factor */
    94  	private double xFactor;
    95
    96  	/*** a second transform group to rotate along the x-axis */
    97  	private TransformGroup transformGroupX = null;
    98
    99  	/***
    100 	 * Creates a rotate behavior given the transform group.
    101 	 *
    102 	 * @param transformGroup The transformGroup to operate on.
    103 	 */
    104 	public RotateXYMouseBehavior(final TransformGroup transformGroup)
    105 	{
    106 		super(transformGroup);
    107 	}
    108
    109 	/***
    110 	 * Creates a default mouse rotate behavior.
    111 	 */
    112 	public RotateXYMouseBehavior()
    113 	{
    114 		super(0);
    115 	}
    116
    117 	/***
    118 	 * Creates a rotate behavior. Note that this behavior still needs a
    119 	 * transform group to work on (use setTransformGroup(tg)) and the transform
    120 	 * group must add this behavior.
    121 	 *
    122 	 * @param flags interesting flags (wakeup conditions).
    123 	 */
    124 	public RotateXYMouseBehavior(final int flags)
    125 	{
    126 		super(flags);
    127 	}
    128
    129 	/***
    130 	 * @see javax.media.j3d.Behavior#initialize()
    131 	 */
    132 	public void initialize()
    133 	{
    134 		super.initialize();
    135 		this.yAngle = 0;
    136 		this.yFactor = .03;
    137 		this.xAngle = 0;
    138 		this.xFactor = .03;
    139 		if ((this.flags & INVERT_INPUT) == INVERT_INPUT)
    140 		{
    141 			this.invert = true;
    142 			this.yFactor *= -1;
    143 			this.xFactor *= -1;
    144 		}
    145 	}
    146
    147 	/***
    148 	 * Get y_factor
    149 	 *
    150 	 * @return y_factor
    151 	 */
    152 	public double getYFactor()
    153 	{
    154 		return this.yFactor;
    155 	}
    156
    157 	/***
    158 	 * Set factor
    159 	 *
    160 	 * @param factor the factor
    161 	 */
    162 	public void setFactor(final double factor)
    163 	{
    164 		this.yFactor = factor;
    165 		this.xFactor = factor;
    166 	}
    167
    168 	/***
    169 	 * Get x_factor
    170 	 *
    171 	 * @return x_factor
    172 	 */
    173 	public double getXFactor()
    174 	{
    175 		return this.xFactor;
    176 	}
    177
    178 	/***
    179 	 * @see javax.media.j3d.Behavior#processStimulus(java.util.Enumeration)
    180 	 */
    181 	public void processStimulus(final Enumeration criteria)
    182 	{
    183 		WakeupCriterion wakeup;
    184 		AWTEvent[] event;
    185 		int id;
    186 		int dx;
    187 		int dy;
    188
    189 		while (criteria.hasMoreElements())
    190 		{
    191 			wakeup = (WakeupCriterion) criteria.nextElement();
    192 			if (wakeup instanceof WakeupOnAWTEvent)
    193 			{
    194 				event = ((WakeupOnAWTEvent) wakeup).getAWTEvent();
    195 				for (int i = 0; i < event.length; i++)
    196 				{
    197 					processMouseEvent((MouseEvent) event[i]);
    198
    199 					if (((this.buttonPress) && ((this.flags & MANUAL_WAKEUP) == 0))
    200 							|| ((this.wakeUp) && ((this.flags & MANUAL_WAKEUP) != 0)))
    201 					{
    202
    203 						id = event[i].getID();
    204 						if ((id == MouseEvent.MOUSE_DRAGGED)
    205 								&& !((MouseEvent) event[i]).isMetaDown()
    206 								&& !((MouseEvent) event[i]).isAltDown())
    207 						{
    208
    209 							this.x = ((MouseEvent) event[i]).getX();
    210 							this.y = ((MouseEvent) event[i]).getY();
    211
    212 							dx = this.x - this.x_last;
    213 							dy = this.y - this.y_last;
    214
    215 							if (!this.reset)
    216 							{
    217 								this.yAngle = dx * this.yFactor;
    218 								this.xAngle = dy * this.xFactor;
    219
    220 								// ROTATE ALONG Y AXIS
    221 								this.transformY.rotY(this.yAngle);
    222 								this.transformX.rotX(0.0d);
    223
    224 								this.transformGroup
    225 										.getTransform(this.currXform);
    226
    227 								// Vector3d translation = new Vector3d();
    228 								// Matrix3f rotation = new Matrix3f();
    229 								Matrix4d mat = new Matrix4d();
    230
    231 								// Remember old matrix
    232 								this.currXform.get(mat);
    233
    234 								// Translate to origin
    235 								this.currXform.setTranslation(new Vector3d(0.0,
    236 										0.0, 0.0));
    237 								if (this.invert)
    238 								{
    239 									this.currXform.mul(this.currXform,
    240 											this.transformX);
    241 									this.currXform.mul(this.currXform,
    242 											this.transformY);
    243 								} else
    244 								{
    245 									this.currXform.mul(this.transformX,
    246 											this.currXform);
    247 									this.currXform.mul(this.transformY,
    248 											this.currXform);
    249 								}
    250
    251 								// Set old translation back
    252 								Vector3d translation = new Vector3d(mat.m03,
    253 										mat.m13, mat.m23);
    254 								this.currXform.setTranslation(translation);
    255
    256 								// Update xform
    257 								this.transformGroup
    258 										.setTransform(this.currXform);
    259
    260 								// ROTATE ALONG X AXIS
    261 								this.transformY.rotY(0.0d);
    262 								this.transformX.rotX(this.xAngle);
    263 								this.transformGroupX
    264 										.getTransform(this.currXform);
    265 								this.currXform.get(mat);
    266 								this.currXform.setTranslation(new Vector3d(0.0,
    267 										0.0, 0.0));
    268 								if (this.invert)
    269 								{
    270 									this.currXform.mul(this.currXform,
    271 											this.transformX);
    272 									this.currXform.mul(this.currXform,
    273 											this.transformY);
    274 								} else
    275 								{
    276 									this.currXform.mul(this.transformX,
    277 											this.currXform);
    278 									this.currXform.mul(this.transformY,
    279 											this.currXform);
    280 								}
    281 								translation = new Vector3d(mat.m03, mat.m13,
    282 										mat.m23);
    283 								this.currXform.setTranslation(translation);
    284 								this.transformGroupX
    285 										.setTransform(this.currXform);
    286
    287 							} else
    288 							{
    289 								this.reset = false;
    290 							}
    291
    292 							this.x_last = this.x;
    293 							this.y_last = this.y;
    294 						} else if (id == MouseEvent.MOUSE_PRESSED)
    295 						{
    296 							this.x_last = ((MouseEvent) event[i]).getX();
    297 							this.y_last = ((MouseEvent) event[i]).getY();
    298 						}
    299 					}
    300 				}
    301 			}
    302 		}
    303
    304 		wakeupOn(this.mouseCriterion);
    305
    306 	}
    307
    308 	/***
    309 	 * Get second transform group
    310 	 *
    311 	 * @return transform group
    312 	 */
    313 	public TransformGroup getTransformGroupX()
    314 	{
    315 		return this.transformGroupX;
    316 	}
    317
    318 	/***
    319 	 * Set second transform group
    320 	 *
    321 	 * @param group A transformgroup
    322 	 */
    323 	public void setTransformGroupX(final TransformGroup group)
    324 	{
    325 		this.transformGroupX = group;
    326 	}
    327
    328 }