]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/action/RotateAction.java
3D framework (Simca 2012)
[simantics/3d.git] / org.simantics.g3d.vtk / src / org / simantics / g3d / vtk / action / RotateAction.java
1 package org.simantics.g3d.vtk.action;\r
2 \r
3 import java.awt.Cursor;\r
4 import java.awt.event.KeyEvent;\r
5 import java.awt.event.MouseEvent;\r
6 \r
7 import javax.vecmath.AxisAngle4d;\r
8 import javax.vecmath.Point3d;\r
9 import javax.vecmath.Quat4d;\r
10 import javax.vecmath.Vector3d;\r
11 \r
12 import org.simantics.g3d.math.EulerTools;\r
13 import org.simantics.g3d.math.MathTools;\r
14 import org.simantics.g3d.math.Ray;\r
15 import org.simantics.g3d.math.EulerTools.Order;\r
16 import org.simantics.g3d.preferences.PreferenceConstants;\r
17 import org.simantics.g3d.scenegraph.IG3DNode;\r
18 import org.simantics.g3d.scenegraph.structural.IStructuralNode;\r
19 import org.simantics.g3d.vtk.Activator;\r
20 import org.simantics.g3d.vtk.common.InteractiveVtkPanel;\r
21 import org.simantics.g3d.vtk.common.VTKNodeMap;\r
22 import org.simantics.g3d.vtk.gizmo.RotateAxisGizmo;\r
23 import org.simantics.g3d.vtk.utils.vtkUtil;\r
24 import org.simantics.utils.threads.AWTThread;\r
25 import org.simantics.utils.threads.ThreadUtils;\r
26 \r
27 import vtk.vtkProp;\r
28 /**\r
29  * FIXME: complete rewrite.\r
30  * \r
31  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
32  *\r
33  */\r
34 public class RotateAction extends vtkAction{\r
35         \r
36         public static final int X = 0;\r
37     public static final int Y = 1;\r
38     public static final int Z = 2;\r
39     public static final int P = 3;\r
40 \r
41         private VTKNodeMap nodeMap;\r
42         //private TranslateGizmo  gizmo = new TranslateGizmo();\r
43         private RotateAxisGizmo gizmo = new RotateAxisGizmo();\r
44         private IG3DNode node;\r
45         \r
46         \r
47         \r
48         private Cursor activeCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);\r
49         private Cursor dragCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);\r
50         \r
51         \r
52         int stepMethod = 1;\r
53         Order order = Order.YXZ;\r
54         \r
55     private int steps; \r
56     private double angles[];\r
57         \r
58         int index = P;\r
59         boolean valid = false;\r
60         private boolean worldCoord = true;\r
61         //private AxisAngle4d aa = null;\r
62         private Quat4d parentWorldOrientation = null;\r
63         \r
64         //AxisAngle4d rotation = new AxisAngle4d();\r
65         Quat4d worldOrientation = new Quat4d();\r
66         \r
67         public void setNode(IG3DNode node) {\r
68                 this.node = node;\r
69                 if ((node instanceof IStructuralNode) && ((IStructuralNode)node).isPartOfInstantiatedModel() && !((IStructuralNode)node).isInstantiatedModelRoot()) {\r
70                         setEnabled(false);\r
71                 } else {\r
72                         setEnabled(true);\r
73                 }\r
74                 \r
75                 String set = org.simantics.g3d.Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.ORIENTATION_PRESENTATION);\r
76                 if (set.equals("aa")) {\r
77                         stepMethod = 0;\r
78                 } else if (set.equals("euler")){\r
79                         stepMethod = 1;\r
80                         String eulerOrder = org.simantics.g3d.Activator.getDefault().getPreferenceStore().getString(PreferenceConstants.EULER_ANGLE_ORDER);\r
81                         try {\r
82                                 order = Order.valueOf(eulerOrder);\r
83                         } catch (Exception e) {\r
84                                 order = Order.YXZ;\r
85                         }\r
86                 } else {\r
87                         stepMethod = 2;\r
88                 }\r
89         }\r
90         \r
91         public IG3DNode getNode() {\r
92                 return node;\r
93         }\r
94         \r
95         public RotateAction(InteractiveVtkPanel panel, VTKNodeMap nodeMap) {\r
96                 super(panel);\r
97                 setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_rotate_clockwise.png"));\r
98                 setText("Rotate");\r
99                 this.nodeMap = nodeMap;\r
100                 \r
101                 \r
102                 steps = 36;\r
103         angles = new double[steps+1];\r
104         for (int i = 0; i < angles.length; i++) {\r
105             angles[i] = - Math.PI + (Math.PI * i * 2.0 / steps);\r
106         }\r
107         }\r
108         \r
109         public void attach() {\r
110                 if (node == null)\r
111                         return;\r
112                 \r
113                 super.attach();\r
114                 ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {\r
115                         public void run() {\r
116                                 attachUI();\r
117                                 update();\r
118                         }\r
119                 });\r
120                 \r
121                 \r
122                 \r
123         }\r
124         \r
125         public void deattach() {\r
126                 \r
127                 node = null;\r
128                 nodeMap.commit();\r
129                 deattachUI();\r
130                 super.deattach();\r
131                 panel.repaint();\r
132         }\r
133         \r
134         private void attachUI() {\r
135                 panel.setCursor(activeCursor);\r
136                 gizmo.attach(panel.GetRenderer());\r
137         }\r
138         \r
139         private void deattachUI() {\r
140                 panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));\r
141                 gizmo.deattach();\r
142         }\r
143         \r
144         @Override\r
145         public void keyPressed(KeyEvent e) {\r
146                 if (e.getKeyCode() == KeyEvent.VK_ESCAPE)\r
147                         panel.useDefaultAction();\r
148                 if (valid)\r
149                         return;\r
150                 if (e.getKeyCode() == KeyEvent.VK_X) {\r
151                         if (index != X)\r
152                                 index = X;\r
153                         else\r
154                                 index = P;\r
155                 }\r
156                 if (e.getKeyCode() == KeyEvent.VK_Y) {\r
157                         if (index != Y)\r
158                                 index = Y;\r
159                         else\r
160                                 index = P;\r
161                 }\r
162                 if (e.getKeyCode() == KeyEvent.VK_Z) {\r
163                         if (index != Z)\r
164                                 index = Z;\r
165                         else\r
166                                 index = P;\r
167                 }\r
168                 if (e.getKeyCode() == KeyEvent.VK_G) {\r
169                         worldCoord = !worldCoord;\r
170                 }\r
171                 gizmo.setType(index);\r
172                 panel.repaint();\r
173         }\r
174         \r
175         @Override\r
176         public void keyReleased(KeyEvent e) {\r
177                 \r
178         }\r
179         \r
180         \r
181         \r
182         @Override\r
183         public void mouseClicked(MouseEvent e) {\r
184                 if (e.getClickCount() > 1) {\r
185                         if (isOverNode(e)) {\r
186                                 return;\r
187                         }\r
188                         panel.useDefaultAction();\r
189                         //if(!gizmo.isPartOf(actor))\r
190                         //      panel.useDefaultAction();\r
191                         \r
192                 }\r
193         }\r
194         \r
195         @Override\r
196         public void mouseEntered(MouseEvent e) {\r
197                 \r
198         }\r
199         \r
200         @Override\r
201         public void mouseExited(MouseEvent e) {\r
202                 \r
203         }\r
204         \r
205         \r
206 \r
207         \r
208         \r
209         public void setWorldCoord(boolean b) {\r
210                 if (worldCoord == b)\r
211                         return;\r
212                 worldCoord = b;\r
213                 update();\r
214                                         \r
215         }\r
216         \r
217         \r
218         private void update() {\r
219                 Vector3d nodePos = node.getWorldPosition();\r
220                 System.out.println(nodePos);\r
221                 gizmo.setPosition(nodePos);\r
222                 if (worldCoord) {\r
223                         gizmo.setRotation(new AxisAngle4d());\r
224                         parentWorldOrientation = null;\r
225                 } else {\r
226                         AxisAngle4d aa = new AxisAngle4d();\r
227                         parentWorldOrientation = ((IG3DNode)node.getParent()).getWorldOrientation();\r
228                         aa.set(parentWorldOrientation);\r
229                         gizmo.setRotation(aa);\r
230                 }\r
231 \r
232                 Point3d camPos = new Point3d(panel.GetRenderer().GetActiveCamera().GetPosition());\r
233                 Vector3d p = new Vector3d(nodePos);\r
234                 p.sub(camPos);\r
235                 \r
236                 if (parentWorldOrientation != null) {\r
237                         Quat4d qi = new Quat4d(parentWorldOrientation);\r
238                         qi.inverse();\r
239                         MathTools.rotate(parentWorldOrientation, p, p);\r
240                 }\r
241                 if (panel.GetRenderer().GetActiveCamera().GetParallelProjection() == 0) {\r
242                         double distance = p.length();\r
243                         p.negate();\r
244             double fov = panel.GetRenderer().GetActiveCamera().GetViewAngle();\r
245             float s = (float) (Math.sin(fov) * distance * 0.1); \r
246 \r
247             Vector3d scale = new Vector3d(1., 1., 1.);\r
248             \r
249 //            if (p.x > 0.f)\r
250 //                scale.x = -1.;\r
251 //            if (p.y > 0.f)\r
252 //                scale.y = -1.;\r
253 //            if (p.z > 0.f)\r
254 //                scale.z = -1.;\r
255             scale.scale(s);\r
256             gizmo.setScale(scale);\r
257                         \r
258                 } else {\r
259                         Vector3d scale = new Vector3d(1.f, 1.f, 1.f);\r
260             double s = panel.GetRenderer().GetActiveCamera().GetParallelScale() / 5.;\r
261 //            if (p.x > 0.f)\r
262 //                scale.x = -1.;\r
263 //            if (p.y > 0.f)\r
264 //                scale.y = -1.;\r
265 //            if (p.z > 0.f)\r
266 //                scale.z = -1.;\r
267             scale.scale(s);\r
268             gizmo.setScale(scale);\r
269                 }\r
270                 \r
271                 panel.Render();\r
272         }\r
273         \r
274         private boolean isOverNode(MouseEvent e) {\r
275                 vtkProp picked[] = panel.pick(e.getX(), e.getY());\r
276                 if (picked !=null) {\r
277                         for (int i = 0; i < picked.length; i++) {\r
278                                 if (node.equals(nodeMap.getNode(picked[i])))\r
279                                         return true;\r
280                         }\r
281                 }\r
282                 return false;\r
283         }\r
284         \r
285 \r
286         \r
287         @Override\r
288         public void mousePressed(MouseEvent e) {\r
289                 if (e.getButton() == MouseEvent.BUTTON1) {\r
290         \r
291         \r
292                         if (isOverNode(e)) {\r
293                                 valid = true;\r
294                                 if ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0) {\r
295                                         useStep = true;\r
296                     } else {\r
297                         useStep = false;\r
298                     }\r
299                                 worldOrientation = node.getWorldOrientation();\r
300                                 doChanges(true, e.getX(), e.getY());\r
301                                 \r
302                                 panel.setCursor(dragCursor);\r
303                         } else {\r
304                                 valid = false;\r
305                                 panel.getDefaultAction().mousePressed(e);\r
306                                 panel.setCursor(activeCursor);\r
307                         }\r
308                 } else {\r
309                         panel.getDefaultAction().mousePressed(e);\r
310                 }\r
311         }\r
312         \r
313         \r
314         \r
315         @Override\r
316         public void mouseReleased(MouseEvent e) {\r
317                 if (e.getButton() == MouseEvent.BUTTON1) {\r
318                         valid = false;\r
319                         worldOrientation = null;\r
320                         panel.setCursor(activeCursor);\r
321                 } else {\r
322                         panel.getDefaultAction().mouseReleased(e);\r
323                 }\r
324         }\r
325         \r
326         @Override\r
327         public void mouseDragged(MouseEvent e) {\r
328                 if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { \r
329                         if ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0) {\r
330                                 useStep = true;\r
331             } else {\r
332                 useStep = false;\r
333             }\r
334                         doChanges(false, e.getX(), e.getY());\r
335                         \r
336                         //nodeMap.modified(node);\r
337                         update();\r
338                 } else {\r
339                         panel.getDefaultAction().mouseDragged(e);\r
340                         update();\r
341                 }\r
342         }\r
343         \r
344          Vector3d axis = null;\r
345         \r
346         @Override\r
347         public void keyTyped(KeyEvent e) {\r
348                  if (e.getKeyCode() == KeyEvent.VK_LEFT) {\r
349                 inputType = InputType.KEY;\r
350                 axis = new Vector3d(0.0,1.0,0.0);\r
351              } else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {\r
352                         inputType = InputType.KEY;\r
353                         axis = new Vector3d(0.0,-1.0,0.0);\r
354              } else if (e.getKeyCode() ==KeyEvent.VK_UP) {\r
355                         inputType = InputType.KEY;\r
356                         axis = new Vector3d(1.0,0.0,0.0);\r
357              } else if (e.getKeyCode() == KeyEvent.VK_DOWN) {\r
358                         inputType = InputType.KEY;\r
359                         axis = new Vector3d(-1.0,0.0,0.0);\r
360              } \r
361         }\r
362         \r
363     public void doChanges(boolean pressed, int x, int y) {\r
364         Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(),x, y);\r
365         Vector3d p = node.getWorldPosition();\r
366         \r
367         if (pressed) {\r
368             Vector3d axis = getRotationAxis();\r
369             if (axis != null) {\r
370                 if (!worldCoord) {\r
371                         MathTools.rotate(parentWorldOrientation, axis, axis);\r
372                 }\r
373 \r
374                \r
375                 double s[] = new double[2];\r
376                 Vector3d i2 = new Vector3d();\r
377                \r
378                 boolean intersect = MathTools.intersectStraightPlane(ray.pos, ray.dir, p, axis, i2, s);\r
379                 double dot = Math.abs(ray.dir.dot(axis));\r
380                 if (intersect &&  dot > 0.4)\r
381                         inputType = InputType.INTERSECT;\r
382                 else\r
383                         inputType = InputType.NONINTERSECT;\r
384                         \r
385                 \r
386                 if (inputType == InputType.INTERSECT) {\r
387                     // picking ray and plane defined by gizmo's center point and\r
388                     // rotation axis can intersect\r
389                     // vector from center point to intersection point\r
390                     i2.sub(p);\r
391                     // creating vectors i and j that are lying on the plane and\r
392                     // are perpendicular\r
393                     // vectors are used to calculate polar coordinate for\r
394                     // intersection point\r
395                     j.set(i2);\r
396                     i.cross(j, axis);\r
397                     System.out.println("I,J " + i + " " + j);\r
398                     double angleI = i2.angle(i);\r
399                     double angleJ = i2.angle(j);\r
400                     prevAngle = Math.atan2(Math.cos(angleJ), Math.cos(angleI));\r
401                 } else {\r
402                     // picking ray and plane defined by gizmo's center point and\r
403                     // rotation axis are parallel,\r
404                     // so we'll use cross product of rotation axis and picking\r
405                     // ray to detect amount of rotation\r
406                     i.cross(ray.dir, axis);\r
407                     MathTools.intersectStraightStraight(ray.pos, ray.dir, p, i, new Vector3d(), new Vector3d(), s);\r
408                     prevS = s[1];\r
409                 }\r
410             }\r
411            \r
412             \r
413         }\r
414 \r
415         if (inputType != InputType.KEY)\r
416                 axis = getRotationAxis();\r
417         if (axis == null) {\r
418             return;   \r
419         }\r
420         Vector3d taxis = null;\r
421         if (!worldCoord) {\r
422                 taxis = new Vector3d(axis);\r
423                 MathTools.rotate(parentWorldOrientation, axis, axis);\r
424         }\r
425         System.out.println(inputType);\r
426         if (inputType == InputType.INTERSECT) {\r
427 \r
428             double s[] = new double[2];\r
429             Vector3d i2 = new Vector3d();\r
430             MathTools.intersectStraightPlane(ray.pos, ray.dir, p, axis, i2, s);\r
431             i2.sub(p);\r
432             double angleI = i2.angle(i);\r
433             double angleJ = i2.angle(j);\r
434             double angle = Math.atan2(Math.cos(angleJ), Math.cos(angleI));\r
435             System.out.println("Angle " + angle + " i " + angleI + " j " + angleJ + " prev " + prevAngle);\r
436             if(!worldCoord)\r
437                 axis = taxis;\r
438             if (useStep) {\r
439 \r
440                 //setOrientation(MathTools.getQuat(rotation));\r
441                 AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);\r
442                 Quat4d qrot = new Quat4d();\r
443                 MathTools.getQuat(rot, qrot);\r
444                 //prevAngle = angle;\r
445                 qrot.mulInverse(worldOrientation);\r
446                 \r
447           \r
448                 if (stepMethod == 0) {\r
449                         rot.set(qrot);\r
450                         rot.angle = roundAngle(rot.angle);\r
451                         //qrot.set(rot);\r
452                         MathTools.getQuat(rot,qrot);\r
453                         setOrientation(qrot);\r
454                 } else if (stepMethod == 1){\r
455                           \r
456                         //Vector3d euler = MathTools.getEuler(qrot);\r
457                         Vector3d euler = EulerTools.getEulerFromQuat(order, qrot);\r
458                         euler.x = roundAngle(euler.x);\r
459                         euler.y = roundAngle(euler.y);\r
460                         euler.z = roundAngle(euler.z);\r
461                         //Quat4d q = MathTools.getQuat(euler);\r
462                         Quat4d q = EulerTools.getQuatFromEuler(order, euler);\r
463                         setOrientation(q);\r
464                         System.out.println(" (" + MathTools.radToDeg(euler.x) + " " + MathTools.radToDeg(euler.y) + " " + MathTools.radToDeg(euler.z) +  ") " + qrot + " "+ q);\r
465                 } else {\r
466                         setOrientation(qrot);\r
467                 }\r
468                 \r
469             } else {\r
470                 if (worldCoord) {\r
471                         //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,angle-prevAngle));\r
472                         AxisAngle4d aa = MathTools.getAxisAngle(node.getWorldOrientation());\r
473                         AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);\r
474                         MathTools.multiplyOrientation(aa, rot);\r
475                         setWorldOrientation(MathTools.getQuat(rot));\r
476                 } else {\r
477                         AxisAngle4d aa = MathTools.getAxisAngle(node.getOrientation());\r
478                         AxisAngle4d rot = new AxisAngle4d(axis,angle-prevAngle);\r
479                         MathTools.multiplyOrientation(aa, rot);\r
480                         setOrientation(MathTools.getQuat(rot));\r
481                         //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,angle-prevAngle));\r
482                 }\r
483                 prevAngle = angle;\r
484             }\r
485             \r
486         } else if (inputType == InputType.NONINTERSECT){\r
487 \r
488             double s[] = new double[2];\r
489             MathTools.intersectStraightStraight(ray.pos, ray.dir, p, i, new Vector3d(), new Vector3d(), s);\r
490             if(!worldCoord)\r
491                 axis = taxis;\r
492             if (useStep) {\r
493                 //setOrientation(MathTools.getQuat(rotation));\r
494                 AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);\r
495                 \r
496                 Quat4d qrot = new Quat4d();\r
497                 //qrot.set(rot);\r
498                 MathTools.getQuat(rot, qrot);\r
499                 //prevAngle = angle;\r
500                 qrot.mulInverse(worldOrientation);\r
501                 \r
502           \r
503                 if (stepMethod == 0) {\r
504                         rot.set(qrot);\r
505                         rot.angle = roundAngle(rot.angle);\r
506                         //qrot.set(rot);\r
507                         MathTools.getQuat(rot,qrot);\r
508                         setOrientation(qrot);\r
509                 } else if (stepMethod == 1){\r
510                           \r
511                         //Vector3d euler = MathTools.getEuler(qrot);\r
512                         Vector3d euler = EulerTools.getEulerFromQuat(order, qrot);\r
513                         euler.x = roundAngle(euler.x);\r
514                         euler.y = roundAngle(euler.y);\r
515                         euler.z = roundAngle(euler.z);\r
516                         //Quat4d q = MathTools.getQuat(euler);\r
517                         Quat4d q = EulerTools.getQuatFromEuler(order, euler);\r
518                         setOrientation(q);\r
519                         System.out.println(" (" + MathTools.radToDeg(euler.x) + " " + MathTools.radToDeg(euler.y) + " " + MathTools.radToDeg(euler.z) +  ") " + qrot + " "+ q);\r
520                 } else {\r
521                         setOrientation(qrot);\r
522                 }\r
523                 prevS = s[1];\r
524                 \r
525 //                    G3DTools.setOrientation(mo.getG3DNode(graph).getLocalOrientation(), rotations.get(mo));\r
526 //                    G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,s[1] - prevS));\r
527 //                    AxisAngle4d aa = G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation());\r
528 //                    rotations.put(mo, aa);\r
529 //                    Vector3d euler = MathTools.getEuler(aa);\r
530 //                    euler.x = roundAngle(euler.x);\r
531 //                    euler.y = roundAngle(euler.y);\r
532 //                    euler.z = roundAngle(euler.z);\r
533 //                    aa = MathTools.getFromEuler2(euler);\r
534 //                    prevS = s[1];\r
535 //                    G3DTools.setOrientation(mo.getG3DNode(graph).getLocalOrientation(), aa);\r
536 //                    Vector3d e = MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()));\r
537 //                    e.scale(180.0/Math.PI);\r
538 //                    text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + e + " ";\r
539                 \r
540                 \r
541             } else {\r
542                         if (worldCoord) {\r
543                                 AxisAngle4d aa =  MathTools.getAxisAngle(node.getWorldOrientation());\r
544                         AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);\r
545                         MathTools.multiplyOrientation(aa, rot);\r
546                         setWorldOrientation(MathTools.getQuat(rot));\r
547                                 //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,s[1] - prevS));\r
548                         } else {\r
549                                 AxisAngle4d aa =  MathTools.getAxisAngle(node.getOrientation());\r
550                         AxisAngle4d rot = new AxisAngle4d(axis,s[1] - prevS);\r
551                         MathTools.multiplyOrientation(aa, rot);\r
552                         setOrientation(MathTools.getQuat(rot));\r
553                                 //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,s[1] - prevS));\r
554                         }\r
555                         //text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation())) + " ";\r
556                 prevS = s[1];\r
557                 \r
558             }\r
559            \r
560         } else {\r
561                 if (worldCoord) {\r
562                         AxisAngle4d aa = MathTools.getAxisAngle(node.getWorldOrientation());\r
563                 AxisAngle4d rot = new AxisAngle4d(axis,Math.PI * 0.5);\r
564                 MathTools.multiplyOrientation(aa, rot);\r
565                 setWorldOrientation(MathTools.getQuat(rot));\r
566                         //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getWorldOrientation(), new AxisAngle4d(axis,Math.PI * 0.5));\r
567                 } else {\r
568                         AxisAngle4d aa = MathTools.getAxisAngle(node.getOrientation());\r
569                 AxisAngle4d rot = new AxisAngle4d(axis,Math.PI * 0.5);\r
570                 MathTools.multiplyOrientation(aa, rot);\r
571                 setOrientation(MathTools.getQuat(rot));\r
572                         //G3DTools.multiplyOrientation(mo.getG3DNode(graph).getLocalOrientation(), new AxisAngle4d(axis,Math.PI * 0.5));\r
573                 }\r
574              //   text += G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation()) + " " + MathTools.getEuler(G3DTools.getOrientation(mo.getG3DNode(graph).getLocalOrientation())) + " ";\r
575             \r
576         }\r
577         //setInfoText(text);\r
578  \r
579     }\r
580     \r
581     protected void setOrientation(Quat4d q) {\r
582         node.setOrientation(q);\r
583     }\r
584     \r
585     protected void setWorldOrientation(Quat4d q) {\r
586         node.setWorldOrientation(q);\r
587     }\r
588         \r
589         @Override\r
590         public void mouseMoved(MouseEvent e) {\r
591                 panel.getDefaultAction().mouseMoved(e);\r
592         }\r
593         \r
594         private Vector3d getRotationAxis() {\r
595                 switch (index) {\r
596                 case X:\r
597                         return new Vector3d(1.0, 0.0, 0.0);\r
598                 case Y:\r
599                         return new Vector3d(0.0, 1.0, 0.0);\r
600                 case Z:\r
601                         return new Vector3d(0.0, 0.0, 1.0);\r
602                 case P:\r
603                         Vector3d axis = new Vector3d(panel.GetRenderer().GetActiveCamera()\r
604                                         .GetDirectionOfProjection());\r
605                         axis.normalize();\r
606                         return axis;\r
607                 default:\r
608                         return null;\r
609                 }\r
610         }\r
611         \r
612          private double prevS = 0.0;\r
613             \r
614     private Vector3d i = new Vector3d();\r
615     private Vector3d j = new Vector3d();\r
616     private double prevAngle = 0;\r
617 \r
618     enum InputType{INTERSECT,NONINTERSECT,KEY,NONE};\r
619     InputType inputType;\r
620     private boolean useStep = false;\r
621     \r
622     \r
623     \r
624     private double roundAngle(double angle) {\r
625         while (angle < - Math.PI)\r
626             angle += Math.PI*2.0;\r
627         while (angle > Math.PI)\r
628             angle -= Math.PI*2.0;\r
629         \r
630         \r
631         int index = 0;\r
632         while (angle > angles[index])\r
633             index++;\r
634         if (index == 0) {\r
635             angle = angles[0];\r
636         } else {\r
637             double d = angle - angles[index - 1];\r
638             double d2 = angles[index] - angle;\r
639             if (d < d2)\r
640                 angle = angles[index - 1];\r
641             else\r
642                 angle = angles[index];\r
643         }\r
644         return angle;\r
645     }\r
646         \r
647 }\r