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,
9    * this list of conditions and the following disclaimer.
10   *  - Redistribution in binary form must reproduce the above copyright notice,
11   * this list of conditions and the following disclaimer in the documentation
12   * and/or other materials provided 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) 2003 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   * RotateXYMouseBehavior behavior = new RotateXYMouseBehavior();
63   * behavior.setTransformGroup(objTrans);
64   * objTrans.addChild(behavior);
65   * behavior.setSchedulingBounds(bounds);
66   * 
67   * 
68   * </pre>
69   * 
70   * </blockquote> The above code will add the rotate behavior to the transform
71   * group. The user can rotate any object attached to the objTrans.
72   */
73  
74  public class RotateXYMouseBehavior extends MouseBehavior
75  {
76  	/*** y angle */
77  	private double yAngle;
78  
79  	/*** y factor */
80  	private double yFactor;
81  
82  	/*** x angle */
83  	private double xAngle;
84  
85  	/*** x factor */
86  	private double xFactor;
87  
88  	/*** a second transform group to rotate along the x-axis */
89  	private TransformGroup transformGroupX = null;
90  
91  	/***
92  	 * Creates a rotate behavior given the transform group.
93  	 * 
94  	 * @param transformGroup The transformGroup to operate on.
95  	 */
96  	public RotateXYMouseBehavior(final TransformGroup transformGroup)
97  	{
98  		super(transformGroup);
99  	}
100 
101 	/***
102 	 * Creates a default mouse rotate behavior.
103 	 */
104 	public RotateXYMouseBehavior()
105 	{
106 		super(0);
107 	}
108 
109 	/***
110 	 * Creates a rotate behavior. Note that this behavior still needs a
111 	 * transform group to work on (use setTransformGroup(tg)) and the transform
112 	 * group must add this behavior.
113 	 * 
114 	 * @param flags interesting flags (wakeup conditions).
115 	 */
116 	public RotateXYMouseBehavior(final int flags)
117 	{
118 		super(flags);
119 	}
120 
121 	/***
122 	 * @see javax.media.j3d.Behavior#initialize()
123 	 */
124 	public void initialize()
125 	{
126 		super.initialize();
127 		this.yAngle = 0;
128 		this.yFactor = .03;
129 		this.xAngle = 0;
130 		this.xFactor = .03;
131 		if ((this.flags & INVERT_INPUT) == INVERT_INPUT)
132 		{
133 			this.invert = true;
134 			this.yFactor *= -1;
135 			this.xFactor *= -1;
136 		}
137 	}
138 
139 	/***
140 	 * Get y_factor
141 	 * 
142 	 * @return y_factor
143 	 */
144 	public double getYFactor()
145 	{
146 		return this.yFactor;
147 	}
148 
149 	/***
150 	 * Set factor
151 	 * 
152 	 * @param factor the factor
153 	 */
154 	public void setFactor(final double factor)
155 	{
156 		this.yFactor = factor;
157 		this.xFactor = factor;
158 	}
159 
160 	/***
161 	 * Get x_factor
162 	 * 
163 	 * @return x_factor
164 	 */
165 	public double getXFactor()
166 	{
167 		return this.xFactor;
168 	}
169 
170 	/***
171 	 * @see javax.media.j3d.Behavior#processStimulus(java.util.Enumeration)
172 	 */
173 	public void processStimulus(final Enumeration criteria)
174 	{
175 		WakeupCriterion wakeup;
176 		AWTEvent[] event;
177 		int id;
178 		int dx;
179 		int dy;
180 
181 		while (criteria.hasMoreElements())
182 		{
183 			wakeup = (WakeupCriterion) criteria.nextElement();
184 			if (wakeup instanceof WakeupOnAWTEvent)
185 			{
186 				event = ((WakeupOnAWTEvent) wakeup).getAWTEvent();
187 				for (int i = 0; i < event.length; i++)
188 				{
189 					processMouseEvent((MouseEvent) event[i]);
190 
191 					if (((this.buttonPress) && ((this.flags & MANUAL_WAKEUP) == 0))
192 							|| ((this.wakeUp) && ((this.flags & MANUAL_WAKEUP) != 0)))
193 					{
194 
195 						id = event[i].getID();
196 						if ((id == MouseEvent.MOUSE_DRAGGED)
197 								&& !((MouseEvent) event[i]).isMetaDown()
198 								&& !((MouseEvent) event[i]).isAltDown())
199 						{
200 
201 							this.x = ((MouseEvent) event[i]).getX();
202 							this.y = ((MouseEvent) event[i]).getY();
203 
204 							dx = this.x - this.x_last;
205 							dy = this.y - this.y_last;
206 
207 							if (!this.reset)
208 							{
209 								this.yAngle = dx * this.yFactor;
210 								this.xAngle = dy * this.xFactor;
211 
212 								// ROTATE ALONG Y AXIS
213 								this.transformY.rotY(this.yAngle);
214 								this.transformX.rotX(0.0d);
215 
216 								this.transformGroup
217 										.getTransform(this.currXform);
218 
219 								//Vector3d translation = new Vector3d();
220 								//Matrix3f rotation = new Matrix3f();
221 								Matrix4d mat = new Matrix4d();
222 
223 								// Remember old matrix
224 								this.currXform.get(mat);
225 
226 								// Translate to origin
227 								this.currXform.setTranslation(new Vector3d(0.0,
228 										0.0, 0.0));
229 								if (this.invert)
230 								{
231 									this.currXform.mul(this.currXform,
232 											this.transformX);
233 									this.currXform.mul(this.currXform,
234 											this.transformY);
235 								} else
236 								{
237 									this.currXform.mul(this.transformX,
238 											this.currXform);
239 									this.currXform.mul(this.transformY,
240 											this.currXform);
241 								}
242 
243 								// Set old translation back
244 								Vector3d translation = new Vector3d(mat.m03,
245 										mat.m13, mat.m23);
246 								this.currXform.setTranslation(translation);
247 
248 								// Update xform
249 								this.transformGroup
250 										.setTransform(this.currXform);
251 
252 								// ROTATE ALONG X AXIS
253 								this.transformY.rotY(0.0d);
254 								this.transformX.rotX(this.xAngle);
255 								this.transformGroupX
256 										.getTransform(this.currXform);
257 								this.currXform.get(mat);
258 								this.currXform.setTranslation(new Vector3d(0.0,
259 										0.0, 0.0));
260 								if (this.invert)
261 								{
262 									this.currXform.mul(this.currXform,
263 											this.transformX);
264 									this.currXform.mul(this.currXform,
265 											this.transformY);
266 								} else
267 								{
268 									this.currXform.mul(this.transformX,
269 											this.currXform);
270 									this.currXform.mul(this.transformY,
271 											this.currXform);
272 								}
273 								translation = new Vector3d(mat.m03, mat.m13,
274 										mat.m23);
275 								this.currXform.setTranslation(translation);
276 								this.transformGroupX
277 										.setTransform(this.currXform);
278 
279 							} else
280 							{
281 								this.reset = false;
282 							}
283 
284 							this.x_last = this.x;
285 							this.y_last = this.y;
286 						} else if (id == MouseEvent.MOUSE_PRESSED)
287 						{
288 							this.x_last = ((MouseEvent) event[i]).getX();
289 							this.y_last = ((MouseEvent) event[i]).getY();
290 						}
291 					}
292 				}
293 			}
294 		}
295 
296 		wakeupOn(this.mouseCriterion);
297 
298 	}
299 
300 	/***
301 	 * Get second transform group
302 	 * 
303 	 * @return transform group
304 	 */
305 	public TransformGroup getTransformGroupX()
306 	{
307 		return this.transformGroupX;
308 	}
309 
310 	/***
311 	 * Set second transform group
312 	 * 
313 	 * @param group A transformgroup
314 	 */
315 	public void setTransformGroupX(final TransformGroup group)
316 	{
317 		this.transformGroupX = group;
318 	}
319 
320 }