]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d/src/org/simantics/proconf/g3d/actions/TranslateAction.java
git-svn-id: https://www.simantics.org/svn/simantics/3d/trunk@22280 ac1ea38d-2e2b...
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / proconf / g3d / actions / TranslateAction.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007- VTT Technical Research Centre of Finland.\r
3  * All rights reserved. This program and the accompanying materials\r
4  * are made available under the terms of the Eclipse Public License v1.0\r
5  * which accompanies this distribution, and is available at\r
6  * http://www.eclipse.org/legal/epl-v10.html\r
7  *\r
8  * Contributors:\r
9  *     VTT Technical Research Centre of Finland - initial API and implementation\r
10  *******************************************************************************/\r
11 package org.simantics.proconf.g3d.actions;\r
12 \r
13 import java.awt.event.MouseEvent;\r
14 import java.math.BigDecimal;\r
15 import java.util.Collection;\r
16 import java.util.List;\r
17 \r
18 import javax.vecmath.AxisAngle4d;\r
19 import javax.vecmath.AxisAngle4f;\r
20 import javax.vecmath.Point3d;\r
21 import javax.vecmath.Quat4d;\r
22 import javax.vecmath.Vector3d;\r
23 \r
24 import org.eclipse.jface.action.Action;\r
25 import org.eclipse.jface.action.IToolBarManager;\r
26 import org.simantics.db.Graph;\r
27 import org.simantics.db.GraphRequest;\r
28 import org.simantics.db.GraphRequestAdapter;\r
29 import org.simantics.db.GraphRequestStatus;\r
30 import org.simantics.db.Resource;\r
31 import org.simantics.layer0.utils.IEntity;\r
32 import org.simantics.layer0.utils.EntityFactory;\r
33 import org.simantics.proconf.g3d.Activator;\r
34 import org.simantics.proconf.g3d.Resources;\r
35 import org.simantics.proconf.g3d.base.G3DTools;\r
36 import org.simantics.proconf.g3d.base.MathTools;\r
37 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
38 import org.simantics.proconf.g3d.gizmo.TransformGizmo;\r
39 import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;\r
40 import org.simantics.proconf.g3d.stubs.Orientation;\r
41 import org.simantics.proconf.g3d.stubs.Position;\r
42 \r
43 \r
44 public class TranslateAction extends ConstrainedTransformAction {\r
45         \r
46         \r
47     private TransformGizmo gizmo;\r
48     \r
49     private double istep = 10.0;\r
50     private int decimals = 2;\r
51     \r
52     \r
53     private Action csAction;\r
54     List<IGraphicsNode> mos = null;\r
55     \r
56     private boolean worldCoord = true;\r
57     \r
58     \r
59     private AxisAngle4d aa;\r
60     private Quat4d q;\r
61     \r
62     public TranslateAction(ThreeDimensionalEditorBase parent) {\r
63         super(parent);\r
64         \r
65         csAction = new Action("World",Action.AS_CHECK_BOX) {\r
66                 public void run() {\r
67                         GraphRequest r = new GraphRequestAdapter() {\r
68                                 @Override\r
69                                 public GraphRequestStatus perform(Graph g) throws Exception {\r
70                                         setWorldCoord(g,!isChecked());\r
71                                         return GraphRequestStatus.transactionComplete();\r
72                                 }\r
73                         };\r
74                         TranslateAction.this.parent.getSession().asyncRead(r);\r
75                         \r
76                 }\r
77         };\r
78         gizmo = new TransformGizmo(component.getDisplaySystem().getRenderer());\r
79     }\r
80     \r
81     public void init() {\r
82         this.setText("Translate");\r
83         this.setToolTipText("Translate the object");\r
84         this.setImageDescriptor(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/translate.png"));\r
85     }\r
86     \r
87     @Override\r
88     public boolean usable(Graph graph, List<Resource> resources) {\r
89         if (resources.size() == 0)\r
90             return false;\r
91         for (Resource r : resources) {\r
92                 IEntity t = EntityFactory.create(graph,r);\r
93             if (t.isInstanceOf(Resources.g3dResource.G3DNode)) {\r
94                 Collection<IEntity> p = t.getRelatedObjects(Resources.g3dResource.HasLocalPosition);\r
95                 if (p == null || p.size() != 1)\r
96                     return false;\r
97             }\r
98                \r
99         }\r
100         return true;\r
101         \r
102     }\r
103     \r
104     @Override\r
105     public void deactivate() {\r
106         super.deactivate();\r
107         parent.setGizmo(null);\r
108         mos = null;\r
109     }\r
110     \r
111     private void setWorldCoord(Graph graph,boolean b) {\r
112         if (worldCoord == b)\r
113                 return;\r
114         worldCoord = b;\r
115         updateWorldCoord(graph);\r
116     }\r
117     \r
118     private void updateWorldCoord(Graph graph) {\r
119         if (worldCoord) {\r
120                         csAction.setText("World");\r
121                         gizmo.setRotation(new AxisAngle4f());\r
122                         aa = null;\r
123                         q = null;\r
124         } else {\r
125                         csAction.setText("Local");\r
126                         Orientation o = mos.get(0).getParent().getG3DNode(graph).getWorldOrientation();\r
127                         if (o == null) {\r
128                                 aa = new AxisAngle4d();\r
129                         } else {\r
130                                 aa = G3DTools.getOrientation(o);\r
131                         }\r
132                                 \r
133                         gizmo.setRotation(new AxisAngle4f(aa));\r
134                         q = new Quat4d();\r
135                         q.set(aa);\r
136         }\r
137 //      if (manager != null)\r
138 //              parent.getRenderingComposite().getDisplay().asyncExec(new Runnable() {\r
139 //                      public void run() {\r
140 //                              manager.update(true);\r
141 //                      }\r
142 //              });\r
143                 \r
144         this.parent.setViewChanged(true);\r
145     }\r
146     \r
147     public void fillToolBar(IToolBarManager manager) {\r
148         super.fillToolBar(manager);\r
149         csAction.setChecked(!worldCoord);\r
150         manager.add(csAction);\r
151     }\r
152 \r
153     @Override\r
154     public void activate() {\r
155         GraphRequest r = new GraphRequestAdapter() {\r
156                 public GraphRequestStatus perform(Graph g) throws Exception {\r
157                         parent.setGizmo(gizmo);\r
158 \r
159                 updateGizmo(g);\r
160 \r
161                 component.getNoShadowRoot().attachChild(gizmo.getNode());\r
162                 \r
163                 String text = "";\r
164                 mos = parent.getSelectionAdapter().getSelectedObjects();\r
165                 for (IGraphicsNode mo : mos) {\r
166                         if (worldCoord)\r
167                                 text += G3DTools.getVector(mo.getG3DNode(g).getWorldPosition()) + " ";//mo.getWorldPosition() + " ";\r
168                         else\r
169                                 text += G3DTools.getVector(mo.getG3DNode(g).getLocalPosition()) + " ";\r
170                 }\r
171                 final String fText = text;\r
172                 parent.getRenderingComposite().getDisplay().asyncExec(new Runnable() {\r
173                         public void run() {\r
174                                 setInfoText(fText);    \r
175                         }\r
176                 });\r
177                 \r
178                 Resource r[] = new Resource[mos.size()];\r
179                 for (int i = 0; i < mos.size(); i++) {\r
180                     r[i] = mos.get(i).getResource();\r
181                 }\r
182                 \r
183                 TranslateActionConstraints.addConstraints(r, detector);   \r
184                 updateWorldCoord(g);\r
185                 return GraphRequestStatus.transactionComplete();\r
186                 };\r
187          \r
188         };\r
189         parent.getSession().asyncRead(r);\r
190         \r
191     }\r
192     \r
193     Vector3d getTranslate(Graph graph) {\r
194         return getTranslate(graph,new Vector3d());\r
195     }\r
196     \r
197     Vector3d getTranslate(Graph graph,Vector3d offset) {\r
198         Vector3d translate = new Vector3d();\r
199         Vector3d o = new Vector3d();\r
200         Vector3d d = new Vector3d();\r
201         parent.createPickRay(o, d);\r
202         Vector3d p = G3DTools.getVector(mos.get(0).getG3DNode(graph).getWorldPosition());//gizmo.getPosition();\r
203         Vector3d dir = null;\r
204         switch (gizmo.getSelected()) {\r
205         case TransformGizmo.XYZ :\r
206             Vector3d normal = camera.getUnNormalizedHeading();\r
207             if(!worldCoord)\r
208                 MathTools.rotate(q, normal, normal);\r
209             normal.normalize();\r
210             double s[] = new double[1];\r
211             Vector3d r = new Vector3d();\r
212             if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {\r
213                 r.sub(p);\r
214                 translate.x = r.x;\r
215                 translate.y = r.y;\r
216                 translate.z = r.z;\r
217             }\r
218             break;\r
219         case TransformGizmo.X :\r
220             dir = new Vector3d(1.0,0.0,0.0);\r
221             if(!worldCoord)\r
222                 MathTools.rotate(q, dir, dir);\r
223             Vector3d i1 = new Vector3d();\r
224             Vector3d i2 = new Vector3d();\r
225             s = new double[2];\r
226             MathTools.intersectStraightStraight( p, dir,o, d, i2, i1,s);\r
227             translate.x = s[0];\r
228             \r
229             break;\r
230         case TransformGizmo.Y :\r
231             dir = new Vector3d(0.0,1.0,0.0);\r
232             if(!worldCoord)\r
233                 MathTools.rotate(q, dir, dir);\r
234             i1 = new Vector3d();\r
235             i2 = new Vector3d();\r
236             s = new double[2];\r
237             MathTools.intersectStraightStraight( p, dir,o, d, i2, i1,s);\r
238             translate.y = s[0];\r
239             break;\r
240         case TransformGizmo.Z :\r
241             dir = new Vector3d(0.0,0.0,1.0);\r
242             if(!worldCoord)\r
243                 MathTools.rotate(q, dir, dir);\r
244             i1 = new Vector3d();\r
245             i2 = new Vector3d();\r
246             s = new double[2];\r
247             MathTools.intersectStraightStraight( p, dir,o, d, i2, i1,s);\r
248             translate.z = s[0];\r
249             break;\r
250         case TransformGizmo.XY :\r
251             normal = new Vector3d(0.0,0.0,1.0);\r
252             if(!worldCoord)\r
253                 MathTools.rotate(q, normal, normal);\r
254             r = new Vector3d();\r
255             if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {\r
256                 r.sub(p);\r
257                 translate.x = r.x;\r
258                 translate.y = r.y;\r
259             }\r
260             break;\r
261         case TransformGizmo.XZ :\r
262             normal = new Vector3d(0.0,1.0,0.0);\r
263             if(!worldCoord)\r
264                 MathTools.rotate(q, normal, normal);\r
265             r = new Vector3d();\r
266             if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {\r
267                 r.sub(p);\r
268                 translate.x = r.x;\r
269                 translate.z = r.z;\r
270             }\r
271             break;\r
272         case TransformGizmo.YZ :\r
273             normal = new Vector3d(1.0,0.0,0.0);\r
274             if(!worldCoord)\r
275                 MathTools.rotate(q, normal, normal);\r
276             r = new Vector3d();\r
277             if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {\r
278                 r.sub(p);\r
279                 translate.y = r.y;\r
280                 translate.z = r.z;\r
281             }\r
282             break;\r
283         default :\r
284             \r
285             return null;\r
286         }\r
287         translate.sub(offset);\r
288         \r
289         if (useConstraints && dir != null) {\r
290             switch (gizmo.getSelected()) {\r
291             case TransformGizmo.X:\r
292             case TransformGizmo.Y:\r
293             case TransformGizmo.Z:\r
294                 Vector3d t = new Vector3d(translate);\r
295                 // TODO : to the test against all translated objects and snap to closest one\r
296                 Point3d pos = G3DTools.getPoint(mos.get(0).getG3DNode(graph).getWorldPosition());\r
297                 t.add(pos);\r
298                 Point3d snap = detector.getPointSnap2(t, dir);\r
299                 if (snap != null) {\r
300                    // System.out.print("t: " + translate);\r
301                     translate = new Vector3d(snap);\r
302                     translate.sub(pos);\r
303                    // System.out.println(" " + translate);\r
304                 }\r
305                 break;\r
306                 \r
307             }\r
308         }\r
309         return translate;\r
310     }\r
311     \r
312     Vector3d prevTranslate = new Vector3d();\r
313     \r
314     @Override\r
315     public void doChanges(Graph graph) throws Exception {\r
316         if (input.mousePressed()) {\r
317             boolean b = useConstraints;\r
318             useConstraints = false;\r
319             prevTranslate = getTranslate(graph);\r
320             useConstraints = b;\r
321         }\r
322         if (input.mouseClicked()) {\r
323             end();\r
324             return;\r
325         }\r
326         if (!input.mouseDragged()) {\r
327             parent.getDefaultAction().update();\r
328             return;\r
329         }   \r
330         detector.clearConstraintHighlights();\r
331         parent.setViewChanged(true);\r
332         \r
333         \r
334         \r
335         Vector3d translate = getTranslate(graph,prevTranslate);\r
336        \r
337         if (translate == null) {\r
338             //cameraRotateAction.update();\r
339             parent.getDefaultAction().update();\r
340             updateGizmo(graph);\r
341             return;\r
342         }\r
343         //translate.sub(prevTranslate);\r
344        \r
345         if ((input.dragModifiers() & MouseEvent.CTRL_MASK) > 0) {\r
346             String text = "";\r
347             for (IGraphicsNode mo : mos) {\r
348                 \r
349                 Point3d p;\r
350                 if (worldCoord)\r
351                         p = G3DTools.getPoint(mo.getG3DNode(graph).getWorldPosition());//mo.getWorldPosition();\r
352                 else\r
353                         p = G3DTools.getPoint(mo.getG3DNode(graph).getLocalPosition());\r
354                 p.add(translate);\r
355                 if (gizmo.getSelected() == TransformGizmo.X || gizmo.getSelected() == TransformGizmo.XY || gizmo.getSelected() == TransformGizmo.XZ || gizmo.getSelected() == TransformGizmo.XYZ) {\r
356                     p.x = Math.round(istep * p.x) / istep;\r
357                     BigDecimal bx = new BigDecimal(p.x);\r
358                     bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);\r
359                     p.x = bx.doubleValue();\r
360                 }\r
361                 if (gizmo.getSelected() == TransformGizmo.Y || gizmo.getSelected() == TransformGizmo.XY || gizmo.getSelected() == TransformGizmo.YZ || gizmo.getSelected() == TransformGizmo.XYZ) {\r
362                     p.y = Math.round(istep * p.y) / istep;\r
363                     BigDecimal by = new BigDecimal(p.y);\r
364                     by.setScale(decimals, BigDecimal.ROUND_HALF_UP);\r
365                     p.y = by.doubleValue();\r
366                 }\r
367                 if (gizmo.getSelected() == TransformGizmo.Z || gizmo.getSelected() == TransformGizmo.YZ || gizmo.getSelected() == TransformGizmo.XZ || gizmo.getSelected() == TransformGizmo.XYZ) {      \r
368                     p.z = Math.round(istep * p.z) / istep;\r
369                     BigDecimal bz = new BigDecimal(p.z);\r
370                     bz.setScale(decimals, BigDecimal.ROUND_HALF_UP);\r
371                     p.z = bz.doubleValue();\r
372                 }\r
373                 text += p + " ";\r
374                 if (worldCoord)\r
375                         G3DTools.setTuple3(mo.getG3DNode(graph).getWorldPosition(), p); \r
376                 else\r
377                         G3DTools.setTuple3(mo.getG3DNode(graph).getLocalPosition(), p);\r
378                 //mo.setWorldTranslation(p);\r
379                 \r
380             }\r
381             if (useConstraints)\r
382                 text+=detector.getSnapString();\r
383             setInfoText(text);\r
384             \r
385         } else {\r
386             String text = "";\r
387             for (IGraphicsNode mo : mos) {\r
388                 Position pos;\r
389                 if (worldCoord) {\r
390                         pos = mo.getG3DNode(graph).getWorldPosition();  \r
391                 } else {\r
392                         pos = mo.getG3DNode(graph).getLocalPosition();\r
393                 }\r
394                 Point3d p = G3DTools.getPoint(pos);\r
395                         p.add(translate);\r
396                         text += p;\r
397                         G3DTools.setTuple3(pos, p);\r
398             }\r
399             if (useConstraints)\r
400                 text+=detector.getSnapString();\r
401             setInfoText(text);\r
402            // parent.getGraph().commitChanges(CommitMessage.CHANGE_MESSAGE);\r
403         }\r
404         updateGizmo(graph);\r
405 \r
406     }\r
407     \r
408     protected void updateGizmo(Graph graph) {\r
409         List<IGraphicsNode> mos = parent.getSelectionAdapter().getSelectedObjects();\r
410         if (mos.size() == 0) {\r
411                 end();\r
412                 return;\r
413         }\r
414         gizmo.update(G3DTools.getVector(mos.get(0).getG3DNode(graph).getWorldPosition()),camera.getCameraPos(),component);\r
415         \r
416    }\r
417     \r
418     public void setInfoText(String text) {\r
419         \r
420     }\r
421 \r
422 }