]> gerrit.simantics Code Review - simantics/3d.git/blob - dev/org.simantics.proconf.processeditor/src/fi/vtt/simantics/processeditor/gizmo/PositionSelectionGizmo.java
Release
[simantics/3d.git] / dev / org.simantics.proconf.processeditor / src / fi / vtt / simantics / processeditor / gizmo / PositionSelectionGizmo.java
1 package fi.vtt.simantics.processeditor.gizmo;\r
2 \r
3 import java.net.URL;\r
4 import java.util.ArrayList;\r
5 import java.util.List;\r
6 \r
7 import javax.vecmath.Point3d;\r
8 \r
9 import org.eclipse.core.runtime.FileLocator;\r
10 import org.eclipse.core.runtime.Path;\r
11 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
12 import org.simantics.proconf.g3d.base.VecmathJmeTools;\r
13 import org.simantics.proconf.g3d.gizmo.Gizmo;\r
14 import org.simantics.utils.datastructures.Pair;\r
15 \r
16 import com.jme.bounding.BoundingSphere;\r
17 import com.jme.image.Image;\r
18 import com.jme.image.Texture;\r
19 import com.jme.math.Vector3f;\r
20 import com.jme.renderer.Renderer;\r
21 import com.jme.scene.BillboardNode;\r
22 import com.jme.scene.Node;\r
23 import com.jme.scene.shape.Quad;\r
24 import com.jme.scene.state.AlphaState;\r
25 import com.jme.scene.state.LightState;\r
26 import com.jme.scene.state.TextureState;\r
27 import com.jme.scene.state.ZBufferState;\r
28 import com.jme.util.TextureManager;\r
29 \r
30 import fi.vtt.simantics.processeditor.Activator;\r
31 import fi.vtt.simantics.processeditor.actions.PositionType;\r
32 \r
33 /**\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
37  * \r
38  * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>\r
39  *\r
40  */\r
41 public class PositionSelectionGizmo implements Gizmo {\r
42 \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
47 \r
48         private ThreeDimensionalEditorBase parent;\r
49         \r
50         private boolean changed = false;\r
51         private int selected = -1;\r
52         private boolean useDistanceResize = true;\r
53         \r
54         private List<BillboardNode> nodes;\r
55         private List<AlphaState> alphaStates;\r
56         private Node rootNode;\r
57         \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
64                 int i = 0;\r
65                 nodes = new ArrayList<BillboardNode>();\r
66                 alphaStates = new ArrayList<AlphaState>();\r
67                 // create a button (billboard) for each insertion position\r
68 \r
69                 ZBufferState zs = parent.getRenderingComponent().getDisplaySystem().getRenderer().createZBufferState();\r
70                 zs.setFunction(ZBufferState.CF_ALWAYS);\r
71                 \r
72                 for (Pair<Point3d, PositionType> p : positions) {\r
73                         BillboardNode node = new BillboardNode("");\r
74                         nodes.add(node);\r
75                         Quad quad = new Quad(PICK_PREFIX + i,1.f,1.f);\r
76                         \r
77                         TextureState ts = parent.getRenderingComponent().getDisplaySystem().getRenderer().createTextureState();\r
78                         String filename = "";\r
79                         switch (p.second) {\r
80                         case NEXT:\r
81                         case PREVIOUS:\r
82                                 filename = END_TEXTURE;\r
83                                 break;\r
84                         case SPLIT:\r
85                                 filename = SPLIT_TEXTURE;\r
86                                 break;\r
87                         case PORT:\r
88                                 filename = PORT_TEXTURE;\r
89                         }\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
97                         \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
105                         \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
111                         \r
112                         i++;\r
113                 }\r
114         }\r
115         \r
116         \r
117         @Override\r
118         public Node getNode() {\r
119                 return rootNode;\r
120         }\r
121         \r
122         @Override\r
123         public String getPickPrefix() {\r
124                 return PICK_PREFIX;\r
125         }\r
126         \r
127         @Override\r
128         public boolean isChanged() {\r
129                 return changed;\r
130         }\r
131         \r
132         @Override\r
133         public void setChanged(boolean b) {\r
134                 changed = b;\r
135         }\r
136         \r
137         @Override\r
138         public void setSelected(String name) {\r
139                 if (name == null) {\r
140                         setSelected(-1);\r
141                         return;\r
142                 }\r
143                 assert(name.startsWith(PICK_PREFIX));\r
144                 setSelected(Integer.parseInt(name.substring(PICK_PREFIX.length())));\r
145         }\r
146         \r
147         private void setSelected(int i) {\r
148                 if (selected == i)\r
149                         return;\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
153                 }\r
154                 selected = i;\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
158                 }\r
159                 parent.setViewChanged(true);\r
160         }\r
161         \r
162         public int getSelected() {\r
163                 return selected;\r
164         }\r
165         \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
172                         }\r
173                 }\r
174         }\r
175 \r
176         \r
177 }\r