]> gerrit.simantics Code Review - simantics/3d.git/blobdiff - org.simantics.g3d/src/org/simantics/proconf/g3d/base/AppearanceTools.java
git-svn-id: https://www.simantics.org/svn/simantics/3d/trunk@22280 ac1ea38d-2e2b...
[simantics/3d.git] / org.simantics.g3d / src / org / simantics / proconf / g3d / base / AppearanceTools.java
diff --git a/org.simantics.g3d/src/org/simantics/proconf/g3d/base/AppearanceTools.java b/org.simantics.g3d/src/org/simantics/proconf/g3d/base/AppearanceTools.java
new file mode 100644 (file)
index 0000000..6a1a930
--- /dev/null
@@ -0,0 +1,453 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007- VTT Technical Research Centre of Finland.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.proconf.g3d.base;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Iterator;\r
+import java.util.List;\r
+\r
+import org.eclipse.swt.graphics.Device;\r
+import org.simantics.layer0.utils.IEntity;\r
+import org.simantics.layer0.utils.StubLinkedList;\r
+import org.simantics.proconf.g3d.Resources;\r
+import org.simantics.proconf.g3d.stubs.Appearance;\r
+import org.simantics.proconf.g3d.stubs.Color;\r
+import org.simantics.proconf.g3d.stubs.ImageTexture;\r
+import org.simantics.proconf.g3d.stubs.Material;\r
+import org.simantics.proconf.g3d.stubs.MultiTexture;\r
+import org.simantics.proconf.g3d.stubs.MultiTextureMode;\r
+import org.simantics.proconf.g3d.stubs.Shader;\r
+import org.simantics.proconf.g3d.stubs.Texture;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+\r
+import com.jme.image.Image;\r
+import com.jme.renderer.ColorRGBA;\r
+import com.jme.renderer.Renderer;\r
+import com.jme.scene.Geometry;\r
+import com.jme.scene.state.AlphaState;\r
+import com.jme.scene.state.FragmentProgramState;\r
+import com.jme.scene.state.MaterialState;\r
+import com.jme.scene.state.RenderState;\r
+import com.jme.scene.state.TextureState;\r
+import com.jme.scene.state.VertexProgramState;\r
+\r
+\r
+public class AppearanceTools {\r
+       \r
+       \r
+    \r
+    \r
+    public static void setColor(Color color, org.eclipse.swt.graphics.Color c) {\r
+        color.setRed(new double[]{(double)c.getRed() / 255.0});\r
+        color.setGreen(new double[]{(double)c.getGreen() / 255.0});\r
+        color.setBlue(new double[]{(double)c.getBlue() / 255.0});\r
+    }\r
+    \r
+    public static org.eclipse.swt.graphics.Color getColor(Color color, Device device) {\r
+        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
+        return c;\r
+    }\r
+    \r
+    /**\r
+     * Returns collection of renderstates that represent the given appearance.\r
+     * Note : if collection contains an alphastate, node must be inserted to transparent rendering queue.!\r
+     * @param appearance\r
+     * @param renderer\r
+     * @return\r
+     */\r
+    public static Collection<RenderState> getAppearance(Appearance appearance, Renderer renderer) {\r
+        Material m = appearance.getMaterial();\r
+        List <RenderState> states = new ArrayList<RenderState>();\r
+        if (m != null) {\r
+          states.addAll(getMaterial(m, renderer));\r
+        }\r
+        Texture t = appearance.getTexture();\r
+        if (t != null) {\r
+            if (t.isInstanceOf(Resources.g3dResource.ImageTexture)) {\r
+                states.addAll(getPatternTexture(t, renderer));\r
+            } else if (t.isInstanceOf(Resources.g3dResource.Texture3D)) {\r
+                ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);\r
+            } else if (t.isInstanceOf(Resources.g3dResource.MultiTexture)) {\r
+                states.addAll(getMultiTexture(t, renderer));\r
+            } else if (t.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {\r
+               ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);    \r
+            } else {\r
+                throw new UnsupportedOperationException("Unsupported texture");\r
+            }\r
+        }\r
+        Shader s =  appearance.getShader();\r
+        if (s != null) {\r
+            states.addAll(getShader(s, renderer));\r
+        }\r
+        return states;\r
+        \r
+    }\r
+    \r
+    private static ColorRGBA getJMEColor(Color color) {\r
+       return new ColorRGBA((float)color.getRed()[0],(float)color.getGreen()[0],(float)color.getBlue()[0],0.f);\r
+    }\r
+    \r
+    private static ColorRGBA getJMEColor(Color color, float alpha) {\r
+       return new ColorRGBA((float)color.getRed()[0],(float)color.getGreen()[0],(float)color.getBlue()[0],alpha);\r
+    }\r
+    \r
+    private static Collection<RenderState> getMaterial(Material m , Renderer renderer) {\r
+       float alpha = 0.f;\r
+       MaterialState ms = renderer.createMaterialState();\r
+       List<RenderState> states = new ArrayList<RenderState>();\r
+       if (m.getTransparency()[0] > 0.0) {\r
+               AlphaState as = renderer.createAlphaState();\r
+               as.setBlendEnabled(true);\r
+               as.setSrcFunction(AlphaState.DB_SRC_ALPHA);\r
+               as.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);\r
+               states.add(as);\r
+               alpha = 1.f - (float)m.getTransparency()[0];\r
+               //node.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);\r
+               ms.setMaterialFace(MaterialState.MF_FRONT_AND_BACK);\r
+        } else {\r
+               //node.setRenderQueueMode(Renderer.QUEUE_OPAQUE);\r
+        }\r
+       \r
+       ms.setEmissive(getJMEColor(m.getEmissiveColor()));\r
+        ms.setSpecular(getJMEColor(m.getSpecularColor()));\r
+        ms.setAmbient(getJMEColor(m.getAmbientColor()));\r
+        ms.setDiffuse(getJMEColor(m.getDiffuseColor(),alpha));\r
+        ms.setShininess((float) m.getShininess()[0]); \r
+        //node.setRenderState(ms);\r
+        states.add(ms);\r
+        return states; \r
+    }\r
+    \r
+    private static Collection<RenderState> getShader(Shader s , Renderer renderer) {\r
+       List<RenderState> states = new ArrayList<RenderState>();\r
+        VertexProgramState vs = renderer.createVertexProgramState();\r
+        vs.load(s.getVertexShader()[0]);\r
+        FragmentProgramState fs = renderer.createFragmentProgramState();\r
+        fs.load(s.getFragmentShader()[0]);\r
+        states.add(vs);\r
+        states.add(fs);\r
+        return states;\r
+    }\r
+    \r
+    private static Collection<RenderState> getPatternTexture(Texture t, Renderer renderer) {\r
+\r
+               List<RenderState> states = new ArrayList<RenderState>();\r
+               com.jme.image.Texture texture = ResourceTextureCache.getInstance().loadTexture(t.getGraph(), t.getResource());\r
+               if (texture == null)\r
+                       return states;\r
+               TextureState state = renderer.createTextureState();\r
+               state.setTexture(texture);\r
+               state.setEnabled(true);\r
+               states.add(state);\r
+               return states;\r
+       \r
+    }\r
+    \r
+    private static Image getPatternTexture(ImageTexture t) {\r
+       return ResourceTextureCache.getInstance().loadImage(t.getGraph(), t.getResource());\r
+    }\r
+    \r
+    \r
+    \r
+    \r
+    \r
+    private static Collection<RenderState> getMultiTexture(Texture t,  Renderer renderer) {\r
+       List<RenderState> states = new ArrayList<RenderState>();\r
+       TextureState state = renderer.createTextureState();\r
+        MultiTexture t3 = new MultiTexture(t); \r
+        Collection<IEntity> mtList = t3.getRelatedObjects(Resources.g3dResource.HasMultiTextureElementList);\r
+        assert (mtList.size() == 1); //this is required in the ontology!\r
+        StubLinkedList<IEntity> list = new StubLinkedList<IEntity>(mtList.iterator().next());\r
+        \r
+        for (int i = 0; i < list.size(); i++) {\r
+               IEntity ie = list.get(i);\r
+               //MultiTextureElement e = new MultiTextureElement(ie);\r
+               Texture tex = new Texture(ie); //e.getTexture();\r
+               MultiTextureMode mode = tex.getTextureMode();//e.getTextureMode();\r
+               com.jme.image.Texture texture = new com.jme.image.Texture();\r
+            texture.setFilter(com.jme.image.Texture.FM_LINEAR);\r
+            texture.setMipmapState(com.jme.image.Texture.MM_LINEAR_LINEAR);\r
+            texture.setWrap(com.jme.image.Texture.WM_WRAP_S_WRAP_T);\r
+            if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_add)) {\r
+               texture.setApply(com.jme.image.Texture.AM_ADD);\r
+            } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_modulate)) {\r
+               texture.setApply(com.jme.image.Texture.AM_MODULATE);\r
+            } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_decal)) {\r
+               texture.setApply(com.jme.image.Texture.AM_DECAL);\r
+            } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_blend)) {\r
+               texture.setApply(com.jme.image.Texture.AM_BLEND);\r
+            } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_replace)) {\r
+               texture.setApply(com.jme.image.Texture.AM_REPLACE);\r
+            } else if (mode.getResource().equals(Resources.g3dResource.MultiTextureMode_combine)) {\r
+               texture.setApply(com.jme.image.Texture.AM_COMBINE);\r
+                //CombineMode cm = e.getCombineMode();\r
+                //CombineSource cs = e.getCombineSource();\r
+               StubLinkedList<IEntity> combine = new StubLinkedList<IEntity>(tex.getCombineDefinition());\r
+                setCombineAttributes(texture, combine);\r
+                  \r
+                  \r
+                  \r
+                  //att.setBlendColor(blendColor)\r
+                  //att.setTexBlendColor(texBlendColor)\r
+                  //att.setTextureBlendColor(color)\r
+                  //att.setTextureTransform(transform)\r
+             } else {\r
+                  throw new UnsupportedOperationException("Texture mode not supported");\r
+             }\r
+              \r
+              \r
+              if (tex.isInstanceOf(Resources.g3dResource.MultiTexture)) {\r
+                  ErrorLogger.defaultLogError("MultiTexture contains another MultiTexture which is not allowed", null);\r
+                  continue;\r
+              } else if (tex.isInstanceOf(Resources.g3dResource.ImageTexture)) {\r
+                  Image image = getPatternTexture(new ImageTexture(tex));\r
+                  if (image != null)\r
+                       texture.setImage(image);\r
+  \r
+              } else if (tex.isInstanceOf(Resources.g3dResource.Texture3D)) {\r
+               ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);\r
+  \r
+              } else if (tex.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {\r
+               ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);    \r
+  \r
+              } else {\r
+                  throw new UnsupportedOperationException("Unsupported texture");\r
+              }\r
+\r
+              state.setTexture(texture, i);\r
+          }\r
+        states.add(state);\r
+        return states;\r
+               \r
+        //MultiTextureElementList texturesList = t3.getMultiTextureElementList();\r
+        //List<MultiTextureElement> textures = texturesList.toStandAloneList();\r
+        //ArrayList<TextureUnitState> states = new ArrayList<TextureUnitState>();\r
+       // for (MultiTextureElement e : textures) {\r
+       //     Texture tex = e.getTexture();\r
+           \r
+            //int index = e.getMultiTextureIndexValue();\r
+            //String mode = e.getMultiTextureModeValue();\r
+            \r
+       //     com.jme.image.Texture texture = new com.jme.image.Texture();\r
+       //     texture.setFilter(com.jme.image.Texture.FM_LINEAR);\r
+       //     texture.setMipmapState(com.jme.image.Texture.MM_LINEAR_LINEAR);\r
+       //     texture.setWrap(com.jme.image.Texture.WM_WRAP_S_WRAP_T);\r
+//            if (mode.startsWith(TEXTURE_MODE_MODULATE)) {\r
+//             texture.setApply(com.jme.image.Texture.AM_MODULATE);\r
+//            } else if (mode.startsWith(TEXTURE_MODE_DECAL)) {\r
+//             texture.setCombineFuncRGB(com.jme.image.Texture.AM_DECAL);\r
+//            } else if (mode.startsWith(TEXTURE_MODE_BLEND)) {\r
+//             texture.setCombineFuncRGB(com.jme.image.Texture.AM_MODULATE);\r
+//            } else if (mode.startsWith(TEXTURE_MODE_REPLACE)) {\r
+//             texture.setCombineFuncRGB(com.jme.image.Texture.AM_REPLACE);\r
+//            } else if (mode.startsWith(TEXTURE_MODE_COMBINE)) {\r
+//             texture.setCombineFuncRGB(com.jme.image.Texture.AM_COMBINE);\r
+//                \r
+//                mode = mode.substring(TEXTURE_MODE_COMBINE.length()+1); \r
+//                setCombineAttributes(texture, mode);\r
+                \r
+                \r
+                \r
+                //att.setBlendColor(blendColor)\r
+                //att.setTexBlendColor(texBlendColor)\r
+                //att.setTextureBlendColor(color)\r
+                //att.setTextureTransform(transform)\r
+//            } else {\r
+//                throw new UnsupportedOperationException("Texture mode not supported");\r
+//            }\r
+//            \r
+//            \r
+//            if (tex.isInstanceOf(Resources.g3dResource.MultiTexture)) {\r
+//                ErrorLogger.defaultLogError("MultiTexture contains another MultiTexture which is not allowed", null);\r
+//                continue;\r
+//            } else if (tex.isInstanceOf(Resources.g3dResource.ImageTexture)) {\r
+//                Image image = getPatternTexture(ImageTextureFactory.create(tex));\r
+//                if (image != null)\r
+//                     texture.setImage(image);\r
+//\r
+//            } else if (tex.isInstanceOf(Resources.g3dResource.Texture3D)) {\r
+//             ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);\r
+//\r
+//            } else if (tex.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {\r
+//             ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);    \r
+//\r
+//            } else {\r
+//                throw new UnsupportedOperationException("Unsupported texture");\r
+//            }\r
+            \r
+            //FIXME !\r
+            //state.setTexture(texture, index);\r
+      //  }\r
+      //  node.setRenderState(state);\r
+       \r
+        \r
+\r
+    }\r
+    \r
+    \r
+    private static void setCombineAttributes(com.jme.image.Texture texture, StubLinkedList<IEntity> definition) {\r
+       // TODO : rgb and alpha scale\r
+        Iterator<IEntity> it = definition.iterator();\r
+        IEntity mode = it.next();\r
+        if (mode.getResource().equals(Resources.g3dResource.CombineMode_add)) {\r
+            texture.setCombineFuncRGB(com.jme.image.Texture.ACF_ADD);\r
+        } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_addsigned)) {\r
+            texture.setCombineFuncRGB(com.jme.image.Texture.ACF_ADD_SIGNED);\r
+        } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_dot3)) {\r
+            texture.setCombineFuncRGB(com.jme.image.Texture.ACF_DOT3_RGB);\r
+        } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_interpolate)) {\r
+            texture.setCombineFuncRGB(com.jme.image.Texture.ACF_INTERPOLATE);\r
+        } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_modulate)) {\r
+            texture.setCombineFuncRGB(com.jme.image.Texture.ACF_MODULATE);\r
+        } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_replace)) {\r
+            texture.setCombineFuncRGB(com.jme.image.Texture.ACF_REPLACE);\r
+        } else if (mode.getResource().equals(Resources.g3dResource.CombineMode_subtract)) {\r
+            texture.setCombineFuncRGB(com.jme.image.Texture.ACF_SUBTRACT);\r
+        } else {\r
+            throw new UnsupportedOperationException("Unsupported combine mode");\r
+        }\r
+        mode = it.next();\r
+        int i = 0;\r
+        for (i = 0; i < 3; i++) {\r
+               int m;\r
+            if (mode.getResource().equals(Resources.g3dResource.CombineSource_constantcolor)) {\r
+                m = com.jme.image.Texture.ACS_CONSTANT;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_objectcolor)) {\r
+                m = com.jme.image.Texture.ACS_PRIMARY_COLOR;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_previousstate)) {\r
+                m = com.jme.image.Texture.ACS_TEXTURE;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texturecolor)) {\r
+                m = com.jme.image.Texture.ACS_TEXTURE;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture0)) {\r
+                m = com.jme.image.Texture.ACS_TEXTURE;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture1)) {\r
+                m = com.jme.image.Texture.ACS_TEXTURE;\r
+            } else {\r
+                break;\r
+                //throw new UnsupportedOperationException("Texture combine source not supported");\r
+            }\r
+            mode = it.next();\r
+            switch (i) {\r
+               case 0:\r
+                       texture.setCombineSrc0RGB(m);\r
+                       break;\r
+               case 1:\r
+                       texture.setCombineSrc1RGB(m);\r
+                       break;\r
+               case 2:\r
+                       texture.setCombineSrc2RGB(m);\r
+                       break;\r
+                       \r
+            }\r
+        }\r
+        if (i > 0) {\r
+            for (i = 0; i < 3; i++) {\r
+               int m;\r
+                if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srccolor)) {\r
+                    m = com.jme.image.Texture.ACO_SRC_COLOR;\r
+                } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srcalpha)) {\r
+                    m = com.jme.image.Texture.ACO_SRC_ALPHA;\r
+                } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrccolor)) {\r
+                    m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_COLOR;\r
+                } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrcalpha)) {\r
+                    m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_ALPHA;\r
+                } else {\r
+                    break;\r
+                }\r
+                mode = it.next();\r
+                switch (i) {\r
+               case 0:\r
+                       texture.setCombineOp0RGB(m);\r
+                       break;\r
+               case 1:\r
+                       texture.setCombineOp1RGB(m);\r
+                       break;\r
+               case 2:\r
+                       texture.setCombineOp2RGB(m);\r
+                       break;\r
+                       \r
+                }\r
+            }\r
+        }\r
+        \r
+        for (i = 0; i < 3; i++) {\r
+               int m;\r
+               if (mode.getResource().equals(Resources.g3dResource.CombineSource_constantcolor)) {\r
+                m = com.jme.image.Texture.ACS_CONSTANT;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_objectcolor)) {\r
+                m = com.jme.image.Texture.ACS_PRIMARY_COLOR;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_previousstate)) {\r
+                m = com.jme.image.Texture.ACS_TEXTURE;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texturecolor)) {\r
+                m = com.jme.image.Texture.ACS_TEXTURE;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture0)) {\r
+                m = com.jme.image.Texture.ACS_TEXTURE;\r
+            } else if (mode.getResource().equals(Resources.g3dResource.CombineSource_texture1)) {\r
+                m = com.jme.image.Texture.ACS_TEXTURE;\r
+            } else {\r
+                break;\r
+                //throw new UnsupportedOperationException("Texture combine source not supported");\r
+            }\r
+            mode = it.next();\r
+            switch (i) {\r
+               case 0:\r
+                       texture.setCombineSrc0Alpha(m);\r
+                       break;\r
+               case 1:\r
+                       texture.setCombineSrc1Alpha(m);\r
+                       break;\r
+               case 2:\r
+                       texture.setCombineSrc2Alpha(m);\r
+                       break;\r
+                       \r
+            }\r
+        }\r
+        if (i > 0) {\r
+            for (i = 0; i < 3; i++) {\r
+               int m;\r
+               if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srccolor)) {\r
+                    m = com.jme.image.Texture.ACO_SRC_COLOR;\r
+                } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_srcalpha)) {\r
+                    m = com.jme.image.Texture.ACO_SRC_ALPHA;\r
+                } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrccolor)) {\r
+                    m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_COLOR;\r
+                } else if (mode.getResource().equals(Resources.g3dResource.CombineFunction_oneminussrcalpha)) {\r
+                    m = com.jme.image.Texture.ACO_ONE_MINUS_SRC_ALPHA;\r
+                } else {\r
+                    break;\r
+                }\r
+                mode = it.next();\r
+                switch (i) {\r
+               case 0:\r
+                       texture.setCombineOp0Alpha(m);\r
+                       break;\r
+               case 1:\r
+                       texture.setCombineOp1Alpha(m);\r
+                       break;\r
+               case 2:\r
+                       texture.setCombineOp2Alpha(m);\r
+                       break;\r
+                       \r
+                }\r
+            }\r
+        }\r
+    }\r
+    \r
+    public static void copyMaterial(Geometry from, Geometry to) {\r
+       for (int i = RenderState.RS_ALPHA; i < RenderState.RS_MAX_STATE; i++) {\r
+               RenderState rs = from.getRenderState(i);\r
+               if (rs != null)\r
+                       to.setRenderState(rs);\r
+       }\r
+       \r
+    }\r
+}\r