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