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 }