1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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
221 this.transformY.rotY(this.yAngle);
222 this.transformX.rotX(0.0d);
223
224 this.transformGroup
225 .getTransform(this.currXform);
226
227
228
229 Matrix4d mat = new Matrix4d();
230
231
232 this.currXform.get(mat);
233
234
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
252 Vector3d translation = new Vector3d(mat.m03,
253 mat.m13, mat.m23);
254 this.currXform.setTranslation(translation);
255
256
257 this.transformGroup
258 .setTransform(this.currXform);
259
260
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 }