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