1 /*******************************************************************************
\r
2 * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.
\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
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.processeditor.actions;
\r
13 import java.util.List;
\r
15 import javax.vecmath.AxisAngle4f;
\r
16 import javax.vecmath.Point3d;
\r
17 import javax.vecmath.Vector3d;
\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
45 * Action that allows translating VariableLengthInlineComontolPoints.
\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
51 * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>
\r
54 public class TranslateStraightAction extends ConstrainedTransformAction {
\r
56 private static final int CONNECTED = 0;
\r
57 private static final int LOOSE = 1;
\r
59 private AbstractGizmo gizmo;
\r
60 private TransformGizmo transformGizmo;
\r
61 private TransformInlineGizmo transformInlineGizmo;
\r
64 //private Straight straight;
\r
65 //private PipeControlPoint pcp;
\r
67 private Resource pcpResource;
\r
71 Vector3d prevTranslate = new Vector3d();
\r
76 double istep = 10.0;
\r
78 public TranslateStraightAction(ThreeDimensionalEditorBase parent) {
\r
80 transformGizmo = new TransformGizmo(component.getDisplaySystem().getRenderer());
\r
81 transformInlineGizmo = new TransformInlineGizmo(component.getDisplaySystem().getRenderer());
\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
91 public boolean usable(Graph graph, List<Resource> resources) {
\r
92 if (resources.size() != 1)
\r
95 IEntity r = EntityFactory.create(graph,resources.get(0));
\r
96 if (!r.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {
\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
104 if (start == null) {
\r
105 pcpResource = scp.getResource();
\r
110 pcpResource = scp.getResource();
\r
114 if (start.isInstanceOf(ProcessResource.plant3Dresource.BranchEndControlPoint)) {
\r
115 pcpResource = graph.getObjects(start.getResource(), ProcessResource.plant3Dresource.SubPointOf).iterator().next();
\r
119 if (end.isInstanceOf(ProcessResource.plant3Dresource.BranchEndControlPoint)) {
\r
120 pcpResource = graph.getObjects(end.getResource(), ProcessResource.plant3Dresource.SubPointOf).iterator().next();
\r
131 public void deactivate() {
\r
132 super.deactivate();
\r
133 parent.setGizmo(null);
\r
138 public void activate() {
\r
139 parent.getSession().syncRead(new GraphRequestAdapter() {
\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
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
152 //PipingTools2.getInlineComponentEnds(ic, start, end);
\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
161 if (angle < 0.01 || (Math.PI - angle) < 0.01) {
\r
162 aa = new AxisAngle4f();
\r
164 current.normalize();
\r
165 Vector3d right = new Vector3d();
\r
166 right.cross(front, current);
\r
169 if (right.lengthSquared() < 0.01) {
\r
170 aa = new AxisAngle4f();
\r
172 aa = new AxisAngle4f((float) right.x, (float) right.y, (float) right.z, angle);
\r
175 transformInlineGizmo.setRotation(aa);
\r
178 gizmo = transformGizmo;
\r
180 parent.setGizmo(gizmo);
\r
182 component.getNoShadowRoot().attachChild(gizmo.getNode());
\r
185 TranslateActionConstraints.addConstraints(new Resource[]{pcpResource}, detector);
\r
186 parent.setViewChanged(true);
\r
188 return GraphRequestStatus.transactionComplete();
\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
205 Vector3d i1 = new Vector3d();
\r
206 Vector3d i2 = new Vector3d();
\r
208 MathTools.intersectStraightStraight(start, dir, o, d, i2, i1, s);
\r
209 translate.set(dir);
\r
212 else if (s[0] > 1.0)
\r
214 translate.scale(s[0]);
\r
215 translate.add(start);
\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
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
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
256 MathTools.intersectStraightStraight( p, dir,o, d, i2, i1,s);
\r
257 translate.x = s[0];
\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
265 MathTools.intersectStraightStraight( p, dir,o, d, i2, i1,s);
\r
266 translate.y = s[0];
\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
273 MathTools.intersectStraightStraight( p, dir,o, d, i2, i1,s);
\r
274 translate.z = s[0];
\r
276 case TransformGizmo.XY :
\r
277 normal = new Vector3d(0.0,0.0,1.0);
\r
279 r = new Vector3d();
\r
280 if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {
\r
286 case TransformGizmo.XZ :
\r
287 normal = new Vector3d(0.0,1.0,0.0);
\r
289 r = new Vector3d();
\r
290 if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {
\r
296 case TransformGizmo.YZ :
\r
297 normal = new Vector3d(1.0,0.0,0.0);
\r
299 r = new Vector3d();
\r
300 if (MathTools.intersectStraightPlane(o, d, p, normal, r)) {
\r
310 //System.out.println(translate + " " + offset);
\r
311 translate.sub(offset);
\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
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
333 //System.out.println(translate);
\r
340 public void doChanges(Graph graph) throws Exception {
\r
341 PipeControlPoint pcp = new PipeControlPoint(graph, pcpResource);
\r
342 if (input.mousePressed()) {
\r
344 prevTranslate = getTranslate(pcp,new Vector3d());
\r
347 if (input.mouseClicked()) {
\r
348 //System.out.println("end");
\r
352 if (!input.mouseDragged()) {
\r
353 parent.getDefaultAction().update();
\r
356 detector.clearConstraintHighlights();
\r
357 parent.setViewChanged(true);
\r
360 Vector3d translate;
\r
361 if (type == CONNECTED)
\r
362 translate = getTranslate();
\r
364 translate = getTranslate(pcp,prevTranslate);
\r
366 if (translate == null) {
\r
367 //cameraRotateAction.update();
\r
368 parent.getDefaultAction().update();
\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
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
396 protected void updateGizmo(PipeControlPoint pcp) {
\r
397 gizmo.update(G3DTools.getVector(pcp.getWorldPosition()), camera.getCameraPos(), component);
\r
400 public void setInfoText(String text) {
\r