]> gerrit.simantics Code Review - simantics/3d.git/blob - org.simantics.proconf.g3d/src/org/simantics/proconf/g3d/base/AppearanceTools.java
6a1a9307e2d67ccdda7e6ce2ede26c897c2c285f
[simantics/3d.git] / org.simantics.proconf.g3d / src / org / simantics / proconf / g3d / base / AppearanceTools.java
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.proconf.g3d.base;\r
12 \r
13 import java.util.ArrayList;\r
14 import java.util.Collection;\r
15 import java.util.Iterator;\r
16 import java.util.List;\r
17 \r
18 import org.eclipse.swt.graphics.Device;\r
19 import org.simantics.layer0.utils.IEntity;\r
20 import org.simantics.layer0.utils.StubLinkedList;\r
21 import org.simantics.proconf.g3d.Resources;\r
22 import org.simantics.proconf.g3d.stubs.Appearance;\r
23 import org.simantics.proconf.g3d.stubs.Color;\r
24 import org.simantics.proconf.g3d.stubs.ImageTexture;\r
25 import org.simantics.proconf.g3d.stubs.Material;\r
26 import org.simantics.proconf.g3d.stubs.MultiTexture;\r
27 import org.simantics.proconf.g3d.stubs.MultiTextureMode;\r
28 import org.simantics.proconf.g3d.stubs.Shader;\r
29 import org.simantics.proconf.g3d.stubs.Texture;\r
30 import org.simantics.utils.ui.ErrorLogger;\r
31 \r
32 import com.jme.image.Image;\r
33 import com.jme.renderer.ColorRGBA;\r
34 import com.jme.renderer.Renderer;\r
35 import com.jme.scene.Geometry;\r
36 import com.jme.scene.state.AlphaState;\r
37 import com.jme.scene.state.FragmentProgramState;\r
38 import com.jme.scene.state.MaterialState;\r
39 import com.jme.scene.state.RenderState;\r
40 import com.jme.scene.state.TextureState;\r
41 import com.jme.scene.state.VertexProgramState;\r
42 \r
43 \r
44 public class AppearanceTools {\r
45         \r
46         \r
47     \r
48     \r
49     public static void setColor(Color color, org.eclipse.swt.graphics.Color c) {\r
50         color.setRed(new double[]{(double)c.getRed() / 255.0});\r
51         color.setGreen(new double[]{(double)c.getGreen() / 255.0});\r
52         color.setBlue(new double[]{(double)c.getBlue() / 255.0});\r
53     }\r
54     \r
55     public static org.eclipse.swt.graphics.Color getColor(Color color, Device device) {\r
56         org.eclipse.swt.graphics.Color c = new org.eclipse.swt.graphics.Color(device, (int)(color.getRed()[0] * 255.0), (int)(color.getGreen()[0] * 255.0),(int)(color.getBlue()[0] * 255.0));\r
57         return c;\r
58     }\r
59     \r
60     /**\r
61      * Returns collection of renderstates that represent the given appearance.\r
62      * Note : if collection contains an alphastate, node must be inserted to transparent rendering queue.!\r
63      * @param appearance\r
64      * @param renderer\r
65      * @return\r
66      */\r
67     public static Collection<RenderState> getAppearance(Appearance appearance, Renderer renderer) {\r
68         Material m = appearance.getMaterial();\r
69         List <RenderState> states = new ArrayList<RenderState>();\r
70         if (m != null) {\r
71           states.addAll(getMaterial(m, renderer));\r
72         }\r
73         Texture t = appearance.getTexture();\r
74         if (t != null) {\r
75             if (t.isInstanceOf(Resources.g3dResource.ImageTexture)) {\r
76                 states.addAll(getPatternTexture(t, renderer));\r
77             } else if (t.isInstanceOf(Resources.g3dResource.Texture3D)) {\r
78                 ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);\r
79             } else if (t.isInstanceOf(Resources.g3dResource.MultiTexture)) {\r
80                 states.addAll(getMultiTexture(t, renderer));\r
81             } else if (t.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {\r
82                 ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);    \r
83             } else {\r
84                 throw new UnsupportedOperationException("Unsupported texture");\r
85             }\r
86         }\r
87         Shader s =  appearance.getShader();\r
88         if (s != null) {\r
89             states.addAll(getShader(s, renderer));\r
90         }\r
91         return states;\r
92         \r
93     }\r
94     \r
95     private static ColorRGBA getJMEColor(Color color) {\r
96         return new ColorRGBA((float)color.getRed()[0],(float)color.getGreen()[0],(float)color.getBlue()[0],0.f);\r
97     }\r
98     \r
99     private static ColorRGBA getJMEColor(Color color, float alpha) {\r
100         return new ColorRGBA((float)color.getRed()[0],(float)color.getGreen()[0],(float)color.getBlue()[0],alpha);\r
101     }\r
102     \r
103     private static Collection<RenderState> getMaterial(Material m , Renderer renderer) {\r
104         float alpha = 0.f;\r
105         MaterialState ms = renderer.createMaterialState();\r
106         List<RenderState> states = new ArrayList<RenderState>();\r
107         if (m.getTransparency()[0] > 0.0) {\r
108                 AlphaState as = renderer.createAlphaState();\r
109                 as.setBlendEnabled(true);\r
110                 as.setSrcFunction(AlphaState.DB_SRC_ALPHA);\r
111                 as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);\r
112                 states.add(as);\r
113                 alpha = 1.f - (float)m.getTransparency()[0];\r
114                 //node.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);\r
115                 ms.setMaterialFace(MaterialState.MF_FRONT_AND_BACK);\r
116         } else {\r
117                 //node.setRenderQueueMode(Renderer.QUEUE_OPAQUE);\r
118         }\r
119         \r
120         ms.setEmissive(getJMEColor(m.getEmissiveColor()));\r
121         ms.setSpecular(getJMEColor(m.getSpecularColor()));\r
122         ms.setAmbient(getJMEColor(m.getAmbientColor()));\r
123         ms.setDiffuse(getJMEColor(m.getDiffuseColor(),alpha));\r
124         ms.setShininess((float) m.getShininess()[0]); \r
125         //node.setRenderState(ms);\r
126         states.add(ms);\r
127         return states; \r
128     }\r
129     \r
130     private static Collection<RenderState> getShader(Shader s , Renderer renderer) {\r
131         List<RenderState> states = new ArrayList<RenderState>();\r
132         VertexProgramState vs = renderer.createVertexProgramState();\r
133         vs.load(s.getVertexShader()[0]);\r
134         FragmentProgramState fs = renderer.createFragmentProgramState();\r
135         fs.load(s.getFragmentShader()[0]);\r
136         states.add(vs);\r
137         states.add(fs);\r
138         return states;\r
139     }\r
140     \r
141     private static Collection<RenderState> getPatternTexture(Texture t, Renderer renderer) {\r
142 \r
143                 List<RenderState> states = new ArrayList<RenderState>();\r
144                 com.jme.image.Texture texture = ResourceTextureCache.getInstance().loadTexture(t.getGraph(), t.getResource());\r
145                 if (texture == null)\r
146                         return states;\r
147                 TextureState state = renderer.createTextureState();\r
148                 state.setTexture(texture);\r
149                 state.setEnabled(true);\r
150                 states.add(state);\r
151                 return states;\r
152         \r
153     }\r
154     \r
155     private static Image getPatternTexture(ImageTexture t) {\r
156         return ResourceTextureCache.getInstance().loadImage(t.getGraph(), t.getResource());\r
157     }\r
158     \r
159     \r
160     \r
161     \r
162     \r
163     private static Collection<RenderState> getMultiTexture(Texture t,  Renderer renderer) {\r
164         List<RenderState> states = new ArrayList<RenderState>();\r
165         TextureState state = renderer.createTextureState();\r
166         MultiTexture t3 = new MultiTexture(t); \r
167         Collection<IEntity> mtList = t3.getRelatedObjects(Resources.g3dResource.HasMultiTextureElementList);\r
168         assert (mtList.size() == 1); //this is required in the ontology!\r
169         StubLinkedList<IEntity> list = new StubLinkedList<IEntity>(mtList.iterator().next());\r
170         \r
171         for (int i = 0; i < list.size(); i++) {\r
172                 IEntity ie = list.get(i);\r
173                 //MultiTextureElement e = new MultiTextureElement(ie);\r
174                 Texture tex = new Texture(ie); //e.getTexture();\r
175                 MultiTextureMode mode = tex.getTextureMode();//e.getTextureMode();\r
176                 com.jme.image.Texture texture = new com.jme.image.Texture();\r
177             texture.setFilter(com.jme.image.Texture.FM_LINEAR);\r
178             texture.setMipmapState(com.jme.image.Texture.MM_LINEAR_LINEAR);\r
179             texture.setWrap(com.jme.image.Texture.WM_WRAP_S_WRAP_T);\r
180             if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_add)) {\r
181                 texture.setApply(com.jme.image.Texture.AM_ADD);\r
182             } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_modulate)) {\r
183                 texture.setApply(com.jme.image.Texture.AM_MODULATE);\r
184             } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_decal)) {\r
185                 texture.setApply(com.jme.image.Texture.AM_DECAL);\r
186             } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_blend)) {\r
187                 texture.setApply(com.jme.image.Texture.AM_BLEND);\r
188             } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_replace)) {\r
189                 texture.setApply(com.jme.image.Texture.AM_REPLACE);\r
190             } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_combine)) {\r
191                 texture.setApply(com.jme.image.Texture.AM_COMBINE);\r
192                 //CombineMode cm = e.getCombineMode();\r
193                 //CombineSource cs = e.getCombineSource();\r
194                 StubLinkedList<IEntity> combine = new StubLinkedList<IEntity>(tex.getCombineDefinition());\r
195                 setCombineAttributes(texture, combine);\r
196                   \r
197                   \r
198                   \r
199                   //att.setBlendColor(blendColor)\r
200                   //att.setTexBlendColor(texBlendColor)\r
201                   //att.setTextureBlendColor(color)\r
202                   //att.setTextureTransform(transform)\r
203              } else {\r
204                   throw new UnsupportedOperationException("Texture mode not supported");\r
205              }\r
206               \r
207               \r
208               if (tex.isInstanceOf(Resources.g3dResource.MultiTexture)) {\r
209                   ErrorLogger.defaultLogError("MultiTexture contains another MultiTexture which is not allowed", null);\r
210                   continue;\r
211               } else if (tex.isInstanceOf(Resources.g3dResource.ImageTexture)) {\r
212                   Image image = getPatternTexture(new ImageTexture(tex));\r
213                   if (image != null)\r
214                         texture.setImage(image);\r
215   \r
216               } else if (tex.isInstanceOf(Resources.g3dResource.Texture3D)) {\r
217                 ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);\r
218   \r
219               } else if (tex.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {\r
220                 ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);    \r
221   \r
222               } else {\r
223                   throw new UnsupportedOperationException("Unsupported texture");\r
224               }\r
225 \r
226               state.setTexture(texture, i);\r
227           }\r
228         states.add(state);\r
229         return states;\r
230                 \r
231         //MultiTextureElementList texturesList = t3.getMultiTextureElementList();\r
232         //List<MultiTextureElement> textures = texturesList.toStandAloneList();\r
233         //ArrayList<TextureUnitState> states = new ArrayList<TextureUnitState>();\r
234        // for (MultiTextureElement e : textures) {\r
235        //     Texture tex = e.getTexture();\r
236            \r
237             //int index = e.getMultiTextureIndexValue();\r
238             //String mode = e.getMultiTextureModeValue();\r
239             \r
240        //     com.jme.image.Texture texture = new com.jme.image.Texture();\r
241        //     texture.setFilter(com.jme.image.Texture.FM_LINEAR);\r
242        //     texture.setMipmapState(com.jme.image.Texture.MM_LINEAR_LINEAR);\r
243        //     texture.setWrap(com.jme.image.Texture.WM_WRAP_S_WRAP_T);\r
244 //            if (mode.startsWith(TEXTURE_MODE_MODULATE)) {\r
245 //              texture.setApply(com.jme.image.Texture.AM_MODULATE);\r
246 //            } else if (mode.startsWith(TEXTURE_MODE_DECAL)) {\r
247 //              texture.setCombineFuncRGB(com.jme.image.Texture.AM_DECAL);\r
248 //            } else if (mode.startsWith(TEXTURE_MODE_BLEND)) {\r
249 //              texture.setCombineFuncRGB(com.jme.image.Texture.AM_MODULATE);\r
250 //            } else if (mode.startsWith(TEXTURE_MODE_REPLACE)) {\r
251 //              texture.setCombineFuncRGB(com.jme.image.Texture.AM_REPLACE);\r
252 //            } else if (mode.startsWith(TEXTURE_MODE_COMBINE)) {\r
253 //              texture.setCombineFuncRGB(com.jme.image.Texture.AM_COMBINE);\r
254 //                \r
255 //                mode = mode.substring(TEXTURE_MODE_COMBINE.length()+1); \r
256 //                setCombineAttributes(texture, mode);\r
257                 \r
258                 \r
259                 \r
260                 //att.setBlendColor(blendColor)\r
261                 //att.setTexBlendColor(texBlendColor)\r
262                 //att.setTextureBlendColor(color)\r
263                 //att.setTextureTransform(transform)\r
264 //            } else {\r
265 //                throw new UnsupportedOperationException("Texture mode not supported");\r
266 //            }\r
267 //            \r
268 //            \r
269 //            if (tex.isInstanceOf(Resources.g3dResource.MultiTexture)) {\r
270 //                ErrorLogger.defaultLogError("MultiTexture contains another MultiTexture which is not allowed", null);\r
271 //                continue;\r
272 //            } else if (tex.isInstanceOf(Resources.g3dResource.ImageTexture)) {\r
273 //                Image image = getPatternTexture(ImageTextureFactory.create(tex));\r
274 //                if (image != null)\r
275 //                      texture.setImage(image);\r
276 //\r
277 //            } else if (tex.isInstanceOf(Resources.g3dResource.Texture3D)) {\r
278 //              ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);\r
279 //\r
280 //            } else if (tex.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {\r
281 //              ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);    \r
282 //\r
283 //            } else {\r
284 //                throw new UnsupportedOperationException("Unsupported texture");\r
285 //            }\r
286             \r
287             //FIXME !\r
288             //state.setTexture(texture, index);\r
289       //  }\r
290       //  node.setRenderState(state);\r
291        \r
292         \r
293 \r
294     }\r
295     \r
296     \r
297     private static void setCombineAttributes(com.jme.image.Texture texture, StubLinkedList<IEntity> definition) {\r
298         // TODO : rgb and alpha scale\r
299         Iterator<IEntity> it = definition.iterator();\r
300         IEntity mode = it.next();\r
301         if (mode.getResource().equals(Resources.g3dResource.CombineMode_add)) {\r
302             texture.setCombineFuncRGB(com.jme.image.Texture.ACF_ADD);\r
303         } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_addsigned)) {\r
304             texture.setCombineFuncRGB(com.jme.image.Texture.ACF_ADD_SIGNED);\r
305         } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_dot3)) {\r
306             texture.setCombineFuncRGB(com.jme.image.Texture.ACF_DOT3_RGB);\r
307         } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_interpolate)) {\r
308             texture.setCombineFuncRGB(com.jme.image.Texture.ACF_INTERPOLATE);\r
309         } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_modulate)) {\r
310             texture.setCombineFuncRGB(com.jme.image.Texture.ACF_MODULATE);\r
311         } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_replace)) {\r
312             texture.setCombineFuncRGB(com.jme.image.Texture.ACF_REPLACE);\r
313         } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_subtract)) {\r
314             texture.setCombineFuncRGB(com.jme.image.Texture.ACF_SUBTRACT);\r
315         } else {\r
316             throw new UnsupportedOperationException("Unsupported combine mode");\r
317         }\r
318         mode = it.next();\r
319         int i = 0;\r
320         for (i = 0; i < 3; i++) {\r
321                 int m;\r
322             if (mode.getResource().equals(Resources.g3dResource.CombineSource_constantcolor)) {\r
323                 m = com.jme.image.Texture.ACS_CONSTANT;\r
324             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_objectcolor)) {\r
325                 m = com.jme.image.Texture.ACS_PRIMARY_COLOR;\r
326             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_previousstate)) {\r
327                 m = com.jme.image.Texture.ACS_TEXTURE;\r
328             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texturecolor)) {\r
329                 m = com.jme.image.Texture.ACS_TEXTURE;\r
330             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture0)) {\r
331                 m = com.jme.image.Texture.ACS_TEXTURE;\r
332             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture1)) {\r
333                 m = com.jme.image.Texture.ACS_TEXTURE;\r
334             } else {\r
335                 break;\r
336                 //throw new UnsupportedOperationException("Texture combine source not supported");\r
337             }\r
338             mode = it.next();\r
339             switch (i) {\r
340                 case 0:\r
341                         texture.setCombineSrc0RGB(m);\r
342                         break;\r
343                 case 1:\r
344                         texture.setCombineSrc1RGB(m);\r
345                         break;\r
346                 case 2:\r
347                         texture.setCombineSrc2RGB(m);\r
348                         break;\r
349                         \r
350             }\r
351         }\r
352         if (i > 0) {\r
353             for (i = 0; i < 3; i++) {\r
354                 int m;\r
355                 if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srccolor)) {\r
356                     m = com.jme.image.Texture.ACO_SRC_COLOR;\r
357                 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srcalpha)) {\r
358                     m = com.jme.image.Texture.ACO_SRC_ALPHA;\r
359                 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrccolor)) {\r
360                     m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_COLOR;\r
361                 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrcalpha)) {\r
362                     m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_ALPHA;\r
363                 } else {\r
364                     break;\r
365                 }\r
366                 mode = it.next();\r
367                 switch (i) {\r
368                 case 0:\r
369                         texture.setCombineOp0RGB(m);\r
370                         break;\r
371                 case 1:\r
372                         texture.setCombineOp1RGB(m);\r
373                         break;\r
374                 case 2:\r
375                         texture.setCombineOp2RGB(m);\r
376                         break;\r
377                         \r
378                 }\r
379             }\r
380         }\r
381         \r
382         for (i = 0; i < 3; i++) {\r
383                 int m;\r
384                 if (mode.getResource().equals(Resources.g3dResource.CombineSource_constantcolor)) {\r
385                 m = com.jme.image.Texture.ACS_CONSTANT;\r
386             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_objectcolor)) {\r
387                 m = com.jme.image.Texture.ACS_PRIMARY_COLOR;\r
388             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_previousstate)) {\r
389                 m = com.jme.image.Texture.ACS_TEXTURE;\r
390             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texturecolor)) {\r
391                 m = com.jme.image.Texture.ACS_TEXTURE;\r
392             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture0)) {\r
393                 m = com.jme.image.Texture.ACS_TEXTURE;\r
394             } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture1)) {\r
395                 m = com.jme.image.Texture.ACS_TEXTURE;\r
396             } else {\r
397                 break;\r
398                 //throw new UnsupportedOperationException("Texture combine source not supported");\r
399             }\r
400             mode = it.next();\r
401             switch (i) {\r
402                 case 0:\r
403                         texture.setCombineSrc0Alpha(m);\r
404                         break;\r
405                 case 1:\r
406                         texture.setCombineSrc1Alpha(m);\r
407                         break;\r
408                 case 2:\r
409                         texture.setCombineSrc2Alpha(m);\r
410                         break;\r
411                         \r
412             }\r
413         }\r
414         if (i > 0) {\r
415             for (i = 0; i < 3; i++) {\r
416                 int m;\r
417                 if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srccolor)) {\r
418                     m = com.jme.image.Texture.ACO_SRC_COLOR;\r
419                 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srcalpha)) {\r
420                     m = com.jme.image.Texture.ACO_SRC_ALPHA;\r
421                 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrccolor)) {\r
422                     m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_COLOR;\r
423                 } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrcalpha)) {\r
424                     m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_ALPHA;\r
425                 } else {\r
426                     break;\r
427                 }\r
428                 mode = it.next();\r
429                 switch (i) {\r
430                 case 0:\r
431                         texture.setCombineOp0Alpha(m);\r
432                         break;\r
433                 case 1:\r
434                         texture.setCombineOp1Alpha(m);\r
435                         break;\r
436                 case 2:\r
437                         texture.setCombineOp2Alpha(m);\r
438                         break;\r
439                         \r
440                 }\r
441             }\r
442         }\r
443     }\r
444     \r
445     public static void copyMaterial(Geometry from, Geometry to) {\r
446         for (int i = RenderState.RS_ALPHA; i < RenderState.RS_MAX_STATE; i++) {\r
447                 RenderState rs = from.getRenderState(i);\r
448                 if (rs != null)\r
449                         to.setRenderState(rs);\r
450         }\r
451         \r
452     }\r
453 }\r