]> gerrit.simantics Code Review - simantics/3d.git/blob
11197f46db86ada335c57fe32e691f40613cbee7
[simantics/3d.git] /
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
7  *\r
8  * Contributors:\r
9  *     VTT Technical Research Centre of Finland - initial API and implementation\r
10  *******************************************************************************/\r
11 package org.simantics.processeditor.gizmo;\r
12 \r
13 import java.net.URL;\r
14 import java.util.ArrayList;\r
15 import java.util.List;\r
16 \r
17 import javax.vecmath.Point3d;\r
18 \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
27 \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
41 \r
42 \r
43 /**\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
47  * \r
48  * @author Marko Luukkainen <Marko.Luukkainen@vtt.fi>\r
49  *\r
50  */\r
51 public class PositionSelectionGizmo implements Gizmo {\r
52 \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
57 \r
58         private ThreeDimensionalEditorBase parent;\r
59         \r
60         private boolean changed = false;\r
61         private int selected = -1;\r
62         private boolean useDistanceResize = true;\r
63         \r
64         private List<BillboardNode> nodes;\r
65         private List<AlphaState> alphaStates;\r
66         private Node rootNode;\r
67         \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
74                 int i = 0;\r
75                 nodes = new ArrayList<BillboardNode>();\r
76                 alphaStates = new ArrayList<AlphaState>();\r
77                 // create a button (billboard) for each insertion position\r
78 \r
79                 ZBufferState zs = parent.getRenderingComponent().getDisplaySystem().getRenderer().createZBufferState();\r
80                 zs.setFunction(ZBufferState.CF_ALWAYS);\r
81                 \r
82                 for (Pair<Point3d, PositionType> p : positions) {\r
83                         BillboardNode node = new BillboardNode("");\r
84                         nodes.add(node);\r
85                         Quad quad = new Quad(PICK_PREFIX + i,1.f,1.f);\r
86                         \r
87                         TextureState ts = parent.getRenderingComponent().getDisplaySystem().getRenderer().createTextureState();\r
88                         String filename = "";\r
89                         switch (p.second) {\r
90                         case NEXT:\r
91                         case PREVIOUS:\r
92                                 filename = END_TEXTURE;\r
93                                 break;\r
94                         case SPLIT:\r
95                                 filename = SPLIT_TEXTURE;\r
96                                 break;\r
97                         case PORT:\r
98                                 filename = PORT_TEXTURE;\r
99                         }\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
107                         \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
115                         \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
121                         \r
122                         i++;\r
123                 }\r
124         }\r
125         \r
126         \r
127         @Override\r
128         public Node getNode() {\r
129                 return rootNode;\r
130         }\r
131         \r
132         @Override\r
133         public String getPickPrefix() {\r
134                 return PICK_PREFIX;\r
135         }\r
136         \r
137         @Override\r
138         public boolean isChanged() {\r
139                 return changed;\r
140         }\r
141         \r
142         @Override\r
143         public void setChanged(boolean b) {\r
144                 changed = b;\r
145         }\r
146         \r
147         @Override\r
148         public void setSelected(String name) {\r
149                 if (name == null) {\r
150                         setSelected(-1);\r
151                         return;\r
152                 }\r
153                 assert(name.startsWith(PICK_PREFIX));\r
154                 setSelected(Integer.parseInt(name.substring(PICK_PREFIX.length())));\r
155         }\r
156         \r
157         private void setSelected(int i) {\r
158                 if (selected == i)\r
159                         return;\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
163                 }\r
164                 selected = i;\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
168                 }\r
169                 parent.setViewChanged(true);\r
170         }\r
171         \r
172         public int getSelected() {\r
173                 return selected;\r
174         }\r
175         \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
182                         }\r
183                 }\r
184         }\r
185 \r
186         \r
187 }\r