1 package org.simantics.processeditor.gizmo;
\r
4 import java.util.ArrayList;
\r
5 import java.util.List;
\r
7 import javax.vecmath.Point3d;
\r
9 import org.eclipse.core.runtime.FileLocator;
\r
10 import org.eclipse.core.runtime.Path;
\r
11 import org.simantics.processeditor.Activator;
\r
12 import org.simantics.processeditor.actions.PositionType;
\r
13 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;
\r
14 import org.simantics.proconf.g3d.base.VecmathJmeTools;
\r
15 import org.simantics.proconf.g3d.gizmo.Gizmo;
\r
16 import org.simantics.utils.datastructures.Pair;
\r
18 import com.jme.bounding.BoundingSphere;
\r
19 import com.jme.image.Image;
\r
20 import com.jme.image.Texture;
\r
21 import com.jme.math.Vector3f;
\r
22 import com.jme.renderer.Renderer;
\r
23 import com.jme.scene.BillboardNode;
\r
24 import com.jme.scene.Node;
\r
25 import com.jme.scene.shape.Quad;
\r
26 import com.jme.scene.state.AlphaState;
\r
27 import com.jme.scene.state.LightState;
\r
28 import com.jme.scene.state.TextureState;
\r
29 import com.jme.scene.state.ZBufferState;
\r
30 import com.jme.util.TextureManager;
\r
34 * Gizmo that allows user to selected insertion point of a component
\r
35 * TODO : for splits we want use line between component ends to
\r
36 * position the button, instead of its center point.
\r
38 * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>
\r
41 public class PositionSelectionGizmo implements Gizmo {
\r
43 private static String PICK_PREFIX = "insert";
\r
44 private static String SPLIT_TEXTURE = "icons/middle.png";
\r
45 private static String END_TEXTURE = "icons/plus.png";
\r
46 private static String PORT_TEXTURE = END_TEXTURE;
\r
48 private ThreeDimensionalEditorBase parent;
\r
50 private boolean changed = false;
\r
51 private int selected = -1;
\r
52 private boolean useDistanceResize = true;
\r
54 private List<BillboardNode> nodes;
\r
55 private List<AlphaState> alphaStates;
\r
56 private Node rootNode;
\r
58 public PositionSelectionGizmo(ThreeDimensionalEditorBase parent, List<Pair<Point3d, PositionType>> positions) {
\r
59 this.parent = parent;
\r
60 rootNode = new Node();
\r
61 rootNode.setCullMode(Node.CULL_NEVER);
\r
62 rootNode.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
\r
63 rootNode.setLightCombineMode(LightState.OFF);
\r
65 nodes = new ArrayList<BillboardNode>();
\r
66 alphaStates = new ArrayList<AlphaState>();
\r
67 // create a button (billboard) for each insertion position
\r
69 ZBufferState zs = parent.getRenderingComponent().getDisplaySystem().getRenderer().createZBufferState();
\r
70 zs.setFunction(ZBufferState.CF_ALWAYS);
\r
72 for (Pair<Point3d, PositionType> p : positions) {
\r
73 BillboardNode node = new BillboardNode("");
\r
75 Quad quad = new Quad(PICK_PREFIX + i,1.f,1.f);
\r
77 TextureState ts = parent.getRenderingComponent().getDisplaySystem().getRenderer().createTextureState();
\r
78 String filename = "";
\r
82 filename = END_TEXTURE;
\r
85 filename = SPLIT_TEXTURE;
\r
88 filename = PORT_TEXTURE;
\r
90 URL url = FileLocator.find(Activator.getDefault().getBundle(), new Path(filename),null);
\r
91 Image image = TextureManager.loadImage(url, true);
\r
92 Texture texture = new Texture();
\r
93 texture.setImage(image);
\r
94 texture.setFilter(Texture.FM_LINEAR);
\r
95 ts.setTexture(texture);
\r
96 quad.setRenderState(ts);
\r
98 AlphaState as = parent.getRenderingComponent().getDisplaySystem().getRenderer().createAlphaState();
\r
99 as.setSrcFunction(AlphaState.SB_SRC_ALPHA);
\r
100 as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
\r
101 as.setBlendEnabled(true);
\r
102 alphaStates.add(as);
\r
103 quad.setRenderState(as);
\r
104 quad.setRenderState(zs);
\r
106 node.attachChild(quad);
\r
107 node.setLocalTranslation(VecmathJmeTools.get(p.first));
\r
108 quad.setModelBound(new BoundingSphere(0.5f,new Vector3f()));
\r
109 quad.updateModelBound();
\r
110 rootNode.attachChild(node);
\r
118 public Node getNode() {
\r
123 public String getPickPrefix() {
\r
124 return PICK_PREFIX;
\r
128 public boolean isChanged() {
\r
133 public void setChanged(boolean b) {
\r
138 public void setSelected(String name) {
\r
139 if (name == null) {
\r
143 assert(name.startsWith(PICK_PREFIX));
\r
144 setSelected(Integer.parseInt(name.substring(PICK_PREFIX.length())));
\r
147 private void setSelected(int i) {
\r
150 if (selected != -1) {
\r
151 alphaStates.get(selected).setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
\r
152 nodes.get(selected).getChild(0).setRenderState(alphaStates.get(selected));
\r
155 if (selected != -1) {
\r
156 alphaStates.get(selected).setDstFunction(AlphaState.DB_ONE);
\r
157 nodes.get(selected).getChild(0).setRenderState(alphaStates.get(selected));
\r
159 parent.setViewChanged(true);
\r
162 public int getSelected() {
\r
166 public void update() {
\r
167 if (useDistanceResize) {
\r
168 Vector3f v = VecmathJmeTools.get(parent.getCamera().getCameraPos());
\r
169 for (BillboardNode n : nodes) {
\r
170 float length = v.subtract(n.getWorldTranslation()).length();
\r
171 n.setLocalScale(length * 0.06f);
\r