소스 검색

Importing generated textures as 3D textures.
UV coordinates generator added (will handle different UV coordinates generation methods in the future).
MaterialHelper refactoring.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8039 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

Kae..pl 14 년 전
부모
커밋
d6574a8cc7
18개의 변경된 파일1104개의 추가작업 그리고 620개의 파일을 삭제
  1. 16 6
      engine/src/blender/com/jme3/asset/BlenderKey.java
  2. 26 0
      engine/src/blender/com/jme3/scene/plugins/blender/materials/IAlphaMask.java
  3. 113 0
      engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java
  4. 131 167
      engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java
  5. 15 60
      engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java
  6. 9 7
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGenerator.java
  7. 61 53
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorBlend.java
  8. 45 38
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorClouds.java
  9. 33 26
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorDistnoise.java
  10. 61 53
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMagic.java
  11. 33 25
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMarble.java
  12. 38 30
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMusgrave.java
  13. 32 25
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorNoise.java
  14. 48 40
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorStucci.java
  15. 72 65
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorVoronoi.java
  16. 29 20
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorWood.java
  17. 18 5
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java
  18. 324 0
      engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java

+ 16 - 6
engine/src/blender/com/jme3/asset/BlenderKey.java

@@ -78,10 +78,12 @@ public class BlenderKey extends ModelKey {
      * between the frames.
      * between the frames.
      */
      */
     protected int fps = DEFAULT_FPS;
     protected int fps = DEFAULT_FPS;
-    /** Width of generated textures (in pixels). Blender uses 140x140 by default. */
-    protected int generatedTextureWidth = 140;
-    /** Height of generated textures (in pixels). Blender uses 140x140 by default. */
-    protected int generatedTextureHeight = 140;
+    /** Width of generated textures (in pixels). */
+    protected int generatedTextureWidth = 20;
+    /** Height of generated textures (in pixels). */
+    protected int generatedTextureHeight = 20;
+    /** Depth of generated textures (in pixels). */
+    protected int generatedTextureDepth = 20;
     /**
     /**
      * This variable is a bitwise flag of FeatureToLoad interface values; By default everything is being loaded.
      * This variable is a bitwise flag of FeatureToLoad interface values; By default everything is being loaded.
      */
      */
@@ -228,7 +230,7 @@ public class BlenderKey extends ModelKey {
     }
     }
 
 
     /**
     /**
-     * This method sets the height of generated texture (in pixels). By default the value is 140 px.
+     * This method sets the height of generated texture (in pixels). By default the value is 20 px.
      * @param generatedTextureHeight
      * @param generatedTextureHeight
      *        the height of generated texture
      *        the height of generated texture
      */
      */
@@ -237,12 +239,20 @@ public class BlenderKey extends ModelKey {
     }
     }
 
 
     /**
     /**
-     * This method returns the height of generated texture (in pixels). By default the value is 140 px.
+     * This method returns the height of generated texture (in pixels). By default the value is 20 px.
      * @return the height of generated texture
      * @return the height of generated texture
      */
      */
     public int getGeneratedTextureHeight() {
     public int getGeneratedTextureHeight() {
         return generatedTextureHeight;
         return generatedTextureHeight;
     }
     }
+    
+    /**
+     * This method returns the depth of generated texture (in pixels). By default the value is 20 px.
+     * @return the depth of generated texture
+     */
+    public int getGeneratedTextureDepth() {
+        return generatedTextureDepth;
+    }
 
 
     /**
     /**
      * This method returns the face cull mode.
      * This method returns the face cull mode.

+ 26 - 0
engine/src/blender/com/jme3/scene/plugins/blender/materials/IAlphaMask.java

@@ -0,0 +1,26 @@
+package com.jme3.scene.plugins.blender.materials;
+
+/**
+ * An interface used in calculating alpha mask during particles' texture calculations.
+ * @author Marcin Roguski (Kaelthas)
+ */
+/*package*/ interface IAlphaMask {
+	/**
+	 * This method sets the size of the texture's image.
+	 * @param width
+	 *        the width of the image
+	 * @param height
+	 *        the height of the image
+	 */
+	void setImageSize(int width, int height);
+
+	/**
+	 * This method returns the alpha value for the specified texture position.
+	 * @param x
+	 *        the X coordinate of the texture position
+	 * @param y
+	 *        the Y coordinate of the texture position
+	 * @return the alpha value for the specified texture position
+	 */
+	byte getAlpha(float x, float y);
+}

+ 113 - 0
engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java

@@ -0,0 +1,113 @@
+package com.jme3.scene.plugins.blender.materials;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.jme3.scene.plugins.blender.DataRepository;
+import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
+import com.jme3.scene.plugins.blender.file.DynamicArray;
+import com.jme3.scene.plugins.blender.file.Pointer;
+import com.jme3.scene.plugins.blender.file.Structure;
+import com.jme3.scene.plugins.blender.textures.TextureHelper;
+import com.jme3.texture.Texture.Type;
+
+/*package*/final class MaterialContext {
+	private static final Logger LOGGER = Logger.getLogger(MaterialContext.class.getName());
+	
+	public final String name;
+	public final List<Structure> mTexs;
+	public final List<Structure> textures;
+	public final int texturesCount;
+	public final Type textureType;
+	public final int textureCoordinatesType;
+	
+	public final boolean shadeless;
+	public final boolean vertexColor;
+	public final boolean transparent;
+	public final boolean vtangent;
+	
+	@SuppressWarnings("unchecked")
+	public MaterialContext(Structure structure, DataRepository dataRepository) throws BlenderFileException {
+		name = structure.getName();
+		
+		int mode = ((Number) structure.getFieldValue("mode")).intValue();
+		shadeless = (mode & 0x4) != 0;
+		vertexColor = (mode & 0x80) != 0;
+		transparent = (mode & 0x10000) != 0;
+		vtangent = (mode & 0x4000000) != 0; // NOTE: Requires tangents
+		
+		mTexs = new ArrayList<Structure>();
+		textures = new ArrayList<Structure>();
+		DynamicArray<Pointer> mtexsArray = (DynamicArray<Pointer>) structure.getFieldValue("mtex");
+		int separatedTextures = ((Number) structure.getFieldValue("septex")).intValue();
+		Type firstTextureType = null;
+		int texco = -1;
+		for (int i = 0; i < mtexsArray.getTotalSize(); ++i) {
+			Pointer p = mtexsArray.get(i);
+			if (p.isNotNull() && (separatedTextures & 1 << i) == 0) {
+				Structure mtex = p.fetchData(dataRepository.getInputStream()).get(0);
+				
+				//the first texture determines the texture coordinates type
+				if(texco == -1) {
+					texco = ((Number) mtex.getFieldValue("texco")).intValue();
+				} else if(texco != ((Number) mtex.getFieldValue("texco")).intValue()) {
+					LOGGER.log(Level.WARNING, "The texture with index: {0} has different UV coordinates type than the first texture! This texture will NOT be loaded!", i+1);
+					continue;
+				}
+				
+				Pointer pTex = (Pointer) mtex.getFieldValue("tex");
+				if(pTex.isNotNull()) {
+					Structure tex = pTex.fetchData(dataRepository.getInputStream()).get(0);
+					int type = ((Number) tex.getFieldValue("type")).intValue();
+					Type textureType = this.getType(type);
+					if(textureType != null) {
+						if(firstTextureType == null) {
+							firstTextureType = textureType;
+							mTexs.add(mtex);
+							textures.add(tex);
+						} else if(firstTextureType == textureType) {
+							mTexs.add(mtex);
+							textures.add(tex);
+						} else {
+							LOGGER.log(Level.WARNING, "The texture with index: {0} is of different dimension than the first one! This texture will NOT be loaded!", i+1);
+						}
+					}
+				}
+			}
+		}
+		
+		this.texturesCount = mTexs.size();
+		this.textureCoordinatesType = texco;
+		this.textureType = firstTextureType;
+	}
+	
+	private Type getType(int texType) {
+		switch (texType) {
+			case TextureHelper.TEX_IMAGE:// (it is first because probably this will be most commonly used)
+				return Type.TwoDimensional;
+			case TextureHelper.TEX_CLOUDS:
+			case TextureHelper.TEX_WOOD:
+			case TextureHelper.TEX_MARBLE:
+			case TextureHelper.TEX_MAGIC:
+			case TextureHelper.TEX_BLEND:
+			case TextureHelper.TEX_STUCCI:
+			case TextureHelper.TEX_NOISE:
+			case TextureHelper.TEX_MUSGRAVE:
+			case TextureHelper.TEX_VORONOI:
+			case TextureHelper.TEX_DISTNOISE:
+				return Type.ThreeDimensional;
+			case TextureHelper.TEX_NONE:// No texture, do nothing
+				return null;
+			case TextureHelper.TEX_POINTDENSITY:
+            case TextureHelper.TEX_VOXELDATA:
+			case TextureHelper.TEX_PLUGIN:
+			case TextureHelper.TEX_ENVMAP:
+				LOGGER.log(Level.WARNING, "Texture type NOT supported: {0}", texType);
+				return null;
+			default:
+				throw new IllegalStateException("Unknown texture type: " + texType);
+		}
+	}
+}

+ 131 - 167
engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java

@@ -52,7 +52,6 @@ import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository.LoadedFeatureDataType;
 import com.jme3.scene.plugins.blender.DataRepository.LoadedFeatureDataType;
 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.DynamicArray;
 import com.jme3.scene.plugins.blender.file.Pointer;
 import com.jme3.scene.plugins.blender.file.Pointer;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper;
 import com.jme3.scene.plugins.blender.textures.TextureHelper;
@@ -61,6 +60,7 @@ import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture.MinFilter;
 import com.jme3.texture.Texture.MinFilter;
+import com.jme3.texture.Texture.Type;
 import com.jme3.texture.Texture.WrapMode;
 import com.jme3.texture.Texture.WrapMode;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
@@ -68,6 +68,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
 	private static final Logger					LOGGER					= Logger.getLogger(MaterialHelper.class.getName());
 	private static final Logger					LOGGER					= Logger.getLogger(MaterialHelper.class.getName());
 	protected static final float				DEFAULT_SHININESS		= 20.0f;
 	protected static final float				DEFAULT_SHININESS		= 20.0f;
 
 
+	public static final String					TEXTURE_TYPE_3D			= "Texture";
 	public static final String					TEXTURE_TYPE_COLOR		= "ColorMap";
 	public static final String					TEXTURE_TYPE_COLOR		= "ColorMap";
 	public static final String					TEXTURE_TYPE_DIFFUSE	= "DiffuseMap";
 	public static final String					TEXTURE_TYPE_DIFFUSE	= "DiffuseMap";
 	public static final String					TEXTURE_TYPE_NORMAL		= "NormalMap";
 	public static final String					TEXTURE_TYPE_NORMAL		= "NormalMap";
@@ -177,7 +178,6 @@ public class MaterialHelper extends AbstractBlenderHelper {
 		this.faceCullMode = faceCullMode;
 		this.faceCullMode = faceCullMode;
 	}
 	}
 
 
-	@SuppressWarnings("unchecked")
 	public Material toMaterial(Structure structure, DataRepository dataRepository) throws BlenderFileException {
 	public Material toMaterial(Structure structure, DataRepository dataRepository) throws BlenderFileException {
 		LOGGER.log(Level.INFO, "Loading material.");
 		LOGGER.log(Level.INFO, "Loading material.");
 		if (structure == null) {
 		if (structure == null) {
@@ -187,153 +187,139 @@ public class MaterialHelper extends AbstractBlenderHelper {
 		if (result != null) {
 		if (result != null) {
 			return result;
 			return result;
 		}
 		}
-
-		int mode = ((Number) structure.getFieldValue("mode")).intValue();
-		boolean shadeless = (mode & 0x4) != 0;
-		boolean vertexColor = (mode & 0x80) != 0;
-		boolean transparent = (mode & 0x10000) != 0;
-                boolean vtangent = (mode & 0x4000000) != 0; // NOTE: Requires tangents
-                
-		if (shadeless) {
-			result = new Material(dataRepository.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
-		} else {
-			result = new Material(dataRepository.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
-		}
-
-                //System.out.println("Mode: \n" +
-                //                   "Shadeless: " + shadeless + "\n" +
-                //                   "VColor: " + vertexColor + "\n" +
-                //                   "ZTrans: " + transparent + "\n" + 
-                //                   "VTangent: " + vtangent);
-                
-		result.getAdditionalRenderState().setFaceCullMode(faceCullMode);
-
-		if (transparent) {
-                        result.setTransparent(true);
-			result.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
-                }
-
-		String name = structure.getName();
-		LOGGER.log(Level.INFO, "Material's name: {0}", name);
-		if (vertexColor) {
-			result.setBoolean(shadeless ? "VertexColor" : "UseVertexColor", true);
-		}
-                
-		MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class);
-		ColorRGBA diffuseColor = null;
-		if (shadeless) {
-			// color of shadeless? doesn't seem to work in blender ..
-                        diffuseColor = ColorRGBA.White.clone();
-		} else {
-			result.setBoolean("UseMaterialColors", Boolean.TRUE);
-
-			// setting the colors
-			DiffuseShader diffuseShader = materialHelper.getDiffuseShader(structure);
-			result.setBoolean("Minnaert", diffuseShader == DiffuseShader.MINNAERT);
-			diffuseColor = materialHelper.getDiffuseColor(structure, diffuseShader);
-                        if (!transparent){
-                            diffuseColor.a = 1;
-                        }
-			result.setColor("Diffuse", diffuseColor);
-
-			SpecularShader specularShader = materialHelper.getSpecularShader(structure);
-			result.setBoolean("WardIso", specularShader == SpecularShader.WARDISO);
-			result.setColor("Specular", materialHelper.getSpecularColor(structure, specularShader));
-
-			result.setColor("Ambient", materialHelper.getAmbientColor(structure));
-			result.setFloat("Shininess", materialHelper.getShininess(structure));
-                        
-                        
-		}
+		
+		MaterialContext materialContext = new MaterialContext(structure, dataRepository);
+		LOGGER.log(Level.INFO, "Material's name: {0}", materialContext.name);
 
 
 		// texture
 		// texture
+		Map<String, Texture> texturesMap = new HashMap<String, Texture>();
+		Type firstTextureType = null;
 		if ((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0) {
 		if ((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0) {
 			TextureHelper textureHelper = dataRepository.getHelper(TextureHelper.class);
 			TextureHelper textureHelper = dataRepository.getHelper(TextureHelper.class);
-			DynamicArray<Pointer> mtexs = (DynamicArray<Pointer>) structure.getFieldValue("mtex");
-			int separatedTextures = ((Number)structure.getFieldValue("septex")).intValue();
-			for (int i = 0; i < mtexs.getTotalSize(); ++i) {
-				Pointer p = mtexs.get(i);
-				if (p.isNotNull() && (separatedTextures & (1 << i)) == 0) {
-					List<Structure> mtex = p.fetchData(dataRepository.getInputStream());
-					if (mtex.size() == 1) {
-						Structure textureLink = mtex.get(0);
-						int texflag = ((Number) textureLink.getFieldValue("texflag")).intValue();
-						// int texco = ((Number) textureLink.getFieldValue("texco")).intValue();
-						boolean negateTexture = (texflag & 0x04) == 0;
-
-						// if(texco == 0x10) {//TEXCO_UV (this is only supported now)
-						int mapto = ((Number) textureLink.getFieldValue("mapto")).intValue();
-						if (mapto != 0) {
-							Pointer pTex = (Pointer) textureLink.getFieldValue("tex");
-							Structure tex = pTex.fetchData(dataRepository.getInputStream()).get(0);
-							Texture texture = textureHelper.getTexture(tex, dataRepository);
-                                                        
-							if (texture != null) {
-                                // NOTE: Enable mipmaps FOR ALL TEXTURES EVER
-                                texture.setMinFilter(MinFilter.Trilinear);
-                                                            
-								if ((mapto & 0x01) != 0) {// Col
-                                    // Map to COLOR channel or DIFFUSE
-                                    // Set diffuse to white so it doesn't get multiplied by texture
-                                    diffuseColor.r = diffuseColor.g = diffuseColor.b = 1.0f;
-                                    result.setColor(shadeless ? "Color" : "Diffuse", diffuseColor);
-									//result.setBoolean("UseMaterialColors", Boolean.FALSE);
-									// blending the texture with material color and texture's defined color
-									int blendType = ((Number) textureLink.getFieldValue("blendtype")).intValue();
-									float[] color = new float[] { ((Number) textureLink.getFieldValue("r")).floatValue(), ((Number) textureLink.getFieldValue("g")).floatValue(), ((Number) textureLink.getFieldValue("b")).floatValue() };
-									float colfac = ((Number) textureLink.getFieldValue("colfac")).floatValue();
-									texture = textureHelper.blendTexture(diffuseColor.getColorArray(), texture, color, colfac, blendType, negateTexture, dataRepository);
-                                                                        texture.setMinFilter(MinFilter.Trilinear);
-                                                                        texture.setWrap(WrapMode.Repeat);
-									if (shadeless) {
-										result.setTexture(TEXTURE_TYPE_COLOR, texture);
-									} else {
-										result.setTexture(TEXTURE_TYPE_DIFFUSE, texture);
-									}
-								}
-								if ((mapto & 0x02) != 0 && !shadeless) {// Nor
-									Texture normalMapTexture;
-									if(texture.getKey() instanceof GeneratedTextureKey) {
-										normalMapTexture = textureHelper.convertToNormalMapTexture(texture, ((Number)textureLink.getFieldValue("norfac")).floatValue());
-                                                                                normalMapTexture.setMinFilter(MinFilter.Trilinear);
-                                                                        } else {
-										normalMapTexture = texture;
-									}
-                                                                        result.setTexture(TEXTURE_TYPE_NORMAL, normalMapTexture);
-									if (vertexColor) {
-										result.setBoolean(shadeless ? "VertexColor" : "UseVertexColor", false);
-									}
-								}
-								if ((mapto & 0x04) != 0 && !shadeless) {// Spec
-                                    // Map to SPECULAR 
-									result.setTexture(TEXTURE_TYPE_SPECULAR, texture);
-								}
-								if ((mapto & 0x40) != 0) {// Emit
-									result.setTexture(TEXTURE_TYPE_GLOW, texture);
-								}
-								if ((mapto & 0x80) != 0 && !shadeless) {// Alpha
-									result.setTexture(TEXTURE_TYPE_ALPHA, texture);
-								}
+			for (int i=0;i<materialContext.texturesCount;++i) {
+				Structure mtex = materialContext.mTexs.get(i);
+				
+				int texflag = ((Number) mtex.getFieldValue("texflag")).intValue();
+				boolean negateTexture = (texflag & 0x04) == 0;
+
+				int mapto = ((Number) mtex.getFieldValue("mapto")).intValue();
+				if (mapto != 0) {
+					Structure tex = materialContext.textures.get(i);
+					Texture texture = textureHelper.getTexture(tex, dataRepository);
+					if (texture != null) {
+						if(firstTextureType == null) {
+							firstTextureType = texture.getType();
+						} else if(firstTextureType != texture.getType()) {
+							LOGGER.warning("The texture with the name: " + texture.getName() + " is of different type than the first applied texture! It will not be applied!");
+							continue;
+						}
+
+						// NOTE: Enable mipmaps FOR ALL TEXTURES EVER
+						texture.setMinFilter(MinFilter.Trilinear);
+//TODO: textures merging
+						if ((mapto & 0x01) != 0) {// Col
+							// Map to COLOR channel or DIFFUSE
+							// Set diffuse to white so it doesn't get multiplied by texture
+							// result.setColor(shadeless ? "Color" : "Diffuse", ColorRGBA.White.clone());
+//							 result.setBoolean("UseMaterialColors", Boolean.FALSE);
+							// blending the texture with material color and texture's defined color
+							int blendType = ((Number) mtex.getFieldValue("blendtype")).intValue();
+							float[] color = new float[] { ((Number) mtex.getFieldValue("r")).floatValue(), ((Number) mtex.getFieldValue("g")).floatValue(), ((Number) mtex.getFieldValue("b")).floatValue() };
+							float colfac = ((Number) mtex.getFieldValue("colfac")).floatValue();
+							texture = textureHelper.blendTexture(new float[] {1, 1, 1}, texture, color, colfac, blendType, negateTexture, dataRepository);
+							texture.setWrap(WrapMode.Repeat);
+							
+							if (materialContext.shadeless) {
+								texturesMap.put(firstTextureType==Type.ThreeDimensional ? TEXTURE_TYPE_3D : TEXTURE_TYPE_COLOR, texture);
 							} else {
 							} else {
-								LOGGER.log(Level.WARNING, "Texture not found!");
+								texturesMap.put(firstTextureType==Type.ThreeDimensional ? TEXTURE_TYPE_3D : TEXTURE_TYPE_DIFFUSE, texture);
+							}
+						}
+						if(firstTextureType == Type.TwoDimensional) {//for now other mappings available for images only
+							if ((mapto & 0x02) != 0 && !materialContext.shadeless) {// Nor
+								Texture normalMapTexture;
+								if (texture.getKey() instanceof GeneratedTextureKey) {
+									normalMapTexture = textureHelper.convertToNormalMapTexture(texture, ((Number) mtex.getFieldValue("norfac")).floatValue());
+									normalMapTexture.setMinFilter(MinFilter.Trilinear);
+								} else {
+									normalMapTexture = texture;
+								}
+								texturesMap.put(TEXTURE_TYPE_NORMAL, normalMapTexture);
+							}
+							if ((mapto & 0x04) != 0 && !materialContext.shadeless) {// Spec
+								// Map to SPECULAR
+								texturesMap.put(TEXTURE_TYPE_SPECULAR, texture);
 							}
 							}
+							if ((mapto & 0x40) != 0) {// Emit
+								texturesMap.put(TEXTURE_TYPE_GLOW, texture);
+							}
+							if ((mapto & 0x80) != 0 && !materialContext.shadeless) {// Alpha
+								texturesMap.put(TEXTURE_TYPE_ALPHA, texture);
+							}
+						} else {
+							LOGGER.warning("The following mappings: [Nor, Spec, Alpha] are available for 2D textures only!");
 						}
 						}
-						// } else {
-						// Pointer pTex = (Pointer)textureLink.getFieldValue("tex");
-						// List<Structure> texs = pTex.fetchData(dataRepository.getInputStream());
-						// Structure tex = texs.get(0);
-						// LOGGER.log(Level.WARNING, "Unsupported texture type: " + texco);
-						// }
 					} else {
 					} else {
-						LOGGER.log(Level.WARNING, "Many textures. Not solved yet!");// TODO
+						LOGGER.log(Level.WARNING, "Texture not found!");
 					}
 					}
 				}
 				}
 			}
 			}
 		}
 		}
+		
+		//creating the material
+		if(firstTextureType==Type.ThreeDimensional) {
+			result = new Material(dataRepository.getAssetManager(), "jme3test/texture/tex3D.j3md");
+		} else {
+			if (materialContext.shadeless) {
+				result = new Material(dataRepository.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
+			} else {
+				result = new Material(dataRepository.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
+			}
+			
+			if (materialContext.vertexColor) {
+				result.setBoolean(materialContext.shadeless ? "VertexColor" : "UseVertexColor", true);
+			}
+			ColorRGBA diffuseColor = null;
+			if (materialContext.shadeless) {
+				// color of shadeless? doesn't seem to work in blender ..
+				diffuseColor = ColorRGBA.White.clone();
+			} else {
+				result.setBoolean("UseMaterialColors", Boolean.TRUE);
+
+				// setting the colors
+				DiffuseShader diffuseShader = this.getDiffuseShader(structure);
+				result.setBoolean("Minnaert", diffuseShader == DiffuseShader.MINNAERT);
+				diffuseColor = this.getDiffuseColor(structure, diffuseShader);
+				if (!materialContext.transparent) {
+					diffuseColor.a = 1;
+				}
+				result.setColor("Diffuse", diffuseColor);
+
+				SpecularShader specularShader = this.getSpecularShader(structure);
+				result.setBoolean("WardIso", specularShader == SpecularShader.WARDISO);
+				result.setColor("Specular", this.getSpecularColor(structure, specularShader));
+
+				result.setColor("Ambient", this.getAmbientColor(structure));
+				result.setFloat("Shininess", this.getShininess(structure));
+			}
+		}
+		
+		//applying textures
+		for(Entry<String, Texture> textureEntry : texturesMap.entrySet()) {
+			result.setTexture(textureEntry.getKey(), textureEntry.getValue());
+		}
+		
+		//applying other data
+		result.getAdditionalRenderState().setFaceCullMode(faceCullMode);
+		if (materialContext.transparent) {
+			result.setTransparent(true);
+			result.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
+		}
+		
 		dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, result);
 		dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, result);
 		return result;
 		return result;
 	}
 	}
-
+	
 	/**
 	/**
 	 * This method returns a material similar to the one given but without textures. If the material has no textures it is not cloned but
 	 * This method returns a material similar to the one given but without textures. If the material has no textures it is not cloned but
 	 * returned itself.
 	 * returned itself.
@@ -428,7 +414,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
 		}
 		}
 		return result;
 		return result;
 	}
 	}
-	
+
 	/**
 	/**
 	 * This method indicates if the material has any kind of texture.
 	 * This method indicates if the material has any kind of texture.
 	 * 
 	 * 
@@ -438,22 +424,25 @@ public class MaterialHelper extends AbstractBlenderHelper {
 	 */
 	 */
 	public boolean hasTexture(Material material) {
 	public boolean hasTexture(Material material) {
 		if (material != null) {
 		if (material != null) {
-			if(material.getTextureParam(TEXTURE_TYPE_ALPHA) != null) {
+			if (material.getTextureParam(TEXTURE_TYPE_3D) != null) {
+				return true;
+			}
+			if (material.getTextureParam(TEXTURE_TYPE_ALPHA) != null) {
 				return true;
 				return true;
 			}
 			}
-			if(material.getTextureParam(TEXTURE_TYPE_COLOR) != null) {
+			if (material.getTextureParam(TEXTURE_TYPE_COLOR) != null) {
 				return true;
 				return true;
 			}
 			}
-			if(material.getTextureParam(TEXTURE_TYPE_DIFFUSE) != null) {
+			if (material.getTextureParam(TEXTURE_TYPE_DIFFUSE) != null) {
 				return true;
 				return true;
 			}
 			}
-			if(material.getTextureParam(TEXTURE_TYPE_GLOW) != null) {
+			if (material.getTextureParam(TEXTURE_TYPE_GLOW) != null) {
 				return true;
 				return true;
 			}
 			}
-			if(material.getTextureParam(TEXTURE_TYPE_NORMAL) != null) {
+			if (material.getTextureParam(TEXTURE_TYPE_NORMAL) != null) {
 				return true;
 				return true;
 			}
 			}
-			if(material.getTextureParam(TEXTURE_TYPE_SPECULAR) != null) {
+			if (material.getTextureParam(TEXTURE_TYPE_SPECULAR) != null) {
 				return true;
 				return true;
 			}
 			}
 		}
 		}
@@ -475,7 +464,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
 		}
 		}
 		return false;
 		return false;
 	}
 	}
-	
+
 	/**
 	/**
 	 * This method returns the diffuse color
 	 * This method returns the diffuse color
 	 * 
 	 * 
@@ -743,29 +732,4 @@ public class MaterialHelper extends AbstractBlenderHelper {
 	public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) {
 	public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) {
 		return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0;
 		return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0;
 	}
 	}
-	
-	/**
-	 * An interface used in calculating alpha mask during particles' texture calculations.
-	 * @author Marcin Roguski (Kaelthas)
-	 */
-	protected static interface IAlphaMask {
-		/**
-		 * This method sets the size of the texture's image.
-		 * @param width
-		 *        the width of the image
-		 * @param height
-		 *        the height of the image
-		 */
-		void setImageSize(int width, int height);
-
-		/**
-		 * This method returns the alpha value for the specified texture position.
-		 * @param x
-		 *        the X coordinate of the texture position
-		 * @param y
-		 *        the Y coordinate of the texture position
-		 * @return the alpha value for the specified texture position
-		 */
-		byte getAlpha(float x, float y);
-	}
 }
 }

+ 15 - 60
engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java

@@ -44,10 +44,8 @@ import com.jme3.asset.BlenderKey.FeaturesToLoad;
 import com.jme3.bounding.BoundingBox;
 import com.jme3.bounding.BoundingBox;
 import com.jme3.bounding.BoundingSphere;
 import com.jme3.bounding.BoundingSphere;
 import com.jme3.bounding.BoundingVolume;
 import com.jme3.bounding.BoundingVolume;
-import com.jme3.collision.CollisionResults;
 import com.jme3.material.Material;
 import com.jme3.material.Material;
 import com.jme3.math.FastMath;
 import com.jme3.math.FastMath;
-import com.jme3.math.Ray;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector2f;
 import com.jme3.math.Vector3f;
 import com.jme3.math.Vector3f;
 import com.jme3.renderer.queue.RenderQueue.Bucket;
 import com.jme3.renderer.queue.RenderQueue.Bucket;
@@ -68,6 +66,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.materials.MaterialHelper;
 import com.jme3.scene.plugins.blender.materials.MaterialHelper;
 import com.jme3.scene.plugins.blender.objects.Properties;
 import com.jme3.scene.plugins.blender.objects.Properties;
 import com.jme3.scene.plugins.blender.textures.TextureHelper;
 import com.jme3.scene.plugins.blender.textures.TextureHelper;
+import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
@@ -127,10 +126,13 @@ public class MeshHelper extends AbstractBlenderHelper {
 		// the following map sorts faces by material number (because in jme Mesh can have only one material)
 		// the following map sorts faces by material number (because in jme Mesh can have only one material)
 		Map<Integer, List<Integer>> meshesMap = new HashMap<Integer, List<Integer>>();
 		Map<Integer, List<Integer>> meshesMap = new HashMap<Integer, List<Integer>>();
 		Pointer pMFace = (Pointer) structure.getFieldValue("mface");
 		Pointer pMFace = (Pointer) structure.getFieldValue("mface");
-                List<Structure> mFaces = null;
-                if (pMFace.isNotNull()){
-                    mFaces = pMFace.fetchData(dataRepository.getInputStream());
-                }
+        List<Structure> mFaces = null;
+        if (pMFace.isNotNull()){
+            mFaces = pMFace.fetchData(dataRepository.getInputStream());
+            if(mFaces==null || mFaces.size()==0) {
+            	return new ArrayList<Geometry>(0);
+            }
+        }
 
 
 		Pointer pMTFace = (Pointer) structure.getFieldValue("mtface");
 		Pointer pMTFace = (Pointer) structure.getFieldValue("mtface");
 		List<Vector2f> uvCoordinates = null;
 		List<Vector2f> uvCoordinates = null;
@@ -142,7 +144,7 @@ public class MeshHelper extends AbstractBlenderHelper {
 			if (mtFaces.size() != facesAmount) {
 			if (mtFaces.size() != facesAmount) {
 				throw new BlenderFileException("The amount of faces uv coordinates is not equal to faces amount!");
 				throw new BlenderFileException("The amount of faces uv coordinates is not equal to faces amount!");
 			}
 			}
-			uvCoordinates = new ArrayList<Vector2f>();// TODO: calculate the amount of coordinates if possible
+			uvCoordinates = new ArrayList<Vector2f>();
 		}
 		}
 
 
 		// normalMap merges normals of faces that will be rendered smooth
 		// normalMap merges normals of faces that will be rendered smooth
@@ -156,9 +158,6 @@ public class MeshHelper extends AbstractBlenderHelper {
 		// positions (it simply tells which vertex is referenced where in the result list)
 		// positions (it simply tells which vertex is referenced where in the result list)
 		Map<Integer, List<Integer>> vertexReferenceMap = new HashMap<Integer, List<Integer>>(verticesAmount);
 		Map<Integer, List<Integer>> vertexReferenceMap = new HashMap<Integer, List<Integer>>(verticesAmount);
 		int vertexColorIndex = 0;
 		int vertexColorIndex = 0;
-                if (mFaces == null){
-                    return null;
-                }
 		for (int i = 0; i < mFaces.size(); ++i) {
 		for (int i = 0; i < mFaces.size(); ++i) {
 			Structure mFace = mFaces.get(i);
 			Structure mFace = mFaces.get(i);
 			boolean smooth = (((Number) mFace.getFieldValue("flag")).byteValue() & 0x01) != 0x00;
 			boolean smooth = (((Number) mFace.getFieldValue("flag")).byteValue() & 0x01) != 0x00;
@@ -392,54 +391,9 @@ public class MeshHelper extends AbstractBlenderHelper {
 			for(Geometry geom : geometries) {
 			for(Geometry geom : geometries) {
 				geom.getMesh().setBuffer(uvCoordsBuffer);
 				geom.getMesh().setBuffer(uvCoordsBuffer);
 			}
 			}
-		} else {
-			Vector2f[] uvTable = new Vector2f[vertexList.size()];
-			Ray ray = new Ray();
-			CollisionResults cr = new CollisionResults();
-			Vector3f yVec = new Vector3f();
-			Vector3f zVec = new Vector3f();
-			for(Geometry geom : geometries) {
-				if(materialHelper.hasTexture(geom.getMaterial())) {//generate only when material has a texture
-					geom.getMesh().updateBound();
-					BoundingSphere bs = this.getBoundingSphere(geom.getMesh());
-					float r2 = bs.getRadius() * bs.getRadius();
-					yVec.set(0, -bs.getRadius(), 0);
-					zVec.set(0, 0, -bs.getRadius());
-					Vector3f center = bs.getCenter();
-					ray.setOrigin(center);
-					//we cast each vertex of the current mesh on the bounding box to determine the UV-coordinates
-					for(int i=0;i<geom.getMesh().getIndexBuffer().size();++i) {
-						int index = geom.getMesh().getIndexBuffer().get(i);
-						
-						ray.setOrigin(vertexList.get(index));
-						ray.setDirection(normalList.get(index));
-						
-						//finding collision point
-						cr.clear();
-						bs.collideWith(ray, cr);//there is ALWAYS one collision
-						Vector3f p = cr.getCollision(0).getContactPoint();
-						p.subtractLocal(center);
-						//arcLength = FastMath.acos(p.dot(yVec)/(p.length * yVec.length)) * r    <- an arc length on the sphere (from top to the point on the sphere)
-						//but yVec.length == r and p.length == r    so: arcLength = FastMath.acos(p.dot(yVec)/r^2)/r
-						//U coordinate is as follows: u = arcLength / PI*r
-						//so to compute it faster we just write: u = FastMath.acos(p.dot(yVec)/r^2) / PI;
-						float u = FastMath.acos(p.dot(yVec)/r2) / FastMath.PI;
-						//we use similiar method to compute v
-						//the only difference is that we need to cast the p vector on ZX plane
-						//and use its length instead of r
-						p.y = 0;
-						float v = FastMath.acos(p.dot(zVec)/(bs.getRadius()*p.length())) / FastMath.PI;
-						uvTable[index] = new Vector2f(u, v);
-					}
-				}
-			}
-			
-			//creating and applying the buffer
-			uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
-			uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvTable));
-			for(Geometry geom : geometries) {
-				geom.getMesh().setBuffer(uvCoordsBuffer);
-			}
+		} else {//TODO: get the proper texture coordinates type
+			UVCoordinatesGenerator.generateUVCoordinates(UVCoordinatesGenerator.TEXCO_ORCO, 
+					com.jme3.texture.Texture.Type.ThreeDimensional, geometries);
 		}
 		}
 		
 		
 		dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
 		dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
@@ -550,8 +504,9 @@ public class MeshHelper extends AbstractBlenderHelper {
 	public Vector3f[] getVertices(Structure meshStructure, DataRepository dataRepository) throws BlenderFileException {
 	public Vector3f[] getVertices(Structure meshStructure, DataRepository dataRepository) throws BlenderFileException {
 		int verticesAmount = ((Number) meshStructure.getFieldValue("totvert")).intValue();
 		int verticesAmount = ((Number) meshStructure.getFieldValue("totvert")).intValue();
 		Vector3f[] vertices = new Vector3f[verticesAmount];
 		Vector3f[] vertices = new Vector3f[verticesAmount];
-                if (verticesAmount == 0)
-                    return vertices;
+                if (verticesAmount == 0) {
+					return vertices;
+				}
                 
                 
 		Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
 		Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
 		List<Structure> mVerts = pMVert.fetchData(dataRepository.getInputStream());
 		List<Structure> mVerts = pMVert.fetchData(dataRepository.getInputStream());

+ 9 - 7
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGenerator.java

@@ -14,14 +14,14 @@ import com.jme3.texture.Texture;
  * @author Marcin Roguski (Kaelthas)
  * @author Marcin Roguski (Kaelthas)
  */
  */
 /* package */abstract class TextureGenerator {
 /* package */abstract class TextureGenerator {
-	private static final Logger LOGGER = Logger.getLogger(TextureGenerator.class.getName());
-	
-	protected NoiseGenerator noiseGenerator;
-	
+	private static final Logger	LOGGER	= Logger.getLogger(TextureGenerator.class.getName());
+
+	protected NoiseGenerator	noiseGenerator;
+
 	public TextureGenerator(NoiseGenerator noiseGenerator) {
 	public TextureGenerator(NoiseGenerator noiseGenerator) {
 		this.noiseGenerator = noiseGenerator;
 		this.noiseGenerator = noiseGenerator;
 	}
 	}
-	
+
 	/**
 	/**
 	 * This method generates the texture.
 	 * This method generates the texture.
 	 * @param tex
 	 * @param tex
@@ -30,12 +30,14 @@ import com.jme3.texture.Texture;
 	 *        the width of the result texture
 	 *        the width of the result texture
 	 * @param height
 	 * @param height
 	 *        the height of the result texture
 	 *        the height of the result texture
+	 * @param depth
+	 *        the depth of the texture
 	 * @param dataRepository
 	 * @param dataRepository
 	 *        the data repository
 	 *        the data repository
 	 * @return newly generated texture
 	 * @return newly generated texture
 	 */
 	 */
-	protected abstract Texture generate(Structure tex, int width, int height, DataRepository dataRepository);
-	
+	protected abstract Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository);
+
 	/**
 	/**
 	 * This method reads the colorband data from the given texture structure.
 	 * This method reads the colorband data from the given texture structure.
 	 * 
 	 * 

+ 61 - 53
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorBlend.java

@@ -1,6 +1,7 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.math.FastMath;
 import com.jme3.math.FastMath;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
@@ -8,9 +9,9 @@ import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -21,85 +22,92 @@ public final class TextureGeneratorBlend extends TextureGenerator {
 
 
 	/**
 	/**
 	 * Constructor stores the given noise generator.
 	 * Constructor stores the given noise generator.
-	 * @param noiseGenerator the noise generator
+	 * @param noiseGenerator
+	 *        the noise generator
 	 */
 	 */
 	public TextureGeneratorBlend(NoiseGenerator noiseGenerator) {
 	public TextureGeneratorBlend(NoiseGenerator noiseGenerator) {
 		super(noiseGenerator);
 		super(noiseGenerator);
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		int flag = ((Number) tex.getFieldValue("flag")).intValue();
 		int flag = ((Number) tex.getFieldValue("flag")).intValue();
 		int stype = ((Number) tex.getFieldValue("stype")).intValue();
 		int stype = ((Number) tex.getFieldValue("stype")).intValue();
 		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
 		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
 		float brightness = ((Number) tex.getFieldValue("bright")).floatValue();
 		float brightness = ((Number) tex.getFieldValue("bright")).floatValue();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, x, y, t;
+		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth, x, y, t;
 		float[] texvec = new float[] { 0, 0, 0 };
 		float[] texvec = new float[] { 0, 0, 0 };
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
-		int halfW = width, halfH = height;
+		int halfW = width, halfH = height, halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i;
 			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j;
 				texvec[1] = hDelta * j;
-				if ((flag & NoiseGenerator.TEX_FLIPBLEND) != 0) {
-					x = texvec[1];
-					y = texvec[0];
-				} else {
-					x = texvec[0];
-					y = texvec[1];
-				}
-
-				if (stype == NoiseGenerator.TEX_LIN) { /* lin */
-					texres.tin = (1.0f + x) / 2.0f;
-				} else if (stype == NoiseGenerator.TEX_QUAD) { /* quad */
-					texres.tin = (1.0f + x) / 2.0f;
-					if (texres.tin < 0.0f) {
-						texres.tin = 0.0f;
+				for (int k = -halfD; k < halfD; ++k) {
+					texvec[2] = dDelta * k;
+					if ((flag & NoiseGenerator.TEX_FLIPBLEND) != 0) {
+						x = texvec[1];
+						y = texvec[0];
 					} else {
 					} else {
-						texres.tin *= texres.tin;
+						x = texvec[0];
+						y = texvec[1];
 					}
 					}
-				} else if (stype == NoiseGenerator.TEX_EASE) { /* ease */
-					texres.tin = (1.0f + x) / 2.0f;
-					if (texres.tin <= 0.0f) {
-						texres.tin = 0.0f;
-					} else if (texres.tin >= 1.0f) {
-						texres.tin = 1.0f;
-					} else {
-						t = texres.tin * texres.tin;
-						texres.tin = 3.0f * t - 2.0f * t * texres.tin;
+
+					if (stype == NoiseGenerator.TEX_LIN) { /* lin */
+						texres.tin = (1.0f + x) / 2.0f;
+					} else if (stype == NoiseGenerator.TEX_QUAD) { /* quad */
+						texres.tin = (1.0f + x) / 2.0f;
+						if (texres.tin < 0.0f) {
+							texres.tin = 0.0f;
+						} else {
+							texres.tin *= texres.tin;
+						}
+					} else if (stype == NoiseGenerator.TEX_EASE) { /* ease */
+						texres.tin = (1.0f + x) / 2.0f;
+						if (texres.tin <= 0.0f) {
+							texres.tin = 0.0f;
+						} else if (texres.tin >= 1.0f) {
+							texres.tin = 1.0f;
+						} else {
+							t = texres.tin * texres.tin;
+							texres.tin = 3.0f * t - 2.0f * t * texres.tin;
+						}
+					} else if (stype == NoiseGenerator.TEX_DIAG) { /* diag */
+						texres.tin = (2.0f + x + y) / 4.0f;
+					} else if (stype == NoiseGenerator.TEX_RAD) { /* radial */
+						texres.tin = (float) Math.atan2(y, x) / FastMath.TWO_PI + 0.5f;
+					} else { /* sphere TEX_SPHERE */
+						texres.tin = 1.0f - (float) Math.sqrt(x * x + y * y + texvec[2] * texvec[2]);
+						if (texres.tin < 0.0f) {
+							texres.tin = 0.0f;
+						}
+						if (stype == NoiseGenerator.TEX_HALO) {
+							texres.tin *= texres.tin;
+						} /* halo */
 					}
 					}
-				} else if (stype == NoiseGenerator.TEX_DIAG) { /* diag */
-					texres.tin = (2.0f + x + y) / 4.0f;
-				} else if (stype == NoiseGenerator.TEX_RAD) { /* radial */
-					texres.tin = (float) Math.atan2(y, x) / FastMath.TWO_PI + 0.5f;
-				} else { /* sphere TEX_SPHERE */
-					texres.tin = 1.0f - (float) Math.sqrt(x * x + y * y + texvec[2] * texvec[2]);
-					if (texres.tin < 0.0f) {
-						texres.tin = 0.0f;
+					if (colorBand != null) {
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+						noiseGenerator.brightnesAndContrastRGB(tex, texres);
+						data.put((byte) (texres.tr * 255.0f));
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else {
+						noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
+						data.put((byte) (texres.tin * 255.0f));
 					}
 					}
-					if (stype == NoiseGenerator.TEX_HALO) {
-						texres.tin *= texres.tin;
-					} /* halo */
-				}
-				if (colorBand != null) {
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-					noiseGenerator.brightnesAndContrastRGB(tex, texres);
-					data.put((byte) (texres.tr * 255.0f));
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else {
-					noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
-					data.put((byte) (texres.tin * 255.0f));
 				}
 				}
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(format, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 45 - 38
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorClouds.java

@@ -1,15 +1,16 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -20,16 +21,17 @@ public class TextureGeneratorClouds extends TextureGenerator {
 
 
 	/**
 	/**
 	 * Constructor stores the given noise generator.
 	 * Constructor stores the given noise generator.
-	 * @param noiseGenerator the noise generator
+	 * @param noiseGenerator
+	 *        the noise generator
 	 */
 	 */
 	public TextureGeneratorClouds(NoiseGenerator noiseGenerator) {
 	public TextureGeneratorClouds(NoiseGenerator noiseGenerator) {
 		super(noiseGenerator);
 		super(noiseGenerator);
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		// preparing the proper data
 		// preparing the proper data
-		float wDelta = 1.0f / width, hDelta = 1.0f / height;
+		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
 		float[] texvec = new float[] { 0, 0, 0 };
 		float[] texvec = new float[] { 0, 0, 0 };
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
 
 
@@ -42,50 +44,55 @@ public class TextureGeneratorClouds extends TextureGenerator {
 		float bright = ((Number) tex.getFieldValue("bright")).floatValue();
 		float bright = ((Number) tex.getFieldValue("bright")).floatValue();
 		boolean isHard = noiseType != NoiseGenerator.TEX_NOISESOFT;
 		boolean isHard = noiseType != NoiseGenerator.TEX_NOISESOFT;
 		int sType = ((Number) tex.getFieldValue("stype")).intValue();
 		int sType = ((Number) tex.getFieldValue("stype")).intValue();
-		int halfW = width, halfH = height;
+		int halfW = width, halfH = height, halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		Format format = sType == NoiseGenerator.TEX_COLOR || colorBand != null ? Format.RGB8 : Format.Luminance8;
 		Format format = sType == NoiseGenerator.TEX_COLOR || colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = sType == NoiseGenerator.TEX_COLOR || colorBand != null ? 3 : 1;
 		int bytesPerPixel = sType == NoiseGenerator.TEX_COLOR || colorBand != null ? 3 : 1;
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
-			texvec[0] = wDelta * i;// x
+			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
-				texvec[1] = hDelta * j;// y (z is always = 0)
-
-				texres.tin = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2], noiseDepth, isHard, noiseBasis);
-				if (colorBand != null) {
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-					if (texres.nor != null) {
-						float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
-						// calculate bumpnormal
-						texres.nor[0] = noiseGenerator.bliGTurbulence(noisesize, texvec[0] + nabla, texvec[1], texvec[2], noiseDepth, isHard, noiseBasis);
-						texres.nor[1] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1] + nabla, texvec[2], noiseDepth, isHard, noiseBasis);
-						texres.nor[2] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2] + nabla, noiseDepth, isHard, noiseBasis);
-						noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+				texvec[1] = hDelta * j;
+				for (int k = -halfD; k < halfD; ++k) {
+					texvec[2] = dDelta * k;
+					texres.tin = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2], noiseDepth, isHard, noiseBasis);
+					if (colorBand != null) {
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+						if (texres.nor != null) {
+							float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
+							// calculate bumpnormal
+							texres.nor[0] = noiseGenerator.bliGTurbulence(noisesize, texvec[0] + nabla, texvec[1], texvec[2], noiseDepth, isHard, noiseBasis);
+							texres.nor[1] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1] + nabla, texvec[2], noiseDepth, isHard, noiseBasis);
+							texres.nor[2] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2] + nabla, noiseDepth, isHard, noiseBasis);
+							noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+						}
+						noiseGenerator.brightnesAndContrastRGB(tex, texres);
+						data.put((byte) (texres.tr * 255.0f));
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else if (sType == NoiseGenerator.TEX_COLOR) {
+						// in this case, int. value should really be computed from color,
+						// and bumpnormal from that, would be too slow, looks ok as is
+						texres.tr = texres.tin;
+						texres.tg = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[0], texvec[2], noiseDepth, isHard, noiseBasis);
+						texres.tb = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[2], texvec[0], noiseDepth, isHard, noiseBasis);
+						noiseGenerator.brightnesAndContrastRGB(tex, texres);
+						data.put((byte) (texres.tr * 255.0f));
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else {
+						noiseGenerator.brightnesAndContrast(texres, contrast, bright);
+						data.put((byte) (texres.tin * 255));
 					}
 					}
-					noiseGenerator.brightnesAndContrastRGB(tex, texres);
-					data.put((byte) (texres.tr * 255.0f));
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else if (sType == NoiseGenerator.TEX_COLOR) {
-					// in this case, int. value should really be computed from color,
-					// and bumpnormal from that, would be too slow, looks ok as is
-					texres.tr = texres.tin;
-					texres.tg = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[0], texvec[2], noiseDepth, isHard, noiseBasis);
-					texres.tb = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[2], texvec[0], noiseDepth, isHard, noiseBasis);
-					noiseGenerator.brightnesAndContrastRGB(tex, texres);
-					data.put((byte) (texres.tr * 255.0f));
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else {
-					noiseGenerator.brightnesAndContrast(texres, contrast, bright);
-					data.put((byte) (texres.tin * 255));
 				}
 				}
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(format, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 33 - 26
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorDistnoise.java

@@ -1,15 +1,16 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -20,14 +21,15 @@ public class TextureGeneratorDistnoise extends TextureGenerator {
 
 
 	/**
 	/**
 	 * Constructor stores the given noise generator.
 	 * Constructor stores the given noise generator.
-	 * @param noiseGenerator the noise generator
+	 * @param noiseGenerator
+	 *        the noise generator
 	 */
 	 */
 	public TextureGeneratorDistnoise(NoiseGenerator noiseGenerator) {
 	public TextureGeneratorDistnoise(NoiseGenerator noiseGenerator) {
 		super(noiseGenerator);
 		super(noiseGenerator);
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
 		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
 		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
 		float distAmount = ((Number) tex.getFieldValue("dist_amount")).floatValue();
 		float distAmount = ((Number) tex.getFieldValue("dist_amount")).floatValue();
@@ -38,42 +40,47 @@ public class TextureGeneratorDistnoise extends TextureGenerator {
 
 
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
 		float[] texvec = new float[] { 0, 0, 0 };
 		float[] texvec = new float[] { 0, 0, 0 };
-		float wDelta = 1.0f / width, hDelta = 1.0f / height;
-		int halfW = width, halfH = height;
+		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
+		int halfW = width, halfH = height, halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i / noisesize;
 			texvec[0] = wDelta * i / noisesize;
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j / noisesize;
 				texvec[1] = hDelta * j / noisesize;
+				for (int k = -halfD; k < halfD; ++k) {
+					texvec[2] = dDelta * k;// z
+					texres.tin = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2], distAmount, noisebasis, noisebasis2);
+					if (colorBand != null) {
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+						if (texres.nor != null) {
+							float offs = nabla / noisesize; // also scaling of texvec
+							/* calculate bumpnormal */
+							texres.nor[0] = noiseGenerator.mgVLNoise(texvec[0] + offs, texvec[1], texvec[2], distAmount, noisebasis, noisebasis2);
+							texres.nor[1] = noiseGenerator.mgVLNoise(texvec[0], texvec[1] + offs, texvec[2], distAmount, noisebasis, noisebasis2);
+							texres.nor[2] = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2] + offs, distAmount, noisebasis, noisebasis2);
+							noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+						}
 
 
-				texres.tin = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2], distAmount, noisebasis, noisebasis2);
-				if (colorBand != null) {
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-					if (texres.nor != null) {
-						float offs = nabla / noisesize; // also scaling of texvec
-						/* calculate bumpnormal */
-						texres.nor[0] = noiseGenerator.mgVLNoise(texvec[0] + offs, texvec[1], texvec[2], distAmount, noisebasis, noisebasis2);
-						texres.nor[1] = noiseGenerator.mgVLNoise(texvec[0], texvec[1] + offs, texvec[2], distAmount, noisebasis, noisebasis2);
-						texres.nor[2] = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2] + offs, distAmount, noisebasis, noisebasis2);
-						noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+						noiseGenerator.brightnesAndContrastRGB(tex, texres);
+						data.put((byte) (texres.tr * 255.0f));
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else {
+						noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
+						data.put((byte) (texres.tin * 255.0f));
 					}
 					}
-
-					noiseGenerator.brightnesAndContrastRGB(tex, texres);
-					data.put((byte) (texres.tr * 255.0f));
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else {
-					noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
-					data.put((byte) (texres.tin * 255.0f));
 				}
 				}
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(format, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 61 - 53
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMagic.java

@@ -1,15 +1,16 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -20,62 +21,67 @@ public class TextureGeneratorMagic extends TextureGenerator {
 
 
 	/**
 	/**
 	 * Constructor stores the given noise generator.
 	 * Constructor stores the given noise generator.
-	 * @param noiseGenerator the noise generator
+	 * @param noiseGenerator
+	 *        the noise generator
 	 */
 	 */
 	public TextureGeneratorMagic(NoiseGenerator noiseGenerator) {
 	public TextureGeneratorMagic(NoiseGenerator noiseGenerator) {
 		super(noiseGenerator);
 		super(noiseGenerator);
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		float x, y, z, turb;
 		float x, y, z, turb;
 		int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
 		int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
 		float turbul = ((Number) tex.getFieldValue("turbul")).floatValue() / 5.0f;
 		float turbul = ((Number) tex.getFieldValue("turbul")).floatValue() / 5.0f;
 		float[] texvec = new float[] { 0, 0, 0 };
 		float[] texvec = new float[] { 0, 0, 0 };
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height;
-		int halfW = width, halfH = height;
+		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
+		int halfW = width, halfH = height, halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * 4);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * 4);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i;
 			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
-				turb = turbul;
 				texvec[1] = hDelta * j;
 				texvec[1] = hDelta * j;
-				x = (float) Math.sin((texvec[0] + texvec[1]) * 5.0f);// in blender: Math.sin((texvec[0] + texvec[1] + texvec[2]) * 5.0f);
-				y = (float) Math.cos((-texvec[0] + texvec[1]) * 5.0f);// in blender: Math.cos((-texvec[0] + texvec[1] - texvec[2]) * 5.0f);
-				z = -(float) Math.cos((-texvec[0] - texvec[1]) * 5.0f);// in blender: Math.cos((-texvec[0] - texvec[1] + texvec[2]) * 5.0f);
+				for (int k = -halfD; k < halfD; ++k) {
+					turb = turbul;
+					texvec[2] = dDelta * k;// z
+					x = (float) Math.sin((texvec[0] + texvec[1] + texvec[2]) * 5.0f);
+					y = (float) Math.cos((-texvec[0] + texvec[1] - texvec[2]) * 5.0f);
+					z = -(float) Math.cos((-texvec[0] - texvec[1] + texvec[2]) * 5.0f);
 
 
-				if (colorBand != null) {
-					texres.tin = 0.3333f * (x + y + z);
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-				} else {
-					if (noisedepth > 0) {
-						x *= turb;
-						y *= turb;
-						z *= turb;
-						y = -(float) Math.cos(x - y + z) * turb;
-						if (noisedepth > 1) {
-							x = (float) Math.cos(x - y - z) * turb;
-							if (noisedepth > 2) {
-								z = (float) Math.sin(-x - y - z) * turb;
-								if (noisedepth > 3) {
-									x = -(float) Math.cos(-x + y - z) * turb;
-									if (noisedepth > 4) {
-										y = -(float) Math.sin(-x + y + z) * turb;
-										if (noisedepth > 5) {
-											y = -(float) Math.cos(-x + y + z) * turb;
-											if (noisedepth > 6) {
-												x = (float) Math.cos(x + y + z) * turb;
-												if (noisedepth > 7) {
-													z = (float) Math.sin(x + y - z) * turb;
-													if (noisedepth > 8) {
-														x = -(float) Math.cos(-x - y + z) * turb;
-														if (noisedepth > 9) {
-															y = -(float) Math.sin(x - y + z) * turb;
+					if (colorBand != null) {
+						texres.tin = 0.3333f * (x + y + z);
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+					} else {
+						if (noisedepth > 0) {
+							x *= turb;
+							y *= turb;
+							z *= turb;
+							y = -(float) Math.cos(x - y + z) * turb;
+							if (noisedepth > 1) {
+								x = (float) Math.cos(x - y - z) * turb;
+								if (noisedepth > 2) {
+									z = (float) Math.sin(-x - y - z) * turb;
+									if (noisedepth > 3) {
+										x = -(float) Math.cos(-x + y - z) * turb;
+										if (noisedepth > 4) {
+											y = -(float) Math.sin(-x + y + z) * turb;
+											if (noisedepth > 5) {
+												y = -(float) Math.cos(-x + y + z) * turb;
+												if (noisedepth > 6) {
+													x = (float) Math.cos(x + y + z) * turb;
+													if (noisedepth > 7) {
+														z = (float) Math.sin(x + y - z) * turb;
+														if (noisedepth > 8) {
+															x = -(float) Math.cos(-x - y + z) * turb;
+															if (noisedepth > 9) {
+																y = -(float) Math.sin(x - y + z) * turb;
+															}
 														}
 														}
 													}
 													}
 												}
 												}
@@ -85,25 +91,27 @@ public class TextureGeneratorMagic extends TextureGenerator {
 								}
 								}
 							}
 							}
 						}
 						}
-					}
 
 
-					if (turb != 0.0f) {
-						turb *= 2.0f;
-						x /= turb;
-						y /= turb;
-						z /= turb;
+						if (turb != 0.0f) {
+							turb *= 2.0f;
+							x /= turb;
+							y /= turb;
+							z /= turb;
+						}
+						texres.tr = 0.5f - x;
+						texres.tg = 0.5f - y;
+						texres.tb = 0.5f - z;
 					}
 					}
-					texres.tr = 0.5f - x;
-					texres.tg = 0.5f - y;
-					texres.tb = 0.5f - z;
+					noiseGenerator.brightnesAndContrastRGB(tex, texres);
+					data.put((byte) (texres.tin * 255));
+					data.put((byte) (texres.tb * 255));
+					data.put((byte) (texres.tg * 255));
+					data.put((byte) (texres.tr * 255));
 				}
 				}
-				noiseGenerator.brightnesAndContrastRGB(tex, texres);
-				data.put((byte) (texres.tin * 255));
-				data.put((byte) (texres.tb * 255));
-				data.put((byte) (texres.tg * 255));
-				data.put((byte) (texres.tr * 255));
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(Format.ABGR8, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(Format.ABGR8, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 33 - 25
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMarble.java

@@ -1,15 +1,16 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -17,56 +18,63 @@ import com.jme3.util.BufferUtils;
  * @author Marcin Roguski (Kaelthas)
  * @author Marcin Roguski (Kaelthas)
  */
  */
 public class TextureGeneratorMarble extends TextureGenerator {
 public class TextureGeneratorMarble extends TextureGenerator {
-	
+
 	/**
 	/**
 	 * Constructor stores the given noise generator.
 	 * Constructor stores the given noise generator.
-	 * @param noiseGenerator the noise generator
+	 * @param noiseGenerator
+	 *        the noise generator
 	 */
 	 */
 	public TextureGeneratorMarble(NoiseGenerator noiseGenerator) {
 	public TextureGeneratorMarble(NoiseGenerator noiseGenerator) {
 		super(noiseGenerator);
 		super(noiseGenerator);
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		// preparing the proper data
 		// preparing the proper data
 		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
 		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
 		float bright = ((Number) tex.getFieldValue("bright")).floatValue();
 		float bright = ((Number) tex.getFieldValue("bright")).floatValue();
 		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
 		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height;
+		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
 		float[] texvec = new float[] { 0, 0, 0 };
 		float[] texvec = new float[] { 0, 0, 0 };
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
-		int halfW = width, halfH = height;
+		int halfW = width, halfH = height, halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i;
 			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j;
 				texvec[1] = hDelta * j;
-				texres.tin = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
-				if (colorBand != null) {
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-					if (texres.nor != null) {// calculate bumpnormal
-						texres.nor[0] = noiseGenerator.marbleInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository);
-						texres.nor[1] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository);
-						texres.nor[2] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository);
-						noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
-					}
+				for (int k = -halfD; k < halfD; ++k) {
+					texvec[2] = dDelta * k;
+					texres.tin = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
+					if (colorBand != null) {
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+						if (texres.nor != null) {// calculate bumpnormal
+							texres.nor[0] = noiseGenerator.marbleInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository);
+							texres.nor[1] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository);
+							texres.nor[2] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository);
+							noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+						}
 
 
-					noiseGenerator.brightnesAndContrastRGB(tex, texres);
-					data.put((byte) (texres.tr * 255.0f));
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else {
-					noiseGenerator.brightnesAndContrast(texres, contrast, bright);
-					data.put((byte) (texres.tin * 255.0f));
+						noiseGenerator.brightnesAndContrastRGB(tex, texres);
+						data.put((byte) (texres.tr * 255.0f));
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else {
+						noiseGenerator.brightnesAndContrast(texres, contrast, bright);
+						data.put((byte) (texres.tin * 255.0f));
+					}
 				}
 				}
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(format, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 38 - 30
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMusgrave.java

@@ -1,15 +1,16 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -20,56 +21,63 @@ public class TextureGeneratorMusgrave extends TextureGenerator {
 
 
 	/**
 	/**
 	 * Constructor stores the given noise generator.
 	 * Constructor stores the given noise generator.
-	 * @param noiseGenerator the noise generator
+	 * @param noiseGenerator
+	 *        the noise generator
 	 */
 	 */
 	public TextureGeneratorMusgrave(NoiseGenerator noiseGenerator) {
 	public TextureGeneratorMusgrave(NoiseGenerator noiseGenerator) {
 		super(noiseGenerator);
 		super(noiseGenerator);
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		int stype = ((Number) tex.getFieldValue("stype")).intValue();
 		int stype = ((Number) tex.getFieldValue("stype")).intValue();
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
 		float[] texvec = new float[] { 0, 0, 0 };
 		float[] texvec = new float[] { 0, 0, 0 };
-		float wDelta = 1.0f / width, hDelta = 1.0f / height;
-		int halfW = width, halfH = height;
+		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
+		int halfW = width, halfH = height, halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i / noisesize;
 			texvec[0] = wDelta * i / noisesize;
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j / noisesize;
 				texvec[1] = hDelta * j / noisesize;
-				switch (stype) {
-					case NoiseGenerator.TEX_MFRACTAL:
-					case NoiseGenerator.TEX_FBM:
-						noiseGenerator.mgMFractalOrfBmTex(tex, texvec, colorBand, texres, dataRepository);
-						break;
-					case NoiseGenerator.TEX_RIDGEDMF:
-					case NoiseGenerator.TEX_HYBRIDMF:
-						noiseGenerator.mgRidgedOrHybridMFTex(tex, texvec, colorBand, texres, dataRepository);
-						break;
-					case NoiseGenerator.TEX_HTERRAIN:
-						noiseGenerator.mgHTerrainTex(tex, texvec, colorBand, texres, dataRepository);
-						break;
-					default:
-						throw new IllegalStateException("Unknown type of musgrave texture: " + stype);
-				}
-				if (colorBand != null) {
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-					data.put((byte) (texres.tr * 255.0f));
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else {
-					data.put((byte) (texres.tin * 255.0f));
+				for (int k = -halfD; k < halfD; ++k) {
+					texvec[2] = dDelta * k;
+					switch (stype) {
+						case NoiseGenerator.TEX_MFRACTAL:
+						case NoiseGenerator.TEX_FBM:
+							noiseGenerator.mgMFractalOrfBmTex(tex, texvec, colorBand, texres, dataRepository);
+							break;
+						case NoiseGenerator.TEX_RIDGEDMF:
+						case NoiseGenerator.TEX_HYBRIDMF:
+							noiseGenerator.mgRidgedOrHybridMFTex(tex, texvec, colorBand, texres, dataRepository);
+							break;
+						case NoiseGenerator.TEX_HTERRAIN:
+							noiseGenerator.mgHTerrainTex(tex, texvec, colorBand, texres, dataRepository);
+							break;
+						default:
+							throw new IllegalStateException("Unknown type of musgrave texture: " + stype);
+					}
+					if (colorBand != null) {
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+						data.put((byte) (texres.tr * 255.0f));
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else {
+						data.put((byte) (texres.tin * 255.0f));
+					}
 				}
 				}
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(format, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 32 - 25
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorNoise.java

@@ -1,6 +1,7 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.math.FastMath;
 import com.jme3.math.FastMath;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
@@ -8,9 +9,9 @@ import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -21,52 +22,58 @@ public class TextureGeneratorNoise extends TextureGenerator {
 
 
 	/**
 	/**
 	 * Constructor stores the given noise generator.
 	 * Constructor stores the given noise generator.
-	 * @param noiseGenerator the noise generator
+	 * @param noiseGenerator
+	 *        the noise generator
 	 */
 	 */
 	public TextureGeneratorNoise(NoiseGenerator noiseGenerator) {
 	public TextureGeneratorNoise(NoiseGenerator noiseGenerator) {
 		super(noiseGenerator);
 		super(noiseGenerator);
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		float div = 3.0f;
 		float div = 3.0f;
 		int val, ran, loop;
 		int val, ran, loop;
 		int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
 		int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
 		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
 		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
 		float brightness = ((Number) tex.getFieldValue("bright")).floatValue();
 		float brightness = ((Number) tex.getFieldValue("bright")).floatValue();
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
-		int halfW = width, halfH = height;
+		int halfW = width, halfH = height, halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
-				ran = FastMath.rand.nextInt();// BLI_rand();
-				val = ran & 3;
+				for (int k = -halfD; k < halfD; ++k) {
+					ran = FastMath.rand.nextInt();// BLI_rand();
+					val = ran & 3;
 
 
-				loop = noisedepth;
-				while (loop-- != 0) {
-					ran = ran >> 2;
-					val *= ran & 3;
-					div *= 3.0f;
-				}
-				texres.tin = val;// / div;
-				if (colorBand != null) {
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-					noiseGenerator.brightnesAndContrastRGB(tex, texres);
-					data.put((byte) (texres.tr * 255.0f));
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else {
-					noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
-					data.put((byte) (texres.tin * 255.0f));
+					loop = noisedepth;
+					while (loop-- != 0) {
+						ran = ran >> 2;
+						val *= ran & 3;
+						div *= 3.0f;
+					}
+					texres.tin = val;// / div;
+					if (colorBand != null) {
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+						noiseGenerator.brightnesAndContrastRGB(tex, texres);
+						data.put((byte) (texres.tr * 255.0f));
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else {
+						noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
+						data.put((byte) (texres.tin * 255.0f));
+					}
 				}
 				}
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(format, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 48 - 40
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorStucci.java

@@ -1,15 +1,16 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -20,14 +21,15 @@ public class TextureGeneratorStucci extends TextureGenerator {
 
 
 	/**
 	/**
 	 * Constructor stores the given noise generator.
 	 * Constructor stores the given noise generator.
-	 * @param noiseGenerator the noise generator
+	 * @param noiseGenerator
+	 *        the noise generator
 	 */
 	 */
 	public TextureGeneratorStucci(NoiseGenerator noiseGenerator) {
 	public TextureGeneratorStucci(NoiseGenerator noiseGenerator) {
 		super(noiseGenerator);
 		super(noiseGenerator);
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
 		int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
 		int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
 		int noisetype = ((Number) tex.getFieldValue("noisetype")).intValue();
 		int noisetype = ((Number) tex.getFieldValue("noisetype")).intValue();
@@ -37,59 +39,65 @@ public class TextureGeneratorStucci extends TextureGenerator {
 
 
 		float[] texvec = new float[] { 0, 0, 0 };
 		float[] texvec = new float[] { 0, 0, 0 };
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, b2, ofs;
-		int halfW = width, halfH = height;
+		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth, b2, ofs;
+		int halfW = width, halfH = height, halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
-			texvec[0] = wDelta * i;// x
+			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
-				texvec[1] = hDelta * j;// y (z is always = 0)
-				b2 = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2], isHard, noisebasis);
+				texvec[1] = hDelta * j;
+				for (int k = -halfD; k < halfD; ++k) {
+					texvec[2] = dDelta * k;
+					b2 = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2], isHard, noisebasis);
 
 
-				ofs = turbul / 200.0f;
+					ofs = turbul / 200.0f;
 
 
-				if (stype != 0) {
-					ofs *= b2 * b2;
-				}
+					if (stype != 0) {
+						ofs *= b2 * b2;
+					}
 
 
-				texres.tin = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2] + ofs, isHard, noisebasis);// ==nor[2]
-				if (colorBand != null) {
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-					if (texres.nor != null) {
-						texres.nor[0] = noiseGenerator.bliGNoise(noisesize, texvec[0] + ofs, texvec[1], texvec[2], isHard, noisebasis);
-						texres.nor[1] = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1] + ofs, texvec[2], isHard, noisebasis);
-						texres.nor[2] = texres.tin;
-						noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+					texres.tin = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2] + ofs, isHard, noisebasis);// ==nor[2]
+					if (colorBand != null) {
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+						if (texres.nor != null) {
+							texres.nor[0] = noiseGenerator.bliGNoise(noisesize, texvec[0] + ofs, texvec[1], texvec[2], isHard, noisebasis);
+							texres.nor[1] = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1] + ofs, texvec[2], isHard, noisebasis);
+							texres.nor[2] = texres.tin;
+							noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
 
 
-						if (stype == NoiseGenerator.TEX_WALLOUT) {
-							texres.nor[0] = -texres.nor[0];
-							texres.nor[1] = -texres.nor[1];
-							texres.nor[2] = -texres.nor[2];
+							if (stype == NoiseGenerator.TEX_WALLOUT) {
+								texres.nor[0] = -texres.nor[0];
+								texres.nor[1] = -texres.nor[1];
+								texres.nor[2] = -texres.nor[2];
+							}
 						}
 						}
 					}
 					}
-				}
 
 
-				if (stype == NoiseGenerator.TEX_WALLOUT) {
-					texres.tin = 1.0f - texres.tin;
-				}
-				if (texres.tin < 0.0f) {
-					texres.tin = 0.0f;
-				}
-				if (colorBand != null) {
-					data.put((byte) (texres.tr * 255.0f));
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else {
-					data.put((byte) (texres.tin * 255.0f));
+					if (stype == NoiseGenerator.TEX_WALLOUT) {
+						texres.tin = 1.0f - texres.tin;
+					}
+					if (texres.tin < 0.0f) {
+						texres.tin = 0.0f;
+					}
+					if (colorBand != null) {
+						data.put((byte) (texres.tr * 255.0f));
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else {
+						data.put((byte) (texres.tin * 255.0f));
+					}
 				}
 				}
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(format, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 72 - 65
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorVoronoi.java

@@ -1,6 +1,7 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.math.FastMath;
 import com.jme3.math.FastMath;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
@@ -8,9 +9,9 @@ import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
-import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
+import com.jme3.texture.Texture;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -21,14 +22,15 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
 
 
 	/**
 	/**
 	 * Constructor stores the given noise generator.
 	 * Constructor stores the given noise generator.
-	 * @param noiseGenerator the noise generator
+	 * @param noiseGenerator
+	 *        the noise generator
 	 */
 	 */
 	public TextureGeneratorVoronoi(NoiseGenerator noiseGenerator) {
 	public TextureGeneratorVoronoi(NoiseGenerator noiseGenerator) {
 		super(noiseGenerator);
 		super(noiseGenerator);
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		float vn_w1 = ((Number) tex.getFieldValue("vn_w1")).floatValue();
 		float vn_w1 = ((Number) tex.getFieldValue("vn_w1")).floatValue();
 		float vn_w2 = ((Number) tex.getFieldValue("vn_w2")).floatValue();
 		float vn_w2 = ((Number) tex.getFieldValue("vn_w2")).floatValue();
 		float vn_w3 = ((Number) tex.getFieldValue("vn_w3")).floatValue();
 		float vn_w3 = ((Number) tex.getFieldValue("vn_w3")).floatValue();
@@ -44,10 +46,11 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
 
 
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
 		float[] texvec = new float[] { 0, 0, 0 };
 		float[] texvec = new float[] { 0, 0, 0 };
-		float wDelta = 1.0f / width, hDelta = 1.0f / height;
-		int halfW = width, halfH = height;
+		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
+		int halfW = width, halfH = height, halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		Format format = vn_coltype != 0 || colorBand != null ? Format.RGB8 : Format.Luminance8;
 		Format format = vn_coltype != 0 || colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = vn_coltype != 0 || colorBand != null ? 3 : 1;
 		int bytesPerPixel = vn_coltype != 0 || colorBand != null ? 3 : 1;
@@ -63,76 +66,80 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
 			sc = ns_outscale / sc;
 			sc = ns_outscale / sc;
 		}
 		}
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i / noisesize;
 			texvec[0] = wDelta * i / noisesize;
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j / noisesize;
 				texvec[1] = hDelta * j / noisesize;
-
-				noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2], da, pa, vn_mexp, vn_distm);
-				texres.tin = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
-				if (vn_coltype != 0) {
-					noiseGenerator.cellNoiseV(pa[0], pa[1], pa[2], ca);
-					texres.tr = aw1 * ca[0];
-					texres.tg = aw1 * ca[1];
-					texres.tb = aw1 * ca[2];
-					noiseGenerator.cellNoiseV(pa[3], pa[4], pa[5], ca);
-					texres.tr += aw2 * ca[0];
-					texres.tg += aw2 * ca[1];
-					texres.tb += aw2 * ca[2];
-					noiseGenerator.cellNoiseV(pa[6], pa[7], pa[8], ca);
-					texres.tr += aw3 * ca[0];
-					texres.tg += aw3 * ca[1];
-					texres.tb += aw3 * ca[2];
-					noiseGenerator.cellNoiseV(pa[9], pa[10], pa[11], ca);
-					texres.tr += aw4 * ca[0];
-					texres.tg += aw4 * ca[1];
-					texres.tb += aw4 * ca[2];
-					if (vn_coltype >= 2) {
-						float t1 = (da[1] - da[0]) * 10.0f;
-						if (t1 > 1) {
-							t1 = 1.0f;
-						}
-						if (vn_coltype == 3) {
-							t1 *= texres.tin;
+				for (int k = -halfD; k < halfD; ++k) {
+					texvec[2] = dDelta * k;
+					noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2], da, pa, vn_mexp, vn_distm);
+					texres.tin = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
+					if (vn_coltype != 0) {
+						noiseGenerator.cellNoiseV(pa[0], pa[1], pa[2], ca);
+						texres.tr = aw1 * ca[0];
+						texres.tg = aw1 * ca[1];
+						texres.tb = aw1 * ca[2];
+						noiseGenerator.cellNoiseV(pa[3], pa[4], pa[5], ca);
+						texres.tr += aw2 * ca[0];
+						texres.tg += aw2 * ca[1];
+						texres.tb += aw2 * ca[2];
+						noiseGenerator.cellNoiseV(pa[6], pa[7], pa[8], ca);
+						texres.tr += aw3 * ca[0];
+						texres.tg += aw3 * ca[1];
+						texres.tb += aw3 * ca[2];
+						noiseGenerator.cellNoiseV(pa[9], pa[10], pa[11], ca);
+						texres.tr += aw4 * ca[0];
+						texres.tg += aw4 * ca[1];
+						texres.tb += aw4 * ca[2];
+						if (vn_coltype >= 2) {
+							float t1 = (da[1] - da[0]) * 10.0f;
+							if (t1 > 1) {
+								t1 = 1.0f;
+							}
+							if (vn_coltype == 3) {
+								t1 *= texres.tin;
+							} else {
+								t1 *= sc;
+							}
+							texres.tr *= t1;
+							texres.tg *= t1;
+							texres.tb *= t1;
 						} else {
 						} else {
-							t1 *= sc;
+							texres.tr *= sc;
+							texres.tg *= sc;
+							texres.tb *= sc;
 						}
 						}
-						texres.tr *= t1;
-						texres.tg *= t1;
-						texres.tb *= t1;
-					} else {
-						texres.tr *= sc;
-						texres.tg *= sc;
-						texres.tb *= sc;
 					}
 					}
-				}
-				if (colorBand != null) {
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-					if (texres.nor != null) {
-						float offs = nabla / noisesize; // also scaling of texvec
-						// calculate bumpnormal
-						noiseGenerator.voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, vn_mexp, vn_distm);
-						texres.nor[0] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
-						noiseGenerator.voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, vn_mexp, vn_distm);
-						texres.nor[1] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
-						noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, vn_mexp, vn_distm);
-						texres.nor[2] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
-						noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+					if (colorBand != null) {
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+						if (texres.nor != null) {
+							float offs = nabla / noisesize; // also scaling of texvec
+							// calculate bumpnormal
+							noiseGenerator.voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, vn_mexp, vn_distm);
+							texres.nor[0] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
+							noiseGenerator.voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, vn_mexp, vn_distm);
+							texres.nor[1] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
+							noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, vn_mexp, vn_distm);
+							texres.nor[2] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
+							noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+						}
 					}
 					}
-				}
 
 
-				if (vn_coltype != 0 || colorBand != null) {
-					noiseGenerator.brightnesAndContrastRGB(tex, texres);
-					data.put((byte) (texres.tr * 255.0f));// tin or tr??
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else {
-					noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
-					data.put((byte) (texres.tin * 255.0f));
+					if (vn_coltype != 0 || colorBand != null) {
+						noiseGenerator.brightnesAndContrastRGB(tex, texres);
+						data.put((byte) (texres.tr * 255.0f));// tin or tr??
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else {
+						noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
+						data.put((byte) (texres.tin * 255.0f));
+					}
 				}
 				}
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(format, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 29 - 20
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorWood.java

@@ -1,6 +1,7 @@
 package com.jme3.scene.plugins.blender.textures;
 package com.jme3.scene.plugins.blender.textures;
 
 
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.file.Structure;
 import com.jme3.scene.plugins.blender.file.Structure;
@@ -9,7 +10,7 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture;
-import com.jme3.texture.Texture2D;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -27,46 +28,54 @@ public class TextureGeneratorWood extends TextureGenerator {
 	}
 	}
 
 
 	@Override
 	@Override
-	protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
+	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		// preparing the proper data
 		// preparing the proper data
 		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
 		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
 		float bright = ((Number) tex.getFieldValue("bright")).floatValue();
 		float bright = ((Number) tex.getFieldValue("bright")).floatValue();
 		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
 		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height;
+		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
 		float[] texvec = new float[] { 0, 0, 0 };
 		float[] texvec = new float[] { 0, 0, 0 };
 		TexResult texres = new TexResult();
 		TexResult texres = new TexResult();
 		int halfW = width;
 		int halfW = width;
 		int halfH = height;
 		int halfH = height;
+		int halfD = depth;
 		width <<= 1;
 		width <<= 1;
 		height <<= 1;
 		height <<= 1;
+		depth <<= 1;
+		
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		ColorBand colorBand = this.readColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
+		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
 		for (int i = -halfW; i < halfW; ++i) {
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i;
 			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j;
 				texvec[1] = hDelta * j;
-				texres.tin = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
-				if (colorBand != null) {
-					noiseGenerator.doColorband(colorBand, texres, dataRepository);
-					if (texres.nor != null) {// calculate bumpnormal
-						texres.nor[0] = noiseGenerator.woodInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository);
-						texres.nor[1] = noiseGenerator.woodInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository);
-						texres.nor[2] = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository);
-						noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+				for(int k = -halfD; k < halfD; ++k) {
+					texvec[2] = dDelta * k;
+					texres.tin = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
+					if (colorBand != null) {
+						noiseGenerator.doColorband(colorBand, texres, dataRepository);
+						if (texres.nor != null) {// calculate bumpnormal
+							texres.nor[0] = noiseGenerator.woodInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository);
+							texres.nor[1] = noiseGenerator.woodInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository);
+							texres.nor[2] = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository);
+							noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
+						}
+						noiseGenerator.brightnesAndContrastRGB(tex, texres);
+						data.put((byte) (texres.tr * 255.0f));
+						data.put((byte) (texres.tg * 255.0f));
+						data.put((byte) (texres.tb * 255.0f));
+					} else {
+						noiseGenerator.brightnesAndContrast(texres, contrast, bright);
+						data.put((byte) (texres.tin * 255));
 					}
 					}
-					noiseGenerator.brightnesAndContrastRGB(tex, texres);
-					data.put((byte) (texres.tr * 255.0f));
-					data.put((byte) (texres.tg * 255.0f));
-					data.put((byte) (texres.tb * 255.0f));
-				} else {
-					noiseGenerator.brightnesAndContrast(texres, contrast, bright);
-					data.put((byte) (texres.tin * 255));
 				}
 				}
 			}
 			}
 		}
 		}
-		return new Texture2D(new Image(format, width, height, data));
+		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+		dataArray.add(data);
+		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 	}
 }
 }

+ 18 - 5
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java

@@ -41,6 +41,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Level;
@@ -68,6 +69,7 @@ import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture;
 import com.jme3.texture.Texture.WrapMode;
 import com.jme3.texture.Texture.WrapMode;
 import com.jme3.texture.Texture2D;
 import com.jme3.texture.Texture2D;
+import com.jme3.texture.Texture3D;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.BufferUtils;
 
 
 /**
 /**
@@ -194,7 +196,8 @@ public class TextureHelper extends AbstractBlenderHelper {
 		int type = ((Number) tex.getFieldValue("type")).intValue();
 		int type = ((Number) tex.getFieldValue("type")).intValue();
 		int width = dataRepository.getBlenderKey().getGeneratedTextureWidth();
 		int width = dataRepository.getBlenderKey().getGeneratedTextureWidth();
 		int height = dataRepository.getBlenderKey().getGeneratedTextureHeight();
 		int height = dataRepository.getBlenderKey().getGeneratedTextureHeight();
-
+		int depth = dataRepository.getBlenderKey().getGeneratedTextureDepth();
+		
 		switch (type) {
 		switch (type) {
 			case TEX_IMAGE:// (it is first because probably this will be most commonly used)
 			case TEX_IMAGE:// (it is first because probably this will be most commonly used)
 				Pointer pImage = (Pointer) tex.getFieldValue("ima");
 				Pointer pImage = (Pointer) tex.getFieldValue("ima");
@@ -214,7 +217,7 @@ public class TextureHelper extends AbstractBlenderHelper {
 			case TEX_VORONOI:
 			case TEX_VORONOI:
 			case TEX_DISTNOISE:
 			case TEX_DISTNOISE:
 				TextureGenerator textureGenerator = textureGenerators.get(Integer.valueOf(type));
 				TextureGenerator textureGenerator = textureGenerators.get(Integer.valueOf(type));
-				result = textureGenerator.generate(tex, width, height, dataRepository);
+				result = textureGenerator.generate(tex, width, height, depth, dataRepository);
 				break;
 				break;
 			case TEX_NONE:// No texture, do nothing
 			case TEX_NONE:// No texture, do nothing
 				break;
 				break;
@@ -266,7 +269,11 @@ public class TextureHelper extends AbstractBlenderHelper {
 		data.rewind();
 		data.rewind();
 		int width = texture.getImage().getWidth();
 		int width = texture.getImage().getWidth();
 		int height = texture.getImage().getHeight();
 		int height = texture.getImage().getHeight();
-		ByteBuffer newData = BufferUtils.createByteBuffer(width * height * 4);
+		int depth = texture.getImage().getDepth();
+		if(depth==0) {
+			depth = 1;
+		}
+		ByteBuffer newData = BufferUtils.createByteBuffer(width * height * depth * 4);
 
 
 		float[] resultPixel = new float[4];
 		float[] resultPixel = new float[4];
 		int dataIndex = 0;
 		int dataIndex = 0;
@@ -276,9 +283,15 @@ public class TextureHelper extends AbstractBlenderHelper {
 			newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
 			newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
 			newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
 			newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
 			newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
 			newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
-                        newData.put(dataIndex++, (byte) (1.0 * 255.0f));
+            newData.put(dataIndex++, (byte) 255.0f);//1.0f * 255.0f
+		}
+		if(texture.getType()==Texture.Type.TwoDimensional) {
+			return new Texture2D(new Image(Format.RGBA8, width, height, newData));
+		} else {
+			ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
+			dataArray.add(newData);
+			return new Texture3D(new Image(Format.RGBA8, width, height, depth, dataArray));
 		}
 		}
-		return new Texture2D(new Image(Format.RGBA8, width, height, newData));
 	}
 	}
 
 
 	/**
 	/**

+ 324 - 0
engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java

@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2009-2010 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.scene.plugins.blender.textures;
+
+import java.nio.FloatBuffer;
+import java.util.List;
+import java.util.logging.Logger;
+
+import com.jme3.bounding.BoundingBox;
+import com.jme3.bounding.BoundingSphere;
+import com.jme3.bounding.BoundingVolume;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
+import com.jme3.scene.VertexBuffer;
+import com.jme3.scene.VertexBuffer.Format;
+import com.jme3.scene.VertexBuffer.Usage;
+import com.jme3.texture.Texture.Type;
+import com.jme3.util.BufferUtils;
+
+/**
+ * This class is used for UV coordinates generation.
+ * @author Marcin Roguski (Kaelthas)
+ */
+public class UVCoordinatesGenerator {
+	private static final Logger	LOGGER						= Logger.getLogger(UVCoordinatesGenerator.class.getName());
+
+	public static final int		TEXCO_ORCO					= 1;
+	public static final int		TEXCO_REFL					= 2;
+	public static final int		TEXCO_NORM					= 4;
+	public static final int		TEXCO_GLOB					= 8;
+	public static final int		TEXCO_UV					= 16;
+	public static final int		TEXCO_OBJECT				= 32;
+	public static final int		TEXCO_LAVECTOR				= 64;
+	public static final int		TEXCO_VIEW					= 128;
+	public static final int		TEXCO_STICKY				= 256;
+	public static final int		TEXCO_OSA					= 512;
+	public static final int		TEXCO_WINDOW				= 1024;
+	public static final int		NEED_UV						= 2048;
+	public static final int		TEXCO_TANGENT				= 4096;
+	// still stored in vertex->accum, 1 D
+	public static final int		TEXCO_PARTICLE_OR_STRAND	= 8192;													// strand is used
+																														// for normal
+																														// materials,
+																														// particle for halo
+																														// materials
+	public static final int		TEXCO_STRESS				= 16384;
+	public static final int		TEXCO_SPEED					= 32768;
+
+	/**
+	 * This method generates UV coordinates for the given geometries.
+	 * @param texco
+	 *        texture coordinates type
+	 * @param textureType
+	 *        the type of the texture (only 2D and 3D)
+	 * @param geometries
+	 *        a list of geometries that will have coordinates applied
+	 */
+	public static void generateUVCoordinates(int texco, Type textureType, List<Geometry> geometries) {
+		for (Geometry geometry : geometries) {
+			UVCoordinatesGenerator.generateUVCoordinates(texco, textureType, geometry.getMesh());
+		}
+	}
+
+	/**
+	 * This method generates UV coordinates for the given mesh.
+	 * @param texco
+	 *        texture coordinates type
+	 * @param textureType
+	 *        the type of the texture (only 2D and 3D)
+	 * @param mesh
+	 *        a mesh that will have coordinates applied
+	 */
+	public static void generateUVCoordinates(int texco, Type textureType, Mesh mesh) {
+		VertexBuffer result = null;
+		switch (texco) {
+			case TEXCO_ORCO:
+				if (textureType == Type.TwoDimensional) {
+
+				} else if (textureType == Type.ThreeDimensional) {
+					BoundingBox bb = UVCoordinatesGenerator.getBoundingBox(mesh);
+
+					result = new VertexBuffer(com.jme3.scene.VertexBuffer.Type.TexCoord);
+					FloatBuffer positions = mesh.getFloatBuffer(com.jme3.scene.VertexBuffer.Type.Position);
+					float[] uvCoordinates = BufferUtils.getFloatArray(positions);
+					Vector3f min = bb.getMin(null);
+					float[] ext = new float[] { bb.getXExtent() * 2, bb.getYExtent() * 2, bb.getZExtent() * 2 };
+
+					// now transform the coordinates so that they are in the range of <0; 1>
+					for (int i = 0; i < uvCoordinates.length; i += 3) {
+						uvCoordinates[i] = (uvCoordinates[i] - min.x) / ext[0];
+						uvCoordinates[i + 1] = (uvCoordinates[i + 1] - min.y) / ext[1];
+						uvCoordinates[i + 2] = (uvCoordinates[i + 2] - min.z) / ext[2];
+					}
+
+					result.setupData(Usage.Static, 3, Format.Float, BufferUtils.createFloatBuffer(uvCoordinates));
+				} else {
+					throw new IllegalStateException("Unsupported texture type: " + textureType);
+				}
+				break;
+			case TEXCO_GLOB:
+
+				break;
+			case TEXCO_TANGENT:
+
+				break;
+			case TEXCO_UV:
+				break;
+			case TEXCO_STRESS:
+
+				break;
+			case TEXCO_NORM:
+
+				break;
+			case TEXCO_LAVECTOR:
+			case TEXCO_OBJECT:
+			case TEXCO_OSA:
+			case TEXCO_PARTICLE_OR_STRAND:
+			case TEXCO_REFL:
+			case TEXCO_SPEED:
+			case TEXCO_STICKY:
+			case TEXCO_VIEW:
+			case TEXCO_WINDOW:
+				LOGGER.warning("Texture coordinates type not currently supported: " + texco);
+				break;
+			default:
+				throw new IllegalStateException("Unknown texture coordinates value: " + texco);
+		}
+
+		mesh.clearBuffer(VertexBuffer.Type.TexCoord);// in case there are coordinates already set
+		mesh.setBuffer(result);
+	}
+
+	/**
+	 * Flat projection for 2D textures.
+	 * @param mesh
+	 *        mesh that is to be projected
+	 * @return UV coordinates after the projection
+	 */
+	public Vector2f[] flatProjection(Mesh mesh) {
+		return null;// TODO: implement
+	}
+
+	/**
+	 * Cube projection for 2D textures.
+	 * @param mesh
+	 *        mesh that is to be projected
+	 * @return UV coordinates after the projection
+	 */
+	public Vector2f[] cubeProjection(Mesh mesh) {
+		return null;// TODO: implement
+	}
+
+	/**
+	 * Tube projection for 2D textures.
+	 * @param mesh
+	 *        mesh that is to be projected
+	 * @return UV coordinates after the projection
+	 */
+
+	public Vector2f[] tubeProjection(Mesh mesh) {
+		return null;// TODO: implement
+	}
+
+	/**
+	 * Sphere projection for 2D textures.
+	 * @param mesh
+	 *        mesh that is to be projected
+	 * @return UV coordinates after the projection
+	 */
+	public Vector2f[] sphereProjection(Mesh mesh) {
+		return null;// TODO: implement
+		// Vector2f[] uvTable = new Vector2f[vertexList.size()];
+		// Ray ray = new Ray();
+		// CollisionResults cr = new CollisionResults();
+		// Vector3f yVec = new Vector3f();
+		// Vector3f zVec = new Vector3f();
+		// for(Geometry geom : geometries) {
+		// if(materialHelper.hasTexture(geom.getMaterial())) {//generate only when material has a texture
+		// geom.getMesh().updateBound();
+		// BoundingSphere bs = this.getBoundingSphere(geom.getMesh());
+		// float r2 = bs.getRadius() * bs.getRadius();
+		// yVec.set(0, -bs.getRadius(), 0);
+		// zVec.set(0, 0, -bs.getRadius());
+		// Vector3f center = bs.getCenter();
+		// ray.setOrigin(center);
+		// //we cast each vertex of the current mesh on the bounding box to determine the UV-coordinates
+		// for(int i=0;i<geom.getMesh().getIndexBuffer().size();++i) {
+		// int index = geom.getMesh().getIndexBuffer().get(i);
+		//
+		// ray.setOrigin(vertexList.get(index));
+		// ray.setDirection(normalList.get(index));
+		//
+		// //finding collision point
+		// cr.clear();
+		// bs.collideWith(ray, cr);//there is ALWAYS one collision
+		// Vector3f p = cr.getCollision(0).getContactPoint();
+		// p.subtractLocal(center);
+		// //arcLength = FastMath.acos(p.dot(yVec)/(p.length * yVec.length)) * r <- an arc length on the sphere (from top to the point on
+		// the sphere)
+		// //but yVec.length == r and p.length == r so: arcLength = FastMath.acos(p.dot(yVec)/r^2)/r
+		// //U coordinate is as follows: u = arcLength / PI*r
+		// //so to compute it faster we just write: u = FastMath.acos(p.dot(yVec)/r^2) / PI;
+		// float u = FastMath.acos(p.dot(yVec)/r2) / FastMath.PI;
+		// //we use similiar method to compute v
+		// //the only difference is that we need to cast the p vector on ZX plane
+		// //and use its length instead of r
+		// p.y = 0;
+		// float v = FastMath.acos(p.dot(zVec)/(bs.getRadius()*p.length())) / FastMath.PI;
+		// uvTable[index] = new Vector2f(u, v);
+		// }
+		// }
+		// }
+	}
+
+	/**
+	 * This method returns the bounding box of the given geometries.
+	 * @param geometries
+	 *        the list of geometries
+	 * @return bounding box of the given geometries
+	 */
+	private static BoundingBox getBoundingBox(List<Geometry> geometries) {
+		BoundingBox result = null;
+		for (Geometry geometry : geometries) {
+			BoundingBox bb = UVCoordinatesGenerator.getBoundingBox(geometry.getMesh());
+			if (result == null) {
+				result = bb;
+			} else {
+				result.merge(bb);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * This method returns the bounding box of the given mesh.
+	 * @param mesh
+	 *        the mesh
+	 * @return bounding box of the given mesh
+	 */
+	private static BoundingBox getBoundingBox(Mesh mesh) {
+		mesh.updateBound();
+		BoundingVolume bv = mesh.getBound();
+		if (bv instanceof BoundingBox) {
+			return (BoundingBox) bv;
+		} else if (bv instanceof BoundingSphere) {
+			BoundingSphere bs = (BoundingSphere) bv;
+			float r = bs.getRadius();
+			return new BoundingBox(bs.getCenter(), r, r, r);
+		} else {
+			throw new IllegalStateException("Unknown bounding volume type: " + bv.getClass().getName());
+		}
+	}
+
+	/**
+	 * This method returns the bounding sphere of the given geometries.
+	 * @param geometries
+	 *        the list of geometries
+	 * @return bounding spheres of the given geometries
+	 */
+	private static BoundingSphere getBoundingSphere(List<Geometry> geometries) {
+		BoundingSphere result = null;
+		for (Geometry geometry : geometries) {
+			BoundingSphere bs = UVCoordinatesGenerator.getBoundingSphere(geometry.getMesh());
+			if (result == null) {
+				result = bs;
+			} else {
+				result.merge(bs);
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * This method returns the bounding sphere of the given mesh.
+	 * @param mesh
+	 *        the mesh
+	 * @return bounding sphere of the given mesh
+	 */
+	private static BoundingSphere getBoundingSphere(Mesh mesh) {
+		mesh.updateBound();
+		BoundingVolume bv = mesh.getBound();
+		if (bv instanceof BoundingBox) {
+			BoundingBox bb = (BoundingBox) bv;
+			float r = Math.max(bb.getXExtent(), bb.getYExtent());
+			r = Math.max(r, bb.getZExtent());
+			return new BoundingSphere(r, bb.getCenter());
+		} else if (bv instanceof BoundingSphere) {
+			return (BoundingSphere) bv;
+		} else {
+			throw new IllegalStateException("Unknown bounding volume type: " + bv.getClass().getName());
+		}
+	}
+}