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
9 * VTT Technical Research Centre of Finland - initial API and implementation
\r
10 *******************************************************************************/
\r
11 package org.simantics.proconf.g3d.base;
\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
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
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
45 public class AppearanceTools {
\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
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
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
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
72 states.addAll(getMaterial(m, renderer));
\r
74 Texture t = appearance.getTexture();
\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
85 throw new UnsupportedOperationException("Unsupported texture");
\r
88 Shader s = appearance.getShader();
\r
90 states.addAll(getShader(s, renderer));
\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
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
104 private static Collection<RenderState> getMaterial(Material m , Renderer renderer) {
\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
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
118 //node.setRenderQueueMode(Renderer.QUEUE_OPAQUE);
\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
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
142 private static Collection<RenderState> getPatternTexture(Texture t, Renderer renderer) {
\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
148 TextureState state = renderer.createTextureState();
\r
149 state.setTexture(texture);
\r
150 state.setEnabled(true);
\r
156 private static Image getPatternTexture(ImageTexture t) {
\r
157 return ResourceTextureCache.getInstance().loadImage(t.getGraph(), t.getResource());
\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
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
200 //att.setBlendColor(blendColor)
\r
201 //att.setTexBlendColor(texBlendColor)
\r
202 //att.setTextureBlendColor(color)
\r
203 //att.setTextureTransform(transform)
\r
205 throw new UnsupportedOperationException("Texture mode not supported");
\r
209 if (tex.isInstanceOf(Resources.g3dResource.MultiTexture)) {
\r
210 ErrorLogger.defaultLogError("MultiTexture contains another MultiTexture which is not allowed", null);
\r
212 } else if (tex.isInstanceOf(Resources.g3dResource.ImageTexture)) {
\r
213 Image image = getPatternTexture(new ImageTexture(tex));
\r
215 texture.setImage(image);
\r
217 } else if (tex.isInstanceOf(Resources.g3dResource.Texture3D)) {
\r
218 ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);
\r
220 } else if (tex.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {
\r
221 ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);
\r
224 throw new UnsupportedOperationException("Unsupported texture");
\r
227 state.setTexture(texture, i);
\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
238 //int index = e.getMultiTextureIndexValue();
\r
239 //String mode = e.getMultiTextureModeValue();
\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
256 // mode = mode.substring(TEXTURE_MODE_COMBINE.length()+1);
\r
257 // setCombineAttributes(texture, mode);
\r
261 //att.setBlendColor(blendColor)
\r
262 //att.setTexBlendColor(texBlendColor)
\r
263 //att.setTextureBlendColor(color)
\r
264 //att.setTextureTransform(transform)
\r
266 // throw new UnsupportedOperationException("Texture mode not supported");
\r
270 // if (tex.isInstanceOf(Resources.g3dResource.MultiTexture)) {
\r
271 // ErrorLogger.defaultLogError("MultiTexture contains another MultiTexture which is not allowed", null);
\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
278 // } else if (tex.isInstanceOf(Resources.g3dResource.Texture3D)) {
\r
279 // ErrorLogger.getDefault().logWarning("JME doesn't support volume textures!", null);
\r
281 // } else if (tex.isInstanceOf(Resources.g3dResource.CubeMapTexture)) {
\r
282 // ErrorLogger.getDefault().logWarning("JME doesn't support cubemap textures!", null);
\r
285 // throw new UnsupportedOperationException("Unsupported texture");
\r
289 //state.setTexture(texture, index);
\r
291 // node.setRenderState(state);
\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
317 throw new UnsupportedOperationException("Unsupported combine mode");
\r
321 for (i = 0; i < 3; i++) {
\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
337 //throw new UnsupportedOperationException("Texture combine source not supported");
\r
342 texture.setCombineSrc0RGB(m);
\r
345 texture.setCombineSrc1RGB(m);
\r
348 texture.setCombineSrc2RGB(m);
\r
354 for (i = 0; i < 3; i++) {
\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
370 texture.setCombineOp0RGB(m);
\r
373 texture.setCombineOp1RGB(m);
\r
376 texture.setCombineOp2RGB(m);
\r
383 for (i = 0; i < 3; i++) {
\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
399 //throw new UnsupportedOperationException("Texture combine source not supported");
\r
404 texture.setCombineSrc0Alpha(m);
\r
407 texture.setCombineSrc1Alpha(m);
\r
410 texture.setCombineSrc2Alpha(m);
\r
416 for (i = 0; i < 3; i++) {
\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
432 texture.setCombineOp0Alpha(m);
\r
435 texture.setCombineOp1Alpha(m);
\r
438 texture.setCombineOp2Alpha(m);
\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
450 to.setRenderState(rs);
\r