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
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.processeditor.gizmo;
\r
13 import java.net.URL;
\r
14 import java.util.ArrayList;
\r
15 import java.util.List;
\r
17 import javax.vecmath.Point3d;
\r
19 import org.eclipse.core.runtime.FileLocator;
\r
20 import org.eclipse.core.runtime.Path;
\r
21 import org.simantics.processeditor.Activator;
\r
22 import org.simantics.processeditor.actions.PositionType;
\r
23 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;
\r
24 import org.simantics.proconf.g3d.base.VecmathJmeTools;
\r
25 import org.simantics.proconf.g3d.gizmo.Gizmo;
\r
26 import org.simantics.utils.datastructures.Pair;
\r
28 import com.jme.bounding.BoundingSphere;
\r
29 import com.jme.image.Image;
\r
30 import com.jme.image.Texture;
\r
31 import com.jme.math.Vector3f;
\r
32 import com.jme.renderer.Renderer;
\r
33 import com.jme.scene.BillboardNode;
\r
34 import com.jme.scene.Node;
\r
35 import com.jme.scene.shape.Quad;
\r
36 import com.jme.scene.state.AlphaState;
\r
37 import com.jme.scene.state.LightState;
\r
38 import com.jme.scene.state.TextureState;
\r
39 import com.jme.scene.state.ZBufferState;
\r
40 import com.jme.util.TextureManager;
\r
44 * Gizmo that allows user to selected insertion point of a component
\r
45 * TODO : for splits we want use line between component ends to
\r
46 * position the button, instead of its center point.
\r
48 * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>
\r
51 public class PositionSelectionGizmo implements Gizmo {
\r
53 private static String PICK_PREFIX = "insert";
\r
54 private static String SPLIT_TEXTURE = "icons/middle.png";
\r
55 private static String END_TEXTURE = "icons/plus.png";
\r
56 private static String PORT_TEXTURE = END_TEXTURE;
\r
58 private ThreeDimensionalEditorBase parent;
\r
60 private boolean changed = false;
\r
61 private int selected = -1;
\r
62 private boolean useDistanceResize = true;
\r
64 private List<BillboardNode> nodes;
\r
65 private List<AlphaState> alphaStates;
\r
66 private Node rootNode;
\r
68 public PositionSelectionGizmo(ThreeDimensionalEditorBase parent, List<Pair<Point3d, PositionType>> positions) {
\r
69 this.parent = parent;
\r
70 rootNode = new Node();
\r
71 rootNode.setCullMode(Node.CULL_NEVER);
\r
72 rootNode.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
\r
73 rootNode.setLightCombineMode(LightState.OFF);
\r
75 nodes = new ArrayList<BillboardNode>();
\r
76 alphaStates = new ArrayList<AlphaState>();
\r
77 // create a button (billboard) for each insertion position
\r
79 ZBufferState zs = parent.getRenderingComponent().getDisplaySystem().getRenderer().createZBufferState();
\r
80 zs.setFunction(ZBufferState.CF_ALWAYS);
\r
82 for (Pair<Point3d, PositionType> p : positions) {
\r
83 BillboardNode node = new BillboardNode("");
\r
85 Quad quad = new Quad(PICK_PREFIX + i,1.f,1.f);
\r
87 TextureState ts = parent.getRenderingComponent().getDisplaySystem().getRenderer().createTextureState();
\r
88 String filename = "";
\r
92 filename = END_TEXTURE;
\r
95 filename = SPLIT_TEXTURE;
\r
98 filename = PORT_TEXTURE;
\r
100 URL url = FileLocator.find(Activator.getDefault().getBundle(), new Path(filename),null);
\r
101 Image image = TextureManager.loadImage(url, true);
\r
102 Texture texture = new Texture();
\r
103 texture.setImage(image);
\r
104 texture.setFilter(Texture.FM_LINEAR);
\r
105 ts.setTexture(texture);
\r
106 quad.setRenderState(ts);
\r
108 AlphaState as = parent.getRenderingComponent().getDisplaySystem().getRenderer().createAlphaState();
\r
109 as.setSrcFunction(AlphaState.SB_SRC_ALPHA);
\r
110 as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
\r
111 as.setBlendEnabled(true);
\r
112 alphaStates.add(as);
\r
113 quad.setRenderState(as);
\r
114 quad.setRenderState(zs);
\r
116 node.attachChild(quad);
\r
117 node.setLocalTranslation(VecmathJmeTools.get(p.first));
\r
118 quad.setModelBound(new BoundingSphere(0.5f,new Vector3f()));
\r
119 quad.updateModelBound();
\r
120 rootNode.attachChild(node);
\r
128 public Node getNode() {
\r
133 public String getPickPrefix() {
\r
134 return PICK_PREFIX;
\r
138 public boolean isChanged() {
\r
143 public void setChanged(boolean b) {
\r
148 public void setSelected(String name) {
\r
149 if (name == null) {
\r
153 assert(name.startsWith(PICK_PREFIX));
\r
154 setSelected(Integer.parseInt(name.substring(PICK_PREFIX.length())));
\r
157 private void setSelected(int i) {
\r
160 if (selected != -1) {
\r
161 alphaStates.get(selected).setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
\r
162 nodes.get(selected).getChild(0).setRenderState(alphaStates.get(selected));
\r
165 if (selected != -1) {
\r
166 alphaStates.get(selected).setDstFunction(AlphaState.DB_ONE);
\r
167 nodes.get(selected).getChild(0).setRenderState(alphaStates.get(selected));
\r
169 parent.setViewChanged(true);
\r
172 public int getSelected() {
\r
176 public void update() {
\r
177 if (useDistanceResize) {
\r
178 Vector3f v = VecmathJmeTools.get(parent.getCamera().getCameraPos());
\r
179 for (BillboardNode n : nodes) {
\r
180 float length = v.subtract(n.getWorldTranslation()).length();
\r
181 n.setLocalScale(length * 0.06f);
\r