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