]> gerrit.simantics Code Review - simantics/3d.git/blob
c3e848de6ca144d51ce53813a4f2f9cb528c0f2a
[simantics/3d.git] /
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.processeditor.actions;\r
12 \r
13 import java.util.List;\r
14 \r
15 import javax.vecmath.AxisAngle4f;\r
16 import javax.vecmath.Point3d;\r
17 import javax.vecmath.Vector3d;\r
18 \r
19 import org.eclipse.jface.action.IToolBarManager;\r
20 import org.simantics.db.Graph;\r
21 import org.simantics.db.GraphRequestAdapter;\r
22 import org.simantics.db.GraphRequestStatus;\r
23 import org.simantics.db.Resource;\r
24 import org.simantics.layer0.utils.EntityFactory;\r
25 import org.simantics.layer0.utils.IEntity;\r
26 import org.simantics.processeditor.Activator;\r
27 import org.simantics.processeditor.ProcessResource;\r
28 import org.simantics.processeditor.common.ControlPointTools;\r
29 import org.simantics.processeditor.common.PipingTools2;\r
30 import org.simantics.processeditor.stubs.FixedLengthInlineComponent;\r
31 import org.simantics.processeditor.stubs.PipeControlPoint;\r
32 import org.simantics.proconf.g3d.actions.ConstrainedTransformAction;\r
33 import org.simantics.proconf.g3d.actions.TranslateActionConstraints;\r
34 import org.simantics.proconf.g3d.base.G3DTools;\r
35 import org.simantics.proconf.g3d.base.MathTools;\r
36 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
37 import org.simantics.proconf.g3d.gizmo.AbstractGizmo;\r
38 import org.simantics.proconf.g3d.gizmo.TransformGizmo;\r
39 import org.simantics.proconf.g3d.gizmo.TransformInlineGizmo;\r
40 \r
41
42 \r
43 \r
44 /**\r
45  * Action that allows translating VariableLengthInlineComontolPoints.\r
46  * \r
47  * TODO : Action won't show two gizmos when both ends can be moved\r
48  * TODO : With loose ends, gizmo is in the middle of component, when it should be positioned on the end of the component\r
49  * \r
50  * \r
51  * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>\r
52  *\r
53  */\r
54 public class TranslateStraightAction extends ConstrainedTransformAction {\r
55         \r
56         private static final int CONNECTED = 0;\r
57     private static final int LOOSE = 1;\r
58     \r
59     private AbstractGizmo gizmo; \r
60     private TransformGizmo transformGizmo;\r
61     private TransformInlineGizmo transformInlineGizmo;\r
62     \r
63     \r
64     //private Straight straight;\r
65     //private PipeControlPoint pcp;\r
66     \r
67     private Resource pcpResource;\r
68     \r
69     private int type;\r
70 \r
71     Vector3d prevTranslate = new Vector3d();\r
72     \r
73     Point3d start;\r
74     Point3d end;\r
75     Vector3d dir;\r
76     double istep = 10.0;\r
77     int decimals = 2;\r
78     public TranslateStraightAction(ThreeDimensionalEditorBase parent) {\r
79         super(parent);\r
80         transformGizmo = new TransformGizmo(component.getDisplaySystem().getRenderer());\r
81         transformInlineGizmo = new TransformInlineGizmo(component.getDisplaySystem().getRenderer());\r
82     }\r
83     \r
84     public void init() {\r
85         this.setText("Translate");\r
86         this.setToolTipText("Translate one end of a straight");\r
87         this.setImageDescriptor(Activator.imageDescriptorFromPlugin(Activator.PLUGIN_ID, "icons/translate_d.png"));\r
88     }\r
89     \r
90     @Override\r
91     public boolean usable(Graph graph, List<Resource> resources) {\r
92         if (resources.size() != 1)\r
93             return false;\r
94        \r
95         IEntity r = EntityFactory.create(graph,resources.get(0));\r
96         if (!r.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {\r
97                         return false;\r
98                 }\r
99         FixedLengthInlineComponent flic = new FixedLengthInlineComponent(r);\r
100         PipeControlPoint scp = flic.getControlPoint();\r
101         PipeControlPoint start = scp.getPrevious();\r
102         PipeControlPoint end = scp.getNext(); \r
103         \r
104         if (start == null) {\r
105                 pcpResource = scp.getResource();\r
106                 type = LOOSE;\r
107                 return true;\r
108         }\r
109         if (end == null) {\r
110                 pcpResource = scp.getResource();\r
111                 type = LOOSE;\r
112                 return true;\r
113         }\r
114         if (start.isInstanceOf(ProcessResource.plant3Dresource.BranchEndControlPoint)) {\r
115                 pcpResource = graph.getObjects(start.getResource(), ProcessResource.plant3Dresource.SubPointOf).iterator().next();\r
116                 type = CONNECTED;\r
117                 return true;\r
118         }\r
119         if (end.isInstanceOf(ProcessResource.plant3Dresource.BranchEndControlPoint)) {\r
120                 pcpResource = graph.getObjects(end.getResource(), ProcessResource.plant3Dresource.SubPointOf).iterator().next();\r
121                 type = CONNECTED;\r
122                 return true;\r
123         }\r
124        \r
125 \r
126         return false;\r
127         \r
128     }\r
129     \r
130     @Override\r
131     public void deactivate() {\r
132         super.deactivate();\r
133         parent.setGizmo(null);\r
134 \r
135     }\r
136 \r
137     @Override\r
138     public void activate() {\r
139         parent.getSession().syncRead(new GraphRequestAdapter() {\r
140                 @Override\r
141                 public GraphRequestStatus perform(Graph g) throws Exception {\r
142                         PipeControlPoint pcp = new PipeControlPoint(g,pcpResource);\r
143                         if (type == CONNECTED) {\r
144                     gizmo = transformInlineGizmo;\r
145                     \r
146                     start = new Point3d();\r
147                     end = new Point3d();\r
148                     dir = new Vector3d();\r
149                     //ControlPointTools.getInlineControlPointEnds(pcp, start, end, dir);\r
150                     ControlPointTools.getInlineMovement(pcp, start, end);\r
151                         \r
152                         //PipingTools2.getInlineComponentEnds(ic, start, end);\r
153                     dir.set(end);\r
154                     dir.sub(start);\r
155                     \r
156                     //System.out.println(start + " " + end + " " + dir);\r
157                     Vector3d front = new Vector3d(1.0,0.0,0.0);\r
158                     Vector3d current = new Vector3d(dir);\r
159                     float angle = (float)current.angle(front);\r
160                     AxisAngle4f aa;\r
161                     if (angle < 0.01 || (Math.PI - angle) < 0.01) {\r
162                         aa = new AxisAngle4f();\r
163                     } else {\r
164                         current.normalize();\r
165                         Vector3d right = new Vector3d();\r
166                         right.cross(front, current);\r
167 \r
168                         right.normalize();\r
169                         if (right.lengthSquared() < 0.01) {\r
170                             aa = new AxisAngle4f();\r
171                         } else {\r
172                             aa = new AxisAngle4f((float) right.x, (float) right.y, (float) right.z, angle);\r
173                         }\r
174                     }\r
175                     transformInlineGizmo.setRotation(aa);\r
176                     \r
177                 } else {\r
178                     gizmo = transformGizmo;\r
179                 }\r
180                 parent.setGizmo(gizmo);\r
181 \r
182                 component.getNoShadowRoot().attachChild(gizmo.getNode());\r
183 \r
184                 updateGizmo(pcp);\r
185                 TranslateActionConstraints.addConstraints(new Resource[]{pcpResource}, detector);\r
186                 parent.setViewChanged(true);\r
187                 \r
188                         return GraphRequestStatus.transactionComplete();\r
189                 }\r
190         });\r
191         \r
192     }\r
193     \r
194     \r
195     // FIXME : copy-paste from TranslateInlineAction.getTranslate()\r
196     Vector3d getTranslate() {\r
197         Vector3d translate = new Vector3d();\r
198         Vector3d o = new Vector3d();\r
199         Vector3d d = new Vector3d();\r
200         parent.createPickRay(o, d);\r
201         // Vector3d p = gizmo.getPosition();\r
202         if (((TransformInlineGizmo) gizmo).isSelected()) {\r
203             double s[] = new double[1];\r
204 \r
205             Vector3d i1 = new Vector3d();\r
206             Vector3d i2 = new Vector3d();\r
207             s = new double[2];\r
208             MathTools.intersectStraightStraight(start, dir, o, d, i2, i1, s);\r
209             translate.set(dir);\r
210             if (s[0] < 0.0)\r
211                 s[0] = 0.0;\r
212             else if (s[0] > 1.0)\r
213                 s[0] = 1.0;\r
214             translate.scale(s[0]);\r
215             translate.add(start);\r
216             \r
217             if (useConstraints) {\r
218                 Vector3d t = new Vector3d(translate);\r
219                 // FIXME : snapped point may be outside of proper range\r
220                 Point3d snap = detector.getPointSnap2(t, dir);\r
221                 if (snap != null) {\r
222                     translate = new Vector3d(snap);\r
223                 }\r
224             }\r
225 \r
226             return translate;\r
227         }\r
228         return null;\r
229     }\r
230     // FIXME : copy-paste from TranslateAction.getTranslate(Vector3d v)\r
231     Vector3d getTranslate(PipeControlPoint pcp, Vector3d offset) {\r
232         Vector3d translate = new Vector3d();\r
233         Vector3d o = new Vector3d();\r
234         Vector3d d = new Vector3d();\r
235         parent.createPickRay(o, d);\r
236         Vector3d p = ((TransformGizmo)gizmo).getPosition();\r
237         Vector3d dir = null;\r
238         switch (((TransformGizmo)gizmo).getSelected()) {\r
239         case TransformGizmo.XYZ :\r
240             Vector3d normal = camera.getUnNormalizedHeading();\r
241             normal.normalize();\r
242             double s[] = new double[1];\r
243             Vector3d r = new Vector3d();\r
244             if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {\r
245                 r.sub(p);\r
246                 translate.x = r.x;\r
247                 translate.y = r.y;\r
248                 translate.z = r.z;\r
249             }\r
250             break;\r
251         case TransformGizmo.X :\r
252             dir = new Vector3d(1.0,0.0,0.0);\r
253             Vector3d i1 = new Vector3d();\r
254             Vector3d i2 = new Vector3d();\r
255             s = new double[2];\r
256             MathTools.intersectStraightStraight( p, dir,o, d, i2, i1,s);\r
257             translate.x = s[0];\r
258             \r
259             break;\r
260         case TransformGizmo.Y :\r
261             dir = new Vector3d(0.0,1.0,0.0);\r
262             i1 = new Vector3d();\r
263             i2 = new Vector3d();\r
264             s = new double[2];\r
265             MathTools.intersectStraightStraight( p, dir,o, d, i2, i1,s);\r
266             translate.y = s[0];\r
267             break;\r
268         case TransformGizmo.Z :\r
269             dir = new Vector3d(0.0,0.0,1.0);\r
270             i1 = new Vector3d();\r
271             i2 = new Vector3d();\r
272             s = new double[2];\r
273             MathTools.intersectStraightStraight( p, dir,o, d, i2, i1,s);\r
274             translate.z = s[0];\r
275             break;\r
276         case TransformGizmo.XY :\r
277             normal = new Vector3d(0.0,0.0,1.0);\r
278             s = new double[1];\r
279             r = new Vector3d();\r
280             if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {\r
281                 r.sub(p);\r
282                 translate.x = r.x;\r
283                 translate.y = r.y;\r
284             }\r
285             break;\r
286         case TransformGizmo.XZ :\r
287             normal = new Vector3d(0.0,1.0,0.0);\r
288             s = new double[1];\r
289             r = new Vector3d();\r
290             if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {\r
291                 r.sub(p);\r
292                 translate.x = r.x;\r
293                 translate.z = r.z;\r
294             }\r
295             break;\r
296         case TransformGizmo.YZ :\r
297             normal = new Vector3d(1.0,0.0,0.0);\r
298             s = new double[1];\r
299             r = new Vector3d();\r
300             if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {\r
301                 r.sub(p);\r
302                 translate.y = r.y;\r
303                 translate.z = r.z;\r
304             }\r
305             break;\r
306         default :\r
307             \r
308             return null;\r
309         }\r
310         //System.out.println(translate + " " + offset);\r
311         translate.sub(offset);\r
312         \r
313         if (useConstraints) {\r
314             switch (((TransformGizmo)gizmo).getSelected()) {\r
315             case TransformGizmo.X:\r
316             case TransformGizmo.Y:\r
317             case TransformGizmo.Z:\r
318                 Vector3d t = new Vector3d(translate);\r
319                 // TODO : to the test against all translated objects and snap to closest one\r
320                 Point3d pos = G3DTools.getPoint(pcp.getLocalPosition());\r
321                 t.add(pos);\r
322                 Point3d snap = detector.getPointSnap2(t, dir);\r
323                 if (snap != null) {\r
324                    // System.out.print("t: " + translate);\r
325                     translate = new Vector3d(snap);\r
326                     translate.sub(pos);\r
327                    // System.out.println(" " + translate);\r
328                 }\r
329                 break;\r
330                 \r
331             }\r
332         }\r
333         //System.out.println(translate);\r
334         return translate;\r
335     }\r
336     \r
337     \r
338     \r
339     @Override\r
340     public void doChanges(Graph graph) throws Exception {\r
341         PipeControlPoint pcp = new PipeControlPoint(graph, pcpResource); \r
342         if (input.mousePressed()) {\r
343             if (type == LOOSE)\r
344                 prevTranslate = getTranslate(pcp,new Vector3d());\r
345             \r
346         }\r
347         if (input.mouseClicked()) {\r
348             //System.out.println("end");\r
349             end();\r
350             return;\r
351         }\r
352         if (!input.mouseDragged()) {\r
353             parent.getDefaultAction().update();\r
354             return;\r
355         } \r
356         detector.clearConstraintHighlights();\r
357         parent.setViewChanged(true);\r
358         \r
359         \r
360         Vector3d translate;\r
361         if (type == CONNECTED)\r
362             translate = getTranslate();\r
363         else\r
364             translate = getTranslate(pcp,prevTranslate);\r
365        \r
366         if (translate == null) {\r
367             //cameraRotateAction.update();\r
368             parent.getDefaultAction().update();\r
369             updateGizmo(pcp);\r
370             return;\r
371         }\r
372 \r
373         String text = "";\r
374         \r
375         if (type == CONNECTED) {\r
376                 G3DTools.setTuple3(pcp.getWorldPosition(), translate);\r
377                 // mo.setLocalTranslation(translate);\r
378                 //text += GraphicsNodeTools.getWorldTranslation(mo.getGraphicsNode()) + " " + translate;// mo.getWorldPosition()\r
379                 if (useConstraints)\r
380                     text+=detector.getSnapString();\r
381 \r
382         } else {\r
383                 G3DTools.addTuple3(pcp.getWorldPosition(), translate);\r
384                // mo.modifyWorldTranslation(translate);\r
385                 //text += GraphicsNodeTools.getWorldTranslation(mo.getGraphicsNode()) + " ";//mo.getWorldPosition() + " ";\r
386             if (useConstraints)\r
387                 text+=detector.getSnapString();\r
388             \r
389         }\r
390         \r
391         setInfoText(text);\r
392         updateGizmo(pcp);\r
393 \r
394     }\r
395     \r
396     protected void updateGizmo(PipeControlPoint pcp) {\r
397                 gizmo.update(G3DTools.getVector(pcp.getWorldPosition()), camera.getCameraPos(), component);\r
398     }\r
399     \r
400     public void setInfoText(String text) {\r
401         \r
402     }\r
403 \r
404 }