]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.g3d.vtk/src/org/simantics/g3d/vtk/awt/TranslateAction.java
Compiler warning elimination
[simantics/3d.git] / org.simantics.g3d.vtk / src / org / simantics / g3d / vtk / awt / TranslateAction.java
1 /*******************************************************************************
2  * Copyright (c) 2012, 2013 Association for Decentralized Information Management in
3  * Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.g3d.vtk.awt;
13
14 import java.awt.Cursor;
15 import java.awt.event.KeyEvent;
16 import java.awt.event.MouseEvent;
17 import java.math.BigDecimal;
18
19 import javax.vecmath.AxisAngle4d;
20 import javax.vecmath.Point3d;
21 import javax.vecmath.Quat4d;
22 import javax.vecmath.Vector3d;
23
24 import org.simantics.g3d.math.MathTools;
25 import org.simantics.g3d.math.Ray;
26 import org.simantics.g3d.scenegraph.IG3DNode;
27 import org.simantics.g3d.scenegraph.base.INode;
28 import org.simantics.g3d.scenegraph.structural.IStructuralNode;
29 import org.simantics.g3d.vtk.Activator;
30 import org.simantics.g3d.vtk.common.VTKNodeMap;
31 import org.simantics.g3d.vtk.gizmo.TranslateAxisGizmo;
32 import org.simantics.g3d.vtk.utils.vtkUtil;
33 import org.simantics.utils.threads.AWTThread;
34 import org.simantics.utils.threads.ThreadUtils;
35
36 import vtk.vtkProp;
37
38 public class TranslateAction extends vtkAwtAction{
39         
40         public static final int X = 0;
41         public static final int Y = 1;
42         public static final int Z = 2;
43         public static final int XY = 3;
44         public static final int XZ = 4;
45         public static final int YZ = 5;
46         public static final int P = 6;
47
48         private VTKNodeMap<?, ? extends INode> nodeMap;
49         //private TranslateGizmo  gizmo = new TranslateGizmo();
50         private TranslateAxisGizmo gizmo = new TranslateAxisGizmo();
51         protected IG3DNode node;
52         
53         
54         
55         private Cursor activeCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR);
56         private Cursor dragCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
57         
58         public void setNode(IG3DNode node) {
59                 this.node = node;
60                 if ((node instanceof IStructuralNode) && ((IStructuralNode)node).isPartOfInstantiatedModel() && !((IStructuralNode)node).isInstantiatedModelRoot()) {
61                         setEnabled(false);
62                 } else {
63                         setEnabled(true);
64                 }
65         }
66         
67         public IG3DNode getNode() {
68                 return node;
69         }
70         
71         public TranslateAction(InteractiveVtkPanel panel, VTKNodeMap<?, ? extends INode> nodeMap) {
72                 super(panel);
73                 setImageDescriptor(Activator.imageDescriptorFromPlugin("com.famfamfam.silk", "icons/arrow_out.png"));
74                 setText("Translate");
75                 this.nodeMap = nodeMap;
76         }
77         
78         public void attach() {
79                 if (node == null)
80                         return;
81                 
82                 super.attach();
83                 ThreadUtils.asyncExec(AWTThread.getThreadAccess(), new Runnable() {
84                         public void run() {
85                                 attachUI();
86                                 update();
87                         }
88                 });
89                 
90                 
91                 
92         }
93         
94         public void deattach() {
95                 
96                 node = null;
97                 nodeMap.commit("Translate");
98                 deattachUI();
99                 super.deattach();
100                 panel.repaint();
101         }
102         
103         private void attachUI() {
104                 panel.setCursor(activeCursor);
105                 gizmo.attach(panel);
106         }
107         
108         private void deattachUI() {
109                 panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
110                 gizmo.deattach();
111         }
112         
113         @Override
114         public void keyPressed(KeyEvent e) {
115                 if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
116                         panel.useDefaultAction();
117                 if (valid)
118                         return;
119                 if (e.getKeyCode() == KeyEvent.VK_X) {
120                         if (index != X)
121                                 index = X;
122                         else
123                                 index = P;
124                 }
125                 if (e.getKeyCode() == KeyEvent.VK_Y) {
126                         if (index != Y)
127                                 index = Y;
128                         else
129                                 index = P;
130                 }
131                 if (e.getKeyCode() == KeyEvent.VK_Z) {
132                         if (index != Z)
133                                 index = Z;
134                         else
135                                 index = P;
136                 }
137                 if (e.getKeyCode() == KeyEvent.VK_G) {
138                         worldCoord = !worldCoord;
139                 }
140                 gizmo.setType(index);
141                 
142                 update();
143                 //panel.repaint();
144         }
145         
146         @Override
147         public void keyReleased(KeyEvent e) {
148                 
149         }
150         
151         @Override
152         public void keyTyped(KeyEvent e) {
153                 
154         }
155         
156         @Override
157         public void mouseClicked(MouseEvent e) {
158                 if (e.getClickCount() > 1) {
159                         if (isOverNode(e)) {
160                                 return;
161                         } else {
162                                 panel.useDefaultAction();
163                         }
164                         //if(!gizmo.isPartOf(actor))
165                         //      panel.useDefaultAction();
166                         
167                 }
168         }
169         
170         private boolean isOverNode(MouseEvent e) {
171                 vtkProp picked[] = panel.pick(e.getX(), e.getY());
172                 if (picked !=null) {
173                         for (int i = 0; i < picked.length; i++) {
174                                 if (node.equals(nodeMap.getNode(picked[i])))
175                                         return true;
176                         }
177                 }
178                 return false;
179         }
180         
181         @Override
182         public void mouseEntered(MouseEvent e) {
183                 
184         }
185         
186         @Override
187         public void mouseExited(MouseEvent e) {
188                 
189         }
190         
191         int index = P;
192         protected boolean valid = false;
193         private boolean worldCoord = true;
194         private AxisAngle4d aa = null;
195         private Quat4d q = null;
196         
197         
198         public void setWorldCoord(boolean b) {
199                 if (worldCoord == b)
200                         return;
201                 worldCoord = b;
202                 update();
203                                         
204         }
205         
206         
207         protected void update() {
208                 if (node == null)
209                         return;
210                 if (worldCoord) {
211                         gizmo.setRotation(new AxisAngle4d());
212                         aa = null;
213                         q = null;
214                 } else {
215                         aa = new AxisAngle4d();
216                         aa.set(((IG3DNode)node.getParent()).getWorldOrientation());
217                         gizmo.setRotation(aa);
218                         q = new Quat4d();
219                         MathTools.getQuat(aa, q);
220                 }
221                 
222                 Vector3d nodePos = node.getWorldPosition();
223                 //System.out.println(nodePos);
224                 gizmo.setPosition(nodePos);
225
226                 
227                 Point3d camPos = new Point3d(panel.GetRenderer().GetActiveCamera().GetPosition());
228                 Vector3d p = new Vector3d(nodePos);
229                 p.sub(camPos);
230                 
231                 if (q != null) {
232                         Quat4d qi = new Quat4d(q);
233                         qi.inverse();
234                         MathTools.rotate(q, p, p);
235                 }
236                 if (panel.GetRenderer().GetActiveCamera().GetParallelProjection() == 0) {
237                         double distance = p.length();
238                         p.negate();
239                         double fov = panel.GetRenderer().GetActiveCamera().GetViewAngle();
240                         float s = (float) (Math.sin(fov) * distance * 0.1); 
241
242                         Vector3d scale = new Vector3d(1., 1., 1.);
243                         
244 //            if (p.x > 0.f)
245 //                scale.x = -1.;
246 //            if (p.y > 0.f)
247 //                scale.y = -1.;
248 //            if (p.z > 0.f)
249 //                scale.z = -1.;
250                         scale.scale(s);
251                         gizmo.setScale(scale);
252                         
253                 } else {
254                         Vector3d scale = new Vector3d(1.f, 1.f, 1.f);
255                         double s = panel.GetRenderer().GetActiveCamera().GetParallelScale() / 5.;
256 //            if (p.x > 0.f)
257 //                scale.x = -1.;
258 //            if (p.y > 0.f)
259 //                scale.y = -1.;
260 //            if (p.z > 0.f)
261 //                scale.z = -1.;
262                         scale.scale(s);
263                         gizmo.setScale(scale);
264                 }
265                 
266                 //panel.Render();
267                 panel.repaint();
268         }
269         
270         protected Vector3d prevTranslate = null;
271         
272         @Override
273         public void mousePressed(MouseEvent e) {
274                 if (e.getButton() == MouseEvent.BUTTON1) {
275
276                         if (isOverNode(e)) {
277                                 prevTranslate = getTranslate(e.getX(), e.getY());
278                                 valid = true;
279                                 panel.setCursor(dragCursor);
280                         } else {
281                                 valid = false;
282                                 getDefaultAction().mousePressed(e);
283                                 panel.setCursor(activeCursor);
284                         }
285                 } else {
286                         getDefaultAction().mousePressed(e);
287                 }
288                 //index = gizmo.getTranslateAxis(actor);
289                 //if (index == -1) {
290                 //  valid = false;
291                 //      panel.getDefaultAction().mousePressed(e);
292                 //      return;
293                 //}
294                 //valid = true; 
295                 //prevTranslate = getTranslate(e.getX(), e.getY());
296                 //System.out.println("start translate " + prevTranslate);
297         }
298         
299         
300         
301         @Override
302         public void mouseReleased(MouseEvent e) {
303                 if (e.getButton() == MouseEvent.BUTTON1) {
304                         valid = false;
305                         prevTranslate = null;
306                         panel.setCursor(activeCursor);
307                 } else {
308                         getDefaultAction().mouseReleased(e);
309                 }
310         }
311         
312         @Override
313         public void mouseDragged(MouseEvent e) {
314                 if ((e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) > 0 && valid) { 
315                         
316                         Vector3d translate = getTranslate(e.getX(), e.getY(), prevTranslate);
317                         //System.out.println("translate " + translate);
318                         if (translate == null)
319                                 return;
320                         boolean step = ((e.getModifiers() & MouseEvent.CTRL_MASK) > 0);
321                         if (worldCoord) {
322                                 Vector3d pos = new Vector3d(node.getWorldPosition());
323                                 pos.add(translate);
324                                 pos = constaints(pos, step);
325                                 setWorldPos(pos);
326                         } else {
327                                 Vector3d pos = new Vector3d(node.getPosition());
328                                 pos.add(translate);
329                                 pos = constaints(pos, step);
330                                 setPos(pos);
331                         }
332                         //mapping.rangeModified(node);
333                         
334                         //nodeMap.modified(node);
335                         update();
336                 } else {
337                         getDefaultAction().mouseDragged(e);
338                         update();
339                 }
340         }
341         
342         protected void setPos(Vector3d pos) {
343                 node.setPosition(pos);
344         }
345         
346         protected void setWorldPos(Vector3d pos) {
347                 node.setWorldPosition(pos);
348         }
349         
350         private double istep = 10.0;
351         private int decimals = 2;
352
353         protected Vector3d constaints(Vector3d p, boolean step) {
354                 if(!step)
355                         return p;
356                 switch (index) {
357                 case X:
358                         p.x = Math.round(istep * p.x) / istep;
359                         BigDecimal bx = new BigDecimal(p.x);
360                         bx.setScale(decimals, BigDecimal.ROUND_HALF_UP);
361                         p.x = bx.doubleValue();
362                         break;
363                 case Y:
364                         p.y = Math.round(istep * p.y) / istep;
365                         BigDecimal by = new BigDecimal(p.y);
366                         by.setScale(decimals, BigDecimal.ROUND_HALF_UP);
367                         p.y = by.doubleValue();
368                         break;
369
370                 case Z:
371                         p.z = Math.round(istep * p.z) / istep;
372                         BigDecimal bz = new BigDecimal(p.z);
373                         bz.setScale(decimals, BigDecimal.ROUND_HALF_UP);
374                         p.z = bz.doubleValue();
375                         break;
376                 }
377                 return p;
378         }
379         
380         @Override
381         public void mouseMoved(MouseEvent e) {
382                 getDefaultAction().mouseMoved(e);
383         }
384         
385         protected Vector3d getTranslate(double x, double y) {
386                 return getTranslate(x, y, new Vector3d());
387         }
388         
389         protected Vector3d getTranslate(double x, double y, Vector3d offset) {
390                 Vector3d translate = new Vector3d();
391                 
392                 Ray ray = vtkUtil.createMouseRay(panel.GetRenderer(),x, y);
393                 
394                 Vector3d p = node.getWorldPosition();
395                 Vector3d dir = null;
396                 
397                 switch (index) {
398                 case P:
399                         Vector3d normal = new Vector3d(panel.GetRenderer().GetActiveCamera().GetDirectionOfProjection());
400                         if (!worldCoord) {
401                                 MathTools.rotate(q, normal, normal);
402                         }
403                         normal.normalize();
404                         double s[] = new double[1];
405                         Vector3d r = new Vector3d();
406                         if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
407                                 r.sub(p);
408                                 translate.x = r.x;
409                                 translate.y = r.y;
410                                 translate.z = r.z;
411                         }
412                         break;
413
414                 case X :
415                                 dir = new Vector3d(1.0,0.0,0.0);
416                                 if(!worldCoord)
417                                         MathTools.rotate(q, dir, dir);
418                                 Vector3d i1 = new Vector3d();
419                                 Vector3d i2 = new Vector3d();
420                                 s = new double[2];
421                                 MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);
422                                 translate.x = s[0];
423                                 
424                                 break;
425                         case Y :
426                                 dir = new Vector3d(0.0,1.0,0.0);
427                                 if(!worldCoord)
428                                         MathTools.rotate(q, dir, dir);
429                                 i1 = new Vector3d();
430                                 i2 = new Vector3d();
431                                 s = new double[2];
432                                 MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);
433                                 translate.y = s[0];
434                                 break;
435                         case Z :
436                                 dir = new Vector3d(0.0,0.0,1.0);
437                                 if(!worldCoord)
438                                         MathTools.rotate(q, dir, dir);
439                                 i1 = new Vector3d();
440                                 i2 = new Vector3d();
441                                 s = new double[2];
442                                 MathTools.intersectStraightStraight( p, dir,ray.pos, ray.dir, i2, i1,s);
443                                 translate.z = s[0];
444                                 break;
445                         case XY :
446                                 normal = new Vector3d(0.0,0.0,1.0);
447                                 if(!worldCoord)
448                                         MathTools.rotate(q, normal, normal);
449                                 r = new Vector3d();
450                                 if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
451                                         r.sub(p);
452                                         translate.x = r.x;
453                                         translate.y = r.y;
454                                 }
455                                 break;
456                         case XZ :
457                                 normal = new Vector3d(0.0,1.0,0.0);
458                                 if(!worldCoord)
459                                         MathTools.rotate(q, normal, normal);
460                                 r = new Vector3d();
461                                 if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
462                                         r.sub(p);
463                                         translate.x = r.x;
464                                         translate.z = r.z;
465                                 }
466                                 break;
467                         case YZ :
468                                 normal = new Vector3d(1.0,0.0,0.0);
469                                 if(!worldCoord)
470                                         MathTools.rotate(q, normal, normal);
471                                 r = new Vector3d();
472                                 if (MathTools.intersectStraightPlane(ray.pos, ray.dir, p, normal, r)) {
473                                         r.sub(p);
474                                         translate.y = r.y;
475                                         translate.z = r.z;
476                                 }
477                                 break;
478                         default :
479                                 
480                                 return null;
481                         }
482                         translate.sub(offset);
483                         return translate;
484         }
485         
486 }