]> gerrit.simantics Code Review - simantics/3d.git/blob - dev/org.simantics.proconf.processeditor/src/fi/vtt/simantics/processeditor/monitors/BillboardMonitor.java
Release
[simantics/3d.git] / dev / org.simantics.proconf.processeditor / src / fi / vtt / simantics / processeditor / monitors / BillboardMonitor.java
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
7  *\r
8  * Contributors:\r
9  *     VTT Technical Research Centre of Finland - initial API and implementation\r
10  *******************************************************************************/\r
11 package fi.vtt.simantics.processeditor.monitors;\r
12 \r
13 import java.awt.Color;\r
14 import java.util.ArrayList;\r
15 \r
16 import javax.vecmath.Point3d;\r
17 import javax.vecmath.Vector3d;\r
18 \r
19 import org.simantics.db.Graph;\r
20 import org.simantics.proconf.g3d.base.G3DTools;\r
21 import org.simantics.proconf.g3d.base.ThreeDimensionalEditorBase;\r
22 import org.simantics.proconf.g3d.base.VecmathJmeTools;\r
23 import org.simantics.proconf.g3d.scenegraph.IGraphicsNode;\r
24 import org.simantics.proconf.g3d.stubs.G3DNode;\r
25 \r
26 import com.jme.image.Texture;\r
27 import com.jme.math.Vector3f;\r
28 import com.jme.renderer.ColorRGBA;\r
29 import com.jme.renderer.Renderer;\r
30 import com.jme.scene.BillboardNode;\r
31 import com.jme.scene.Node;\r
32 import com.jme.scene.shape.Quad;\r
33 import com.jme.scene.state.AlphaState;\r
34 import com.jme.scene.state.MaterialState;\r
35 import com.jme.scene.state.RenderState;\r
36 import com.jme.scene.state.TextureState;\r
37 import com.jme.scene.state.ZBufferState;\r
38 import com.jmex.awt.swingui.ImageGraphics;\r
39 \r
40 \r
41 import fi.vtt.simantics.processeditor.ProcessResource;\r
42 import fi.vtt.simantics.processeditor.stubs.InlineComponent;\r
43 \r
44 \r
45 \r
46 /**\r
47  * A monitor that uses billboard to show it's information. \r
48  * \r
49  * @author Marko Luukkainen\r
50  *\r
51  */\r
52 //TODO : should it be variable length / fixed length inline component instead of Straight\r
53 \r
54 public class BillboardMonitor implements Monitor{\r
55         private enum Type{POSITION,PIPE};\r
56         private Type type;\r
57         private ThreeDimensionalEditorBase editor; \r
58         private BillboardNode monitorNode = null;\r
59         private int monitorSize = 128;\r
60     private ImageGraphics graphics = ImageGraphics.createInstance(monitorSize, monitorSize, 0);\r
61     private Node currentParent = null;\r
62     private IGraphicsNode node = null;\r
63     private boolean useDistanceResize = true;\r
64     \r
65     Point3d start;\r
66     Point3d end;\r
67     Point3d middle;\r
68     \r
69     private MonitorTextProvider provider = new ObjectPropertyProvider();\r
70         \r
71     \r
72         public BillboardMonitor(ThreeDimensionalEditorBase editor) {\r
73                 this.editor = editor;\r
74                 monitorNode = new BillboardNode("");\r
75                 monitorNode.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);\r
76                 ZBufferState zs = editor.getRenderingComponent()\r
77                                 .getDisplaySystem().getRenderer().createZBufferState();\r
78                 zs.setEnabled(true);\r
79                 zs.setFunction(ZBufferState.CF_ALWAYS);\r
80                 monitorNode.setRenderState(zs);\r
81                 Quad quad = new Quad("");\r
82                 quad.initialize(3.f, 3.f);\r
83                 monitorNode.attachChild(quad);\r
84                 // SWTImageGraphics graphics =\r
85                 // SWTImageGraphics.createInstance(64,64, 0);\r
86 \r
87                 graphics.clearRect(0, 0, monitorSize, monitorSize);\r
88 \r
89                 // graphics.setFont(new Font("Arial",Font.PLAIN,30));\r
90                 // graphics.setColor(Display.getDefault().getSystemColor(SWT.COLOR_GREEN));\r
91                 graphics.setColor(new Color(0, 255, 0, 255));\r
92                 graphics.drawString("Monitor", 0, 32);\r
93                 \r
94                 TextureState ts = editor.getRenderingComponent().getDisplaySystem().getRenderer().createTextureState();\r
95                 Texture texture = new Texture();\r
96                 texture.setApply(Texture.AM_MODULATE);\r
97                 // texture.setBlendColor(new ColorRGBA(1, 1, 1, 1));\r
98                 texture.setFilter(Texture.MM_LINEAR);\r
99                 texture.setMipmapState(Texture.FM_LINEAR);\r
100                 texture.setImage(graphics.getImage());\r
101                 graphics.update();\r
102                 AlphaState as = editor.getRenderingComponent().getDisplaySystem()\r
103                                 .getRenderer().createAlphaState();\r
104                 as.setBlendEnabled(true);\r
105                 as.setSrcFunction(AlphaState.SB_SRC_ALPHA);\r
106                 as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);\r
107         as.setTestEnabled(true);\r
108         as.setTestFunction(AlphaState.TF_GREATER);\r
109                 ts.setTexture(texture);\r
110                 MaterialState ms = editor.getRenderingComponent().getDisplaySystem().getRenderer().createMaterialState();\r
111                 ms.setEmissive(new ColorRGBA(1.f, 1.f, 1.f, 0.f));\r
112                 monitorNode.setRenderState(ts);\r
113                 monitorNode.setRenderState(as);\r
114                 monitorNode.setRenderState(ms);\r
115                 graphics.drawLine(0, 33, monitorSize-1, 33);\r
116                 graphics.update();\r
117         }\r
118         \r
119         public boolean acceptNode(Graph graph, IGraphicsNode node) {\r
120                 Node selectedParent = node.getGroup();\r
121                 if (currentParent == null || !selectedParent.equals(currentParent)) {\r
122                         if (node.getG3DNode(graph).getLocalPosition() != null) {\r
123                                 return true;\r
124                         } else if (node.getG3DNode(graph).isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {\r
125                                 \r
126                                 return true;\r
127                         }\r
128                 }\r
129 \r
130                 return false;\r
131         }\r
132         \r
133         public void setNode(Graph graph, IGraphicsNode node) {\r
134                 G3DNode n = node.getG3DNode(graph);\r
135                 if (n.getLocalPosition() != null) {\r
136                         type = Type.POSITION;\r
137                         monitorNode.setLocalTranslation(new Vector3f(0.f,0.f,0.f));\r
138                 } else if (n.isInstanceOf(ProcessResource.plant3Dresource.VariableLengthInlineComponent)) {\r
139                         type = Type.PIPE;\r
140                         InlineComponent ic = new InlineComponent(n);\r
141                         start = G3DTools.getPoint(ic.getControlPoint().getPrevious().getLocalPosition());\r
142                         end = G3DTools.getPoint(ic.getControlPoint().getNext().getLocalPosition());\r
143                         Vector3d dir = new Vector3d(end);\r
144                         dir.sub(start);\r
145                         dir.scale(0.5);\r
146                         middle = new Point3d(start);\r
147                         middle.add(dir);\r
148                         monitorNode.setLocalTranslation(VecmathJmeTools.get(middle));\r
149                 } else {\r
150                         return;\r
151                 }\r
152                 Node selectedParent = node.getGroup();\r
153                 this.node = node;\r
154                 currentParent = selectedParent;\r
155                 monitorNode.removeFromParent();\r
156                 currentParent.attachChild(monitorNode);\r
157 \r
158                 provider.setSource(n);\r
159                 update(graph);\r
160         }\r
161         \r
162         public IGraphicsNode getNode() {\r
163                 return node;\r
164         }\r
165         \r
166         public void update() {\r
167                 if (useDistanceResize) {\r
168                         Vector3f v = VecmathJmeTools.get(editor.getCamera().getCameraPos());\r
169                         v.subtractLocal(monitorNode.getWorldTranslation());\r
170                         float length = v.length();\r
171                         monitorNode.setLocalScale(length * 0.06f);\r
172                 }\r
173         }\r
174         \r
175         \r
176         public void update(Graph graph) {\r
177                 ArrayList<String> titles = provider.getTexts(graph);\r
178                 graphics.clearRect(0, 0, monitorSize, monitorSize);\r
179                 int y = 16;\r
180                 for (String s : titles) {\r
181                         graphics.drawString(s, 0, y);\r
182                         y += 16;\r
183                 }\r
184 \r
185                 TextureState ts = (TextureState) monitorNode\r
186                                 .getRenderState(RenderState.RS_TEXTURE);\r
187                 ts.deleteAll(); // FIXME : texture won't be updated without this\r
188                 graphics.update();\r
189                 update();\r
190         }\r
191         \r
192         public void remove() {\r
193                 monitorNode.removeFromParent();\r
194                 node = null;\r
195         }\r
196 \r
197         /**\r
198          * if true, monitors size is independent of distance to camera. Else monitor's size changes when camera is moved.\r
199          * @return\r
200          */\r
201         public boolean isUseDistanceResize() {\r
202                 return useDistanceResize;\r
203         }\r
204 \r
205         public void setUseDistanceResize(boolean useDistanceResize) {\r
206                 this.useDistanceResize = useDistanceResize;\r
207                 if (!useDistanceResize) {\r
208                         monitorNode.setLocalScale(1.f);\r
209                 }\r
210         }\r
211         \r
212         public void setTextProvider(MonitorTextProvider provider) {\r
213                 this.provider = provider;\r
214         }\r
215 \r
216 }\r