Jelajahi Sumber

Generated textures refactoring.
* Algorithms changed (not depending on blender sources any more).
* Improved loading speed (at least in some cases).
* Unnecessary functions removed (there were a few :) ).
* Several bugs fixed (some blending functions did not work well with textures; colorbands now calculated properly).

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

Kae..pl 14 tahun lalu
induk
melakukan
b86c1f4e64
16 mengubah file dengan 1759 tambahan dan 2047 penghapusan
  1. 6 4
      engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java
  2. 40 1
      engine/src/blender/com/jme3/scene/plugins/blender/textures/ImageLoader.java
  3. 214 867
      engine/src/blender/com/jme3/scene/plugins/blender/textures/NoiseGenerator.java
  4. 370 5
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGenerator.java
  5. 114 89
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorBlend.java
  6. 70 68
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorClouds.java
  7. 72 55
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorDistnoise.java
  8. 126 85
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMagic.java
  9. 94 56
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMarble.java
  10. 78 54
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMusgrave.java
  11. 48 51
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorNoise.java
  12. 52 61
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorStucci.java
  13. 101 107
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorVoronoi.java
  14. 138 33
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorWood.java
  15. 188 510
      engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java
  16. 48 1
      engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java

+ 6 - 4
engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java

@@ -201,6 +201,10 @@ public class MaterialHelper extends AbstractBlenderHelper {
 		MaterialContext materialContext = new MaterialContext(structure, dataRepository);
 		LOGGER.log(Level.INFO, "Material's name: {0}", materialContext.name);
 
+		DiffuseShader diffuseShader = this.getDiffuseShader(structure);
+		ColorRGBA diffuseColor = this.getDiffuseColor(structure, diffuseShader);
+		float[] diffuseColorArray = new float[] {diffuseColor.r, diffuseColor.g, diffuseColor.b};
+		
 		// texture
 		Map<String, Texture> texturesMap = new HashMap<String, Texture>();
 		Type firstTextureType = null;
@@ -236,7 +240,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
 							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 = textureHelper.blendTexture(diffuseColorArray, texture, color, colfac, blendType, negateTexture, dataRepository);
 							texture.setWrap(WrapMode.Repeat);
 							//TODO: textures merging
 							if (materialContext.shadeless) {
@@ -289,7 +293,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
 			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();
@@ -297,9 +301,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
 				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;
 				}

+ 40 - 1
engine/src/blender/com/jme3/scene/plugins/blender/textures/ImageLoader.java

@@ -1,10 +1,40 @@
+/*
+ * 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.io.InputStream;
 import java.util.logging.Logger;
 
 import com.jme3.scene.plugins.blender.file.BlenderInputStream;
-import com.jme3.scene.plugins.blender.textures.TextureHelper.ImageType;
 import com.jme3.texture.Image;
 import com.jme3.texture.plugins.AWTLoader;
 import com.jme3.texture.plugins.DDSLoader;
@@ -94,4 +124,13 @@ import com.jme3.texture.plugins.TGALoader;
 		}
 		return result;
 	}
+	
+	/**
+	 * Image types that can be loaded. AWT: png, jpg, jped or bmp TGA: tga DDS: DirectX image files
+	 * 
+	 * @author Marcin Roguski (Kaelthas)
+	 */
+	private static enum ImageType {
+		AWT, TGA, DDS;
+	}
 }

File diff ditekan karena terlalu besar
+ 214 - 867
engine/src/blender/com/jme3/scene/plugins/blender/textures/NoiseGenerator.java


+ 370 - 5
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGenerator.java

@@ -1,12 +1,47 @@
+/*
+ * 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.util.Map;
+import java.util.TreeMap;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.jme3.math.FastMath;
 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.ColorBand;
 import com.jme3.texture.Texture;
 
 /**
@@ -17,7 +52,7 @@ import com.jme3.texture.Texture;
 	private static final Logger	LOGGER	= Logger.getLogger(TextureGenerator.class.getName());
 
 	protected NoiseGenerator	noiseGenerator;
-
+	
 	public TextureGenerator(NoiseGenerator noiseGenerator) {
 		this.noiseGenerator = noiseGenerator;
 	}
@@ -47,7 +82,7 @@ import com.jme3.texture.Texture;
 	 *        the data repository
 	 * @return read colorband or null if not present
 	 */
-	protected ColorBand readColorband(Structure tex, DataRepository dataRepository) {
+	private ColorBand readColorband(Structure tex, DataRepository dataRepository) {
 		ColorBand result = null;
 		int flag = ((Number) tex.getFieldValue("flag")).intValue();
 		if ((flag & NoiseGenerator.TEX_COLORBAND) != 0) {
@@ -57,10 +92,340 @@ import com.jme3.texture.Texture;
 				colorbandStructure = pColorband.fetchData(dataRepository.getInputStream()).get(0);
 				result = new ColorBand(colorbandStructure);
 			} catch (BlenderFileException e) {
-				LOGGER.warning("Cannot fetch the colorband structure. The reason: " + e.getLocalizedMessage());
-				// TODO: throw an exception here ???
+				LOGGER.log(Level.WARNING, "Cannot fetch the colorband structure. The reason: {0}", e.getLocalizedMessage());
+			}
+		}
+		return result;
+	}
+	
+	protected float[][] computeColorband(Structure tex, DataRepository dataRepository) {
+		ColorBand colorBand = this.readColorband(tex, dataRepository);
+		float[][] result = null;
+		if(colorBand!=null) {
+			result = new float[1001][4];//1001 - amount of possible cursor positions; 4 = [r, g, b, a]
+			ColorBandData[] dataArray = colorBand.data;
+			
+			if(dataArray.length==1) {//special case; use only one color for all types of colorband interpolation
+				for(int i=0;i<result.length;++i) {
+					result[i][0] = dataArray[0].r;
+					result[i][1] = dataArray[0].g;
+					result[i][2] = dataArray[0].b;
+					result[i][3] = dataArray[0].a;
+				}
+			} else {
+				int currentCursor = 0;
+				ColorBandData currentData = dataArray[0];
+				ColorBandData nextData = dataArray[0];
+				switch(colorBand.ipoType) {
+					case ColorBand.IPO_LINEAR:
+						float rDiff = 0, gDiff = 0, bDiff = 0, aDiff = 0, posDiff;
+						for(int i=0;i<result.length;++i) {
+							posDiff = i - currentData.pos;
+							result[i][0] = currentData.r + rDiff * posDiff;
+							result[i][1] = currentData.g + gDiff * posDiff;
+							result[i][2] = currentData.b + bDiff * posDiff;
+							result[i][3] = currentData.a + aDiff * posDiff;
+							if(nextData.pos==i) {
+								currentData = dataArray[currentCursor++];
+								if(currentCursor < dataArray.length) {
+									nextData = dataArray[currentCursor];
+									//calculate differences
+									int d = nextData.pos - currentData.pos;
+									rDiff = (nextData.r - currentData.r)/d;
+									gDiff = (nextData.g - currentData.g)/d;
+									bDiff = (nextData.b - currentData.b)/d;
+									aDiff = (nextData.a - currentData.a)/d;
+								} else {
+									rDiff = gDiff = bDiff = aDiff = 0;
+								}							
+							}
+						}
+						break;
+					case ColorBand.IPO_BSPLINE:
+					case ColorBand.IPO_CARDINAL:
+						Map<Integer, ColorBandData> cbDataMap = new TreeMap<Integer, ColorBandData>();
+						for(int i=0;i<colorBand.data.length;++i) {
+							cbDataMap.put(Integer.valueOf(i), colorBand.data[i]);
+						}
+						
+						if(colorBand.data[0].pos==0) {
+							cbDataMap.put(Integer.valueOf(-1), colorBand.data[0]);
+						} else {
+							ColorBandData cbData = colorBand.data[0].clone();
+							cbData.pos = 0;
+							cbDataMap.put(Integer.valueOf(-1), cbData);
+							cbDataMap.put(Integer.valueOf(-2), cbData);
+						}
+						
+						if(colorBand.data[colorBand.data.length - 1].pos==1000) {
+							cbDataMap.put(Integer.valueOf(colorBand.data.length), colorBand.data[colorBand.data.length - 1]);
+						} else {
+							ColorBandData cbData = colorBand.data[colorBand.data.length - 1].clone();
+							cbData.pos = 1000;
+							cbDataMap.put(Integer.valueOf(colorBand.data.length), cbData);
+							cbDataMap.put(Integer.valueOf(colorBand.data.length + 1), cbData);
+						}
+						
+						float[] ipoFactors = new float[4];
+						float f;
+						
+						ColorBandData data0 = cbDataMap.get(currentCursor - 2);
+						ColorBandData data1 = cbDataMap.get(currentCursor - 1);
+						ColorBandData data2 = cbDataMap.get(currentCursor);
+						ColorBandData data3 = cbDataMap.get(currentCursor + 1);
+						
+						for(int i=0;i<result.length;++i) {
+							if (data2.pos != data1.pos) {
+		                        f = (i - data2.pos) / (float)(data1.pos - data2.pos);
+		                    } else {
+		                        f = 0.0f;
+		                    }
+							
+							f = FastMath.clamp(f, 0.0f, 1.0f);
+							
+							this.getIpoData(colorBand, f, ipoFactors);
+							result[i][0] = ipoFactors[3] * data0.r + ipoFactors[2] * data1.r + ipoFactors[1] * data2.r + ipoFactors[0] * data3.r;
+							result[i][1] = ipoFactors[3] * data0.g + ipoFactors[2] * data1.g + ipoFactors[1] * data2.g + ipoFactors[0] * data3.g;
+							result[i][2] = ipoFactors[3] * data0.b + ipoFactors[2] * data1.b + ipoFactors[1] * data2.b + ipoFactors[0] * data3.b;
+							result[i][3] = ipoFactors[3] * data0.a + ipoFactors[2] * data1.a + ipoFactors[1] * data2.a + ipoFactors[0] * data3.a;
+							result[i][0] = FastMath.clamp(result[i][0], 0.0f, 1.0f);
+							result[i][1] = FastMath.clamp(result[i][1], 0.0f, 1.0f);
+							result[i][2] = FastMath.clamp(result[i][2], 0.0f, 1.0f);
+							result[i][3] = FastMath.clamp(result[i][3], 0.0f, 1.0f);
+							
+							if(nextData.pos==i) {
+								++currentCursor;
+								data0 = cbDataMap.get(currentCursor - 2);
+								data1 = cbDataMap.get(currentCursor - 1);
+								data2 = cbDataMap.get(currentCursor);
+								data3 = cbDataMap.get(currentCursor + 1);
+							}
+						}
+						break;
+					case ColorBand.IPO_EASE:
+						float d, a, b, d2;
+						for(int i=0;i<result.length;++i) {
+							if(nextData.pos != currentData.pos) {
+								d = (i - currentData.pos) / (float)(nextData.pos - currentData.pos);
+								d2 = d * d;
+								a = 3.0f * d2 - 2.0f * d * d2;
+								b = 1.0f - a;
+							} else {
+								d = a = 0.0f;
+								b = 1.0f;
+							}
+							
+							result[i][0] = b * currentData.r + a * nextData.r;
+							result[i][1] = b * currentData.g + a * nextData.g;
+							result[i][2] = b * currentData.b + a * nextData.b;
+							result[i][3] = b * currentData.a + a * nextData.a;
+							if(nextData.pos==i) {
+								currentData = dataArray[currentCursor++];
+								if(currentCursor < dataArray.length) {
+									nextData = dataArray[currentCursor];
+								}						
+							}
+						}
+						break;
+					case ColorBand.IPO_CONSTANT:
+						for(int i=0;i<result.length;++i) {
+							result[i][0] = currentData.r;
+							result[i][1] = currentData.g;
+							result[i][2] = currentData.b;
+							result[i][3] = currentData.a;
+							if(nextData.pos==i) {
+								currentData = dataArray[currentCursor++];
+								if(currentCursor < dataArray.length) {
+									nextData = dataArray[currentCursor];
+								}
+							}
+						}
+						break;
+					default:
+						throw new IllegalStateException("Unknown interpolation type: " + colorBand.ipoType);
+				}
 			}
 		}
 		return result;
 	}
+	
+	/**
+	 * This method returns the data for either B-spline of Cardinal interpolation.
+	 * @param colorBand the color band
+	 * @param d distance factor for the current intensity
+	 * @param ipoFactors table to store the results (size of the table must be at least 4)
+	 */
+	private void getIpoData(ColorBand colorBand, float d, float[] ipoFactors) {
+		float d2 = d * d;
+		float d3 = d2 * d;
+		if(colorBand.ipoType==ColorBand.IPO_BSPLINE) {
+			ipoFactors[0] = -0.71f * d3 + 1.42f * d2 - 0.71f * d;
+			ipoFactors[1] = 1.29f * d3 - 2.29f * d2 + 1.0f;
+			ipoFactors[2] = -1.29f * d3 + 1.58f * d2 + 0.71f * d;
+			ipoFactors[3] = 0.71f * d3 - 0.71f * d2;
+		} else if(colorBand.ipoType==ColorBand.IPO_CARDINAL) {
+			ipoFactors[0] = -0.16666666f * d3 + 0.5f * d2 - 0.5f * d + 0.16666666f;
+			ipoFactors[1] = 0.5f * d3 - d2 + 0.6666666f;
+			ipoFactors[2] = -0.5f * d3 + 0.5f * d2 + 0.5f * d + 0.16666666f;
+			ipoFactors[3] = 0.16666666f * d3;
+		} else {
+			throw new IllegalStateException("Cannot get interpolation data for other colorband types than B-spline and Cardinal!");
+		}
+	}
+	
+	/**
+	 * This method applies brightness and contrast for RGB textures.
+	 * @param tex texture structure
+	 * @param texres
+	 */
+	protected void applyBrightnessAndContrast(BrightnessAndContrastData bacd, TextureResult texres) {
+        texres.red = (texres.red - 0.5f) * bacd.contrast + bacd.brightness;
+        if (texres.red < 0.0f) {
+            texres.red = 0.0f;
+        }
+        texres.green =(texres.green - 0.5f) * bacd.contrast + bacd.brightness;
+        if (texres.green < 0.0f) {
+            texres.green = 0.0f;
+        }
+        texres.blue = (texres.blue - 0.5f) * bacd.contrast + bacd.brightness;
+        if (texres.blue < 0.0f) {
+            texres.blue = 0.0f;
+        }
+    }
+	
+	/**
+	 * This method applies brightness and contrast for Luminance textures.
+	 * @param texres
+	 * @param contrast
+	 * @param brightness
+	 */
+	protected void applyBrightnessAndContrast(TextureResult texres, float contrast, float brightness) {
+        texres.intensity = (texres.intensity - 0.5f) * contrast + brightness;
+        if (texres.intensity < 0.0f) {
+            texres.intensity = 0.0f;
+        } else if (texres.intensity > 1.0f) {
+            texres.intensity = 1.0f;
+        }
+    }
+	
+	/**
+	 * The result pixel of generated texture computations;
+	 * 
+	 * @author Marcin Roguski (Kaelthas)
+	 */
+	protected static class TextureResult implements Cloneable {
+		public float	intensity, red, green, blue, alpha;
+
+		@Override
+		public Object clone() throws CloneNotSupportedException {
+			return super.clone();
+		}
+	}
+	
+	/**
+	 * A class constaining the colorband data.
+	 * 
+	 * @author Marcin Roguski (Kaelthas)
+	 */
+	protected static class ColorBand {
+		//interpolation types
+		public static final int IPO_LINEAR 		= 0;
+		public static final int IPO_EASE 		= 1;
+		public static final int IPO_BSPLINE 	= 2;
+		public static final int IPO_CARDINAL 	= 3;
+		public static final int IPO_CONSTANT 	= 4;
+
+		public int		cursorsAmount, ipoType;
+		public ColorBandData[]	data;
+
+		/**
+		 * Constructor. Loads the data from the given structure.
+		 * 
+		 * @param cbdataStructure
+		 *        the colorband structure
+		 */
+		@SuppressWarnings("unchecked")
+		public ColorBand(Structure colorbandStructure) {
+			this.cursorsAmount = ((Number) colorbandStructure.getFieldValue("tot")).intValue();
+			this.ipoType = ((Number) colorbandStructure.getFieldValue("ipotype")).intValue();
+			this.data = new ColorBandData[this.cursorsAmount];
+			DynamicArray<Structure> data = (DynamicArray<Structure>) colorbandStructure.getFieldValue("data");
+			for (int i = 0; i < this.cursorsAmount; ++i) {
+				this.data[i] = new ColorBandData(data.get(i));
+			}
+		}
+	}
+
+	/**
+	 * Class to store the single colorband cursor data.
+	 * 
+	 * @author Marcin Roguski (Kaelthas)
+	 */
+	protected static class ColorBandData implements Cloneable {
+		public final float	r, g, b, a;
+		public int 	pos;
+
+		/**
+		 * Copy constructor.
+		 */
+		private ColorBandData(ColorBandData data) {
+			this.r = data.r;
+			this.g = data.g;
+			this.b = data.b;
+			this.a = data.a;
+			this.pos = data.pos;
+		}
+
+		/**
+		 * Constructor. Loads the data from the given structure.
+		 * 
+		 * @param cbdataStructure
+		 *        the structure containing the CBData object
+		 */
+		public ColorBandData(Structure cbdataStructure) {
+			this.r = ((Number) cbdataStructure.getFieldValue("r")).floatValue();
+			this.g = ((Number) cbdataStructure.getFieldValue("g")).floatValue();
+			this.b = ((Number) cbdataStructure.getFieldValue("b")).floatValue();
+			this.a = ((Number) cbdataStructure.getFieldValue("a")).floatValue();
+			this.pos = (int) (((Number) cbdataStructure.getFieldValue("pos")).floatValue() * 1000.0f);
+		}
+
+		@Override
+		public ColorBandData clone() {
+			try {
+				return (ColorBandData) super.clone();
+			} catch (CloneNotSupportedException e) {
+				return new ColorBandData(this);
+			}
+		}
+
+		@Override
+		public String toString() {
+			return "P: " + this.pos + " [" + this.r+", "+this.g+", "+this.b+", "+this.a+"]";
+		}
+	}
+	
+	/**
+	 * This class contains brightness and contrast data.
+	 * @author Marcin Roguski (Kaelthas)
+	 */
+	protected static class BrightnessAndContrastData {
+		public final float contrast;
+        public final float brightness;
+        public final float rFactor;
+        public final float gFactor;
+        public final float bFactor;
+        
+        /**
+         * Constructor reads the required data from the given structure.
+         * @param tex texture structure
+         */
+		public BrightnessAndContrastData(Structure tex) {
+			contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
+	        brightness = ((Number) tex.getFieldValue("bright")).floatValue() - 0.5f;
+	        rFactor = ((Number) tex.getFieldValue("rfac")).floatValue();
+	        gFactor = ((Number) tex.getFieldValue("gfac")).floatValue();
+	        bFactor = ((Number) tex.getFieldValue("bfac")).floatValue();
+		}
+	}
 }

+ 114 - 89
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorBlend.java

@@ -1,32 +1,33 @@
 /*
- *
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * Copyright (c) 2009-2010 jMonkeyEngine
  * All rights reserved.
  *
- * The Original Code is: all of this file.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * Contributor(s): none yet.
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
  *
- * ***** END GPL LICENSE BLOCK *****
+ * * 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;
 
@@ -36,8 +37,6 @@ import java.util.ArrayList;
 import com.jme3.math.FastMath;
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -49,7 +48,63 @@ import com.jme3.util.BufferUtils;
  * @author Marcin Roguski (Kaelthas)
  */
 public final class TextureGeneratorBlend extends TextureGenerator {
-
+    
+    private static final IntensityFunction INTENSITY_FUNCTION[] = new IntensityFunction[7];
+    static {
+    	INTENSITY_FUNCTION[0] = new IntensityFunction() {//Linear: stype = 0 (TEX_LIN)
+			@Override
+			public float getIntensity(float x, float y, float z) {
+				return (1.0f + x) * 0.5f;
+			}
+		};
+		INTENSITY_FUNCTION[1] = new IntensityFunction() {//Quad: stype = 1 (TEX_QUAD)
+			@Override
+			public float getIntensity(float x, float y, float z) {
+				float result = (1.0f + x) * 0.5f;
+				return result * result;
+			}
+		};
+		INTENSITY_FUNCTION[2] = new IntensityFunction() {//Ease: stype = 2 (TEX_EASE)
+			@Override
+			public float getIntensity(float x, float y, float z) {
+				float result = (1.0f + x) * 0.5f;
+				if (result <= 0.0f) {
+					return 0.0f;
+				} else if (result >= 1.0f) {
+					return 1.0f;
+				} else {
+					return result * result *(3.0f - 2.0f * result);
+				}
+			}
+		};
+		INTENSITY_FUNCTION[3] = new IntensityFunction() {//Diagonal: stype = 3 (TEX_DIAG)
+			@Override
+			public float getIntensity(float x, float y, float z) {
+				return (2.0f + x + y) * 0.25f;
+			}
+		};
+		INTENSITY_FUNCTION[4] = new IntensityFunction() {//Sphere: stype = 4 (TEX_SPHERE)
+			@Override
+			public float getIntensity(float x, float y, float z) {
+				float result = 1.0f - (float) Math.sqrt(x * x + y * y + z * z);
+				return result < 0.0f ? 0.0f : result;
+			}
+		};
+		INTENSITY_FUNCTION[5] = new IntensityFunction() {//Halo: stype = 5 (TEX_HALO)
+			@Override
+			public float getIntensity(float x, float y, float z) {
+				float result = 1.0f - (float) Math.sqrt(x * x + y * y + z * z);
+				return result <= 0.0f ? 0.0f : result * result;
+			}
+		};
+		INTENSITY_FUNCTION[6] = new IntensityFunction() {//Radial: stype = 6 (TEX_RAD)
+			@Override
+			public float getIntensity(float x, float y, float z) {
+				return (float) Math.atan2(y, x) * FastMath.INV_TWO_PI + 0.5f;
+			}
+		};
+    }
+    
 	/**
 	 * Constructor stores the given noise generator.
 	 * @param noiseGenerator
@@ -63,81 +118,51 @@ public final class TextureGeneratorBlend extends TextureGenerator {
 	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		int flag = ((Number) tex.getFieldValue("flag")).intValue();
 		int stype = ((Number) tex.getFieldValue("stype")).intValue();
-		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
-		float brightness = ((Number) tex.getFieldValue("bright")).floatValue();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth, x, y, t;
-		float[] texvec = new float[] { 0, 0, 0 };
-		TexResult texres = new TexResult();
-		int halfW = width, halfH = height, halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
+		TextureResult texres = new TextureResult();
+		int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
+		float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD, x, y;
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
+		BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
-
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
+		boolean flipped = (flag & NoiseGenerator.TEX_FLIPBLEND) != 0;
+		
+		byte[] data = new byte[width * height * depth * bytesPerPixel];
 		for (int i = -halfW; i < halfW; ++i) {
-			texvec[0] = wDelta * i;
+			x = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
-				texvec[1] = hDelta * j;
+				if (flipped) {
+					y = x;
+					x = hDelta * j;
+				} else {
+					y = hDelta * j;
+				}
 				for (int k = -halfD; k < halfD; ++k) {
-					texvec[2] = dDelta * k;
-					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;
-						} 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 */
-					}
+					texres.intensity = INTENSITY_FUNCTION[stype].getIntensity(x, y, dDelta * k);
+					
 					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));
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
+						
+						this.applyBrightnessAndContrast(bacd, texres);
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
 					} else {
-						noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
-						data.put((byte) (texres.tin * 255.0f));
+						this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
+						data[index++] = (byte) (texres.intensity * 255.0f);
 					}
 				}
 			}
 		}
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
+		dataArray.add(BufferUtils.createByteBuffer(data));
 		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
+	
+	private static interface IntensityFunction {
+		float getIntensity(float x, float y, float z);
+	}
 }

+ 70 - 68
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorClouds.java

@@ -1,42 +1,42 @@
 /*
- *
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * Copyright (c) 2009-2010 jMonkeyEngine
  * All rights reserved.
  *
- * The Original Code is: all of this file.
+ * 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.
  *
- * Contributor(s): none yet.
+ * * 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.
  *
- * ***** END GPL LICENSE BLOCK *****
+ * * 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.ByteBuffer;
 import java.util.ArrayList;
 
+import com.jme3.math.FastMath;
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -48,7 +48,14 @@ import com.jme3.util.BufferUtils;
  * @author Marcin Roguski (Kaelthas)
  */
 public class TextureGeneratorClouds extends TextureGenerator {
-
+	// tex->noisetype
+    protected static final int TEX_NOISESOFT = 0;
+    protected static final int TEX_NOISEPERL = 1;
+    
+    // tex->stype
+    protected static final int TEX_DEFAULT = 0;
+    protected static final int TEX_COLOR = 1;
+    
 	/**
 	 * Constructor stores the given noise generator.
 	 * @param noiseGenerator
@@ -60,69 +67,64 @@ public class TextureGeneratorClouds extends TextureGenerator {
 
 	@Override
 	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
-		// preparing the proper data
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
 		float[] texvec = new float[] { 0, 0, 0 };
-		TexResult texres = new TexResult();
+		TextureResult texres = new TextureResult();
 
 		// reading the data from the texture structure
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
 		int noiseDepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
 		int noiseBasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
 		int noiseType = ((Number) tex.getFieldValue("noisetype")).intValue();
-		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
-		float bright = ((Number) tex.getFieldValue("bright")).floatValue();
-		boolean isHard = noiseType != NoiseGenerator.TEX_NOISESOFT;
+		boolean isHard = noiseType != TEX_NOISESOFT;
 		int sType = ((Number) tex.getFieldValue("stype")).intValue();
-		int halfW = width, halfH = height, halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
-		Format format = sType == NoiseGenerator.TEX_COLOR || colorBand != null ? Format.RGB8 : Format.Luminance8;
-		int bytesPerPixel = sType == NoiseGenerator.TEX_COLOR || colorBand != null ? 3 : 1;
-
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
+		int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
+		float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
+		Format format = sType == TEX_COLOR || colorBand != null ? Format.RGB8 : Format.Luminance8;
+		int bytesPerPixel = sType == TEX_COLOR || colorBand != null ? 3 : 1;
+		BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
+		
+		byte[] data = new byte[width * height * depth * bytesPerPixel];
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 				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);
+					texres.intensity = NoiseGenerator.NoiseFunctions.turbulence(texvec[0], texvec[1], texvec[2], noisesize, noiseDepth, noiseBasis, isHard);
+					texres.intensity = FastMath.clamp(texres.intensity, 0.0f, 1.0f);
 					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));
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
+						
+						this.applyBrightnessAndContrast(bacd, texres);
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
+					} else if (sType == TEX_COLOR) {
+						texres.red = texres.intensity;
+						texres.green = NoiseGenerator.NoiseFunctions.turbulence(texvec[1], texvec[0], texvec[2], noisesize, noiseDepth, noiseBasis, isHard);
+						texres.blue = NoiseGenerator.NoiseFunctions.turbulence(texvec[1], texvec[2], texvec[0], noisesize, noiseDepth, noiseBasis, isHard);
+						
+						texres.green = FastMath.clamp(texres.green, 0.0f, 1.0f);
+						texres.blue = FastMath.clamp(texres.blue, 0.0f, 1.0f);
+						
+						this.applyBrightnessAndContrast(bacd, texres);
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
 					} else {
-						noiseGenerator.brightnesAndContrast(texres, contrast, bright);
-						data.put((byte) (texres.tin * 255));
+						this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
+						data[index++] = (byte) (texres.intensity * 255.0f);
 					}
 				}
 			}
 		}
+		
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
+		dataArray.add(BufferUtils.createByteBuffer(data));
 		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 }

+ 72 - 55
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorDistnoise.java

@@ -1,32 +1,33 @@
 /*
- *
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * Copyright (c) 2009-2010 jMonkeyEngine
  * All rights reserved.
  *
- * The Original Code is: all of this file.
+ * 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.
  *
- * Contributor(s): none yet.
+ * * 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.
  *
- * ***** END GPL LICENSE BLOCK *****
+ * * 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;
 
@@ -35,8 +36,7 @@ import java.util.ArrayList;
 
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
+import com.jme3.scene.plugins.blender.textures.NoiseGenerator.NoiseFunction;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -61,56 +61,73 @@ public class TextureGeneratorDistnoise extends TextureGenerator {
 	@Override
 	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
-		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
 		float distAmount = ((Number) tex.getFieldValue("dist_amount")).floatValue();
 		int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
 		int noisebasis2 = ((Number) tex.getFieldValue("noisebasis2")).intValue();
-		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
-		float brightness = ((Number) tex.getFieldValue("bright")).floatValue();
 
-		TexResult texres = new TexResult();
+		TextureResult texres = new TextureResult();
 		float[] texvec = new float[] { 0, 0, 0 };
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
-		int halfW = width, halfH = height, halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
+		int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
+		float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
-
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
+		BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
+		
+		byte[] data = new byte[width * height * depth * bytesPerPixel];
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i / noisesize;
 			for (int j = -halfH; j < halfH; ++j) {
 				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);
+					texvec[2] = dDelta * k;
+					texres.intensity = this.musgraveVariableLunacrityNoise(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);
-						}
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
 
-						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));
+						this.applyBrightnessAndContrast(bacd, texres);
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
 					} else {
-						noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
-						data.put((byte) (texres.tin * 255.0f));
+						this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
+						data[index++] = (byte) (texres.intensity * 255.0f);
 					}
 				}
 			}
 		}
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
+		dataArray.add(BufferUtils.createByteBuffer(data));
 		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
+	
+	/**
+     * "Variable Lacunarity Noise" A distorted variety of Perlin noise. This method is used to calculate distorted noise
+     * texture.
+     * @param x
+     * @param y
+     * @param z
+     * @param distortion
+     * @param nbas1
+     * @param nbas2
+     * @return
+     */
+    private float musgraveVariableLunacrityNoise(float x, float y, float z, float distortion, int nbas1, int nbas2) {
+        NoiseFunction abstractNoiseFunc1 = NoiseGenerator.noiseFunctions.get(Integer.valueOf(nbas1));
+        if (abstractNoiseFunc1 == null) {
+            abstractNoiseFunc1 = NoiseGenerator.noiseFunctions.get(Integer.valueOf(0));
+        }
+        NoiseFunction abstractNoiseFunc2 = NoiseGenerator.noiseFunctions.get(Integer.valueOf(nbas2));
+        if (abstractNoiseFunc2 == null) {
+            abstractNoiseFunc2 = NoiseGenerator.noiseFunctions.get(Integer.valueOf(0));
+        }
+        // get a random vector and scale the randomization
+        float rx = abstractNoiseFunc1.execute(x + 13.5f, y + 13.5f, z + 13.5f) * distortion;
+        float ry = abstractNoiseFunc1.execute(x, y, z) * distortion;
+        float rz = abstractNoiseFunc1.execute(x - 13.5f, y - 13.5f, z - 13.5f) * distortion;
+        return abstractNoiseFunc2.executeSigned(x + rx, y + ry, z + rz); //distorted-domain noise
+    }
 }

+ 126 - 85
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMagic.java

@@ -1,32 +1,33 @@
 /*
- *
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * Copyright (c) 2009-2010 jMonkeyEngine
  * All rights reserved.
  *
- * The Original Code is: all of this file.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * Contributor(s): none yet.
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
  *
- * ***** END GPL LICENSE BLOCK *****
+ * * 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;
 
@@ -35,8 +36,6 @@ import java.util.ArrayList;
 
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -48,7 +47,70 @@ import com.jme3.util.BufferUtils;
  * @author Marcin Roguski (Kaelthas)
  */
 public class TextureGeneratorMagic extends TextureGenerator {
-
+	private static NoiseDepthFunction[] noiseDepthFunctions = new NoiseDepthFunction[10];
+	static {
+		noiseDepthFunctions[0] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[1] = -(float) Math.cos(xyz[0] - xyz[1] + xyz[2]) * turbulence;
+			}
+		};
+		noiseDepthFunctions[1] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[0] = (float) Math.cos(xyz[0] - xyz[1] - xyz[2]) * turbulence;
+			}
+		};
+		noiseDepthFunctions[2] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[2] = (float) Math.sin(-xyz[0] - xyz[1] - xyz[2]) * turbulence;
+			}
+		};
+		noiseDepthFunctions[3] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[0] = -(float) Math.cos(-xyz[0] + xyz[1] - xyz[2]) * turbulence;
+			}
+		};
+		noiseDepthFunctions[4] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[1] = -(float) Math.sin(-xyz[0] + xyz[1] + xyz[2]) * turbulence;
+			}
+		};
+		noiseDepthFunctions[5] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[1] = -(float) Math.cos(-xyz[0] + xyz[1] + xyz[2]) * turbulence;
+			}
+		};
+		noiseDepthFunctions[6] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[0] = (float) Math.cos(xyz[0] + xyz[1] + xyz[2]) * turbulence;
+			}
+		};
+		noiseDepthFunctions[7] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[2] = (float) Math.sin(xyz[0] + xyz[1] - xyz[2]) * turbulence;
+			}
+		};
+		noiseDepthFunctions[8] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[0] = -(float) Math.cos(-xyz[0] - xyz[1] + xyz[2]) * turbulence;
+			}
+		};
+		noiseDepthFunctions[9] = new NoiseDepthFunction() {
+			@Override
+			public void compute(float[] xyz, float turbulence) {
+				xyz[1] = -(float) Math.sin(xyz[0] - xyz[1] + xyz[2]) * turbulence;
+			}
+		};
+	}
+	
 	/**
 	 * Constructor stores the given noise generator.
 	 * @param noiseGenerator
@@ -60,88 +122,67 @@ public class TextureGeneratorMagic extends TextureGenerator {
 
 	@Override
 	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
-		float x, y, z, turb;
+		float xyz[] = new float[3], turb;
 		int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
 		float turbul = ((Number) tex.getFieldValue("turbul")).floatValue() / 5.0f;
 		float[] texvec = new float[] { 0, 0, 0 };
-		TexResult texres = new TexResult();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
-		int halfW = width, halfH = height, halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
-
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * 4);
+		TextureResult texres = new TextureResult();
+		int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
+		float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
+		BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
+		
+		byte[] data = new byte[width * height * depth * 3];
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j;
 				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);
+					texvec[2] = dDelta * k;
+					xyz[0] = (float) Math.sin((texvec[0] + texvec[1] + texvec[2]) * 5.0f);
+					xyz[1] = (float) Math.cos((-texvec[0] + texvec[1] - texvec[2]) * 5.0f);
+					xyz[2] = -(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);
+						texres.intensity = 0.3333f * (xyz[0] + xyz[1] + xyz[2]);
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
 					} 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;
-															}
-														}
-													}
-												}
-											}
-										}
-									}
-								}
+							xyz[0] *= turb;
+							xyz[1] *= turb;
+							xyz[2] *= turb;
+							for (int m=0;m<noisedepth;++m) {
+								noiseDepthFunctions[m].compute(xyz, turb);
 							}
 						}
 
 						if (turb != 0.0f) {
 							turb *= 2.0f;
-							x /= turb;
-							y /= turb;
-							z /= turb;
+							xyz[0] /= turb;
+							xyz[1] /= turb;
+							xyz[2] /= turb;
 						}
-						texres.tr = 0.5f - x;
-						texres.tg = 0.5f - y;
-						texres.tb = 0.5f - z;
+						texres.red = 0.5f - xyz[0];
+						texres.green = 0.5f - xyz[1];
+						texres.blue = 0.5f - xyz[2];
 					}
-					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));
+					this.applyBrightnessAndContrast(bacd, texres);
+					data[index++] = (byte) (texres.red * 255.0f);
+					data[index++] = (byte) (texres.green * 255.0f);
+					data[index++] = (byte) (texres.blue * 255.0f);
 				}
 			}
 		}
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
-		return new Texture3D(new Image(Format.ABGR8, width, height, depth, dataArray));
+		dataArray.add(BufferUtils.createByteBuffer(data));
+		return new Texture3D(new Image(Format.RGB8, width, height, depth, dataArray));
+	}
+	
+	private static interface NoiseDepthFunction {
+		void compute(float[] xyz, float turbulence);
 	}
 }

+ 94 - 56
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMarble.java

@@ -1,32 +1,33 @@
 /*
- *
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * Copyright (c) 2009-2010 jMonkeyEngine
  * All rights reserved.
  *
- * The Original Code is: all of this file.
+ * 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.
  *
- * Contributor(s): none yet.
+ * * 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.
  *
- * ***** END GPL LICENSE BLOCK *****
+ * * 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;
 
@@ -35,8 +36,6 @@ import java.util.ArrayList;
 
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -47,8 +46,12 @@ import com.jme3.util.BufferUtils;
  * This class generates the 'marble' texture.
  * @author Marcin Roguski (Kaelthas)
  */
-public class TextureGeneratorMarble extends TextureGenerator {
-
+public class TextureGeneratorMarble extends TextureGeneratorWood {
+	// tex->stype
+    protected static final int TEX_SOFT = 0;
+    protected static final int TEX_SHARP = 1;
+    protected static final int TEX_SHARPER = 2;
+    
 	/**
 	 * Constructor stores the given noise generator.
 	 * @param noiseGenerator
@@ -60,51 +63,86 @@ public class TextureGeneratorMarble extends TextureGenerator {
 
 	@Override
 	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
-		// preparing the proper data
-		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
-		float bright = ((Number) tex.getFieldValue("bright")).floatValue();
-		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
 		float[] texvec = new float[] { 0, 0, 0 };
-		TexResult texres = new TexResult();
-		int halfW = width, halfH = height, halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
+		TextureResult texres = new TextureResult();
+		int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
+		float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
-
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
+		BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
+		MarbleData marbleData = new MarbleData(tex);
+		
+		byte[] data = new byte[width * height * depth * bytesPerPixel];
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j;
 				for (int k = -halfD; k < halfD; ++k) {
 					texvec[2] = dDelta * k;
-					texres.tin = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
+					texres.intensity = this.marbleInt(marbleData, texvec[0], texvec[1], texvec[2]);
 					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));
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
+						
+						this.applyBrightnessAndContrast(bacd, texres);
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
 					} else {
-						noiseGenerator.brightnesAndContrast(texres, contrast, bright);
-						data.put((byte) (texres.tin * 255.0f));
+						this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
+						data[index++] = (byte) (texres.intensity * 255.0f);
 					}
 				}
 			}
 		}
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
+		dataArray.add(BufferUtils.createByteBuffer(data));
 		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
+	
+    public float marbleInt(MarbleData marbleData, float x, float y, float z) {
+    	int waveform;
+        if (marbleData.waveform > TEX_TRI || marbleData.waveform < TEX_SIN) {
+        	waveform = 0;
+        } else {
+        	waveform = marbleData.waveform;
+        }
+
+        float n = 5.0f * (x + y + z);
+        float mi = n + marbleData.turbul * NoiseGenerator.NoiseFunctions.turbulence(x, y, z, marbleData.noisesize, marbleData.noisedepth, marbleData.noisebasis, marbleData.isHard);
+
+        if (marbleData.stype >= TEX_SOFT) {
+            mi = waveformFunctions[waveform].execute(mi);
+            if (marbleData.stype == TEX_SHARP) {
+                mi = (float) Math.sqrt(mi);
+            } else if (marbleData.stype == TEX_SHARPER) {
+                mi = (float) Math.sqrt(Math.sqrt(mi));
+            }
+        }
+        return mi;
+    }
+    
+    private static class MarbleData {
+    	public final float noisesize;
+    	public final int noisebasis;
+    	public final int noisedepth;
+    	public final int stype;
+    	public final float turbul;
+    	public final int waveform;
+    	public final boolean isHard;
+        
+        public MarbleData(Structure tex) {
+        	noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
+            noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
+            noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
+            stype = ((Number) tex.getFieldValue("stype")).intValue();
+            turbul = ((Number) tex.getFieldValue("turbul")).floatValue();
+            int noisetype = ((Number) tex.getFieldValue("noisetype")).intValue();
+            waveform = ((Number) tex.getFieldValue("noisebasis2")).intValue();
+            isHard = noisetype != TEX_NOISESOFT;
+		}
+    }
 }

+ 78 - 54
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMusgrave.java

@@ -1,32 +1,33 @@
 /*
- *
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * Copyright (c) 2009-2010 jMonkeyEngine
  * All rights reserved.
  *
- * The Original Code is: all of this file.
+ * 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.
  *
- * Contributor(s): none yet.
+ * * 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.
  *
- * ***** END GPL LICENSE BLOCK *****
+ * * 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;
 
@@ -35,8 +36,7 @@ import java.util.ArrayList;
 
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
+import com.jme3.scene.plugins.blender.textures.NoiseGenerator.MusgraveFunction;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -62,52 +62,76 @@ public class TextureGeneratorMusgrave extends TextureGenerator {
 	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
 		int stype = ((Number) tex.getFieldValue("stype")).intValue();
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
-		TexResult texres = new TexResult();
+		TextureResult texres = new TextureResult();
 		float[] texvec = new float[] { 0, 0, 0 };
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
-		int halfW = width, halfH = height, halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
+		int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
+		float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
-
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
+		MusgraveData musgraveData = new MusgraveData(tex);
+		MusgraveFunction musgraveFunction;
+		BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
+		
+		byte[] data = new byte[width * height * depth * bytesPerPixel];
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i / noisesize;
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j / noisesize;
 				for (int k = -halfD; k < halfD; ++k) {
 					texvec[2] = dDelta * k / 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);
+					musgraveFunction = NoiseGenerator.musgraveFunctions.get(Integer.valueOf(musgraveData.stype));
+					if(musgraveFunction==null) {
+						throw new IllegalStateException("Unknown type of musgrave texture: " + stype);
 					}
+					texres.intensity = musgraveData.outscale * musgraveFunction.execute(musgraveData, texvec[0], texvec[1], texvec[2]);
+					if(texres.intensity>1) {
+						texres.intensity = 1.0f;
+					} else if(texres.intensity < 0) {
+						texres.intensity = 0.0f;
+					}
+					
 					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));
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
+						
+						this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
 					} else {
-						data.put((byte) (texres.tin * 255.0f));
+						this.applyBrightnessAndContrast(bacd, texres);
+						data[index++] = (byte) (texres.intensity * 255.0f);
 					}
 				}
 			}
 		}
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
+		dataArray.add(BufferUtils.createByteBuffer(data));
 		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
+	
+    protected static class MusgraveData {
+    	public final int stype;
+    	public final float outscale;
+    	public final float h;
+    	public final float lacunarity;
+    	public final float octaves;
+    	public final int noisebasis;
+    	public final float offset;
+    	public final float gain;
+        
+    	public MusgraveData(Structure tex) {
+    		stype = ((Number) tex.getFieldValue("stype")).intValue();
+            outscale = ((Number) tex.getFieldValue("ns_outscale")).floatValue();
+            h = ((Number) tex.getFieldValue("mg_H")).floatValue();
+            lacunarity = ((Number) tex.getFieldValue("mg_lacunarity")).floatValue();
+            octaves = ((Number) tex.getFieldValue("mg_octaves")).floatValue();
+            noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
+            offset = ((Number) tex.getFieldValue("mg_offset")).floatValue();
+            gain = ((Number) tex.getFieldValue("mg_gain")).floatValue();
+		}
+    }
 }

+ 48 - 51
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorNoise.java

@@ -1,32 +1,33 @@
 /*
- *
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * Copyright (c) 2009-2010 jMonkeyEngine
  * All rights reserved.
  *
- * The Original Code is: all of this file.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * Contributor(s): none yet.
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
  *
- * ***** END GPL LICENSE BLOCK *****
+ * * 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;
 
@@ -36,8 +37,6 @@ import java.util.ArrayList;
 import com.jme3.math.FastMath;
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -61,49 +60,47 @@ public class TextureGeneratorNoise extends TextureGenerator {
 
 	@Override
 	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
-		float div = 3.0f;
-		int val, ran, loop;
+		int val, random, loop;
 		int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
-		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
-		float brightness = ((Number) tex.getFieldValue("bright")).floatValue();
-		TexResult texres = new TexResult();
-		int halfW = width, halfH = height, halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
+		TextureResult texres = new TextureResult();
+		int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
-
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
+		BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
+		
+		byte[] data = new byte[width * height * depth * bytesPerPixel];
 		for (int i = -halfW; i < halfW; ++i) {
 			for (int j = -halfH; j < halfH; ++j) {
 				for (int k = -halfD; k < halfD; ++k) {
-					ran = FastMath.rand.nextInt();// BLI_rand();
-					val = ran & 3;
+					random = FastMath.rand.nextInt();
+					val = random & 3;
 
 					loop = noisedepth;
 					while (loop-- != 0) {
-						ran = ran >> 2;
-						val *= ran & 3;
-						div *= 3.0f;
+						random >>= 2;
+						val *= random & 3;
 					}
-					texres.tin = val;// / div;
+					texres.intensity = val;
 					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));
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
+						
+						this.applyBrightnessAndContrast(bacd, texres);
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
 					} else {
-						noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
-						data.put((byte) (texres.tin * 255.0f));
+						this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
+						data[index++] = (byte) (texres.intensity * 255.0f);
 					}
 				}
 			}
 		}
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
+		dataArray.add(BufferUtils.createByteBuffer(data));
 		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 }

+ 52 - 61
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorStucci.java

@@ -1,32 +1,33 @@
 /*
- *
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * Copyright (c) 2009-2010 jMonkeyEngine
  * All rights reserved.
  *
- * The Original Code is: all of this file.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * Contributor(s): none yet.
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
  *
- * ***** END GPL LICENSE BLOCK *****
+ * * 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;
 
@@ -35,8 +36,6 @@ import java.util.ArrayList;
 
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -48,7 +47,8 @@ import com.jme3.util.BufferUtils;
  * @author Marcin Roguski (Kaelthas)
  */
 public class TextureGeneratorStucci extends TextureGenerator {
-
+	protected static final int TEX_NOISESOFT = 0;
+	
 	/**
 	 * Constructor stores the given noise generator.
 	 * @param noiseGenerator
@@ -64,70 +64,61 @@ public class TextureGeneratorStucci extends TextureGenerator {
 		int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
 		int noisetype = ((Number) tex.getFieldValue("noisetype")).intValue();
 		float turbul = ((Number) tex.getFieldValue("turbul")).floatValue();
-		boolean isHard = noisetype != NoiseGenerator.TEX_NOISESOFT;
+		boolean isHard = noisetype != TEX_NOISESOFT;
 		int stype = ((Number) tex.getFieldValue("stype")).intValue();
 
+		if(noisesize<=0.001f) {//the texture goes black if this value is lower than 0.001f
+			noisesize = 0.001f;
+		}
+		
 		float[] texvec = new float[] { 0, 0, 0 };
-		TexResult texres = new TexResult();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth, b2, ofs;
-		int halfW = width, halfH = height, halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
+		TextureResult texres = new TextureResult();
+		int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
+		float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD, noiseValue, ofs;;
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
+		byte[] data = new byte[width * height * depth * bytesPerPixel];
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 				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);
-
+					noiseValue = NoiseGenerator.NoiseFunctions.noise(texvec[0], texvec[1], texvec[2], noisesize, 0, noisebasis, isHard);
 					ofs = turbul / 200.0f;
-
 					if (stype != 0) {
-						ofs *= b2 * b2;
+						ofs *= noiseValue * noiseValue;
 					}
 
-					texres.tin = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2] + ofs, isHard, noisebasis);// ==nor[2]
+					texres.intensity = NoiseGenerator.NoiseFunctions.noise(texvec[0], texvec[1], texvec[2] + ofs, noisesize, 0, noisebasis, isHard);
 					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];
-							}
-						}
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
 					}
 
 					if (stype == NoiseGenerator.TEX_WALLOUT) {
-						texres.tin = 1.0f - texres.tin;
+						texres.intensity = 1.0f - texres.intensity;
 					}
-					if (texres.tin < 0.0f) {
-						texres.tin = 0.0f;
+					if (texres.intensity < 0.0f) {
+						texres.intensity = 0.0f;
 					}
+					//no brightness and contrast needed for stucci (it doesn't affect the texture)
 					if (colorBand != null) {
-						data.put((byte) (texres.tr * 255.0f));
-						data.put((byte) (texres.tg * 255.0f));
-						data.put((byte) (texres.tb * 255.0f));
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
 					} else {
-						data.put((byte) (texres.tin * 255.0f));
+						data[index++] = (byte) (texres.intensity * 255.0f);
 					}
 				}
 			}
 		}
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
+		dataArray.add(BufferUtils.createByteBuffer(data));
 		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
 }

+ 101 - 107
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorVoronoi.java

@@ -1,32 +1,33 @@
 /*
- *
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * Copyright (c) 2009-2010 jMonkeyEngine
  * All rights reserved.
  *
- * The Original Code is: all of this file.
+ * 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.
  *
- * Contributor(s): none yet.
+ * * 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.
  *
- * ***** END GPL LICENSE BLOCK *****
+ * * 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;
 
@@ -36,8 +37,7 @@ import java.util.ArrayList;
 import com.jme3.math.FastMath;
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
+import com.jme3.scene.plugins.blender.textures.NoiseGenerator.NoiseMath;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -61,115 +61,109 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
 
 	@Override
 	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
-		float vn_w1 = ((Number) tex.getFieldValue("vn_w1")).floatValue();
-		float vn_w2 = ((Number) tex.getFieldValue("vn_w2")).floatValue();
-		float vn_w3 = ((Number) tex.getFieldValue("vn_w3")).floatValue();
-		float vn_w4 = ((Number) tex.getFieldValue("vn_w4")).floatValue();
+		float voronoiWeight1 = ((Number) tex.getFieldValue("vn_w1")).floatValue();
+		float voronoiWeight2 = ((Number) tex.getFieldValue("vn_w2")).floatValue();
+		float voronoiWeight3 = ((Number) tex.getFieldValue("vn_w3")).floatValue();
+		float voronoiWeight4 = ((Number) tex.getFieldValue("vn_w4")).floatValue();
 		float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
-		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
-		float ns_outscale = ((Number) tex.getFieldValue("ns_outscale")).floatValue();
-		float vn_mexp = ((Number) tex.getFieldValue("vn_mexp")).floatValue();
-		int vn_distm = ((Number) tex.getFieldValue("vn_distm")).intValue();
-		int vn_coltype = ((Number) tex.getFieldValue("vn_coltype")).intValue();
-		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
-		float brightness = ((Number) tex.getFieldValue("bright")).floatValue();
+		float outscale = ((Number) tex.getFieldValue("ns_outscale")).floatValue();
+		float mexp = ((Number) tex.getFieldValue("vn_mexp")).floatValue();
+		int distm = ((Number) tex.getFieldValue("vn_distm")).intValue();
+		int voronoiColorType = ((Number) tex.getFieldValue("vn_coltype")).intValue();
 
-		TexResult texres = new TexResult();
+		TextureResult texres = new TextureResult();
 		float[] texvec = new float[] { 0, 0, 0 };
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
-		int halfW = width, halfH = height, halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
-		Format format = vn_coltype != 0 || colorBand != null ? Format.RGB8 : Format.Luminance8;
-		int bytesPerPixel = vn_coltype != 0 || colorBand != null ? 3 : 1;
-
-		float[] da = new float[4], pa = new float[12]; /* distance and point coordinate arrays of 4 nearest neighbours */
-		float[] ca = vn_coltype != 0 ? new float[3] : null; // cell color
-		float aw1 = FastMath.abs(vn_w1);
-		float aw2 = FastMath.abs(vn_w2);
-		float aw3 = FastMath.abs(vn_w3);
-		float aw4 = FastMath.abs(vn_w4);
-		float sc = aw1 + aw2 + aw3 + aw4;
-		if (sc != 0.f) {
-			sc = ns_outscale / sc;
+		int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
+		float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
+		
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
+		Format format = voronoiColorType != 0 || colorBand != null ? Format.RGB8 : Format.Luminance8;
+		int bytesPerPixel = voronoiColorType != 0 || colorBand != null ? 3 : 1;
+		BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
+		
+		float[] da = new float[4], pa = new float[12];
+		float[] hashPoint = voronoiColorType != 0 ? new float[3] : null;
+		float[] voronoiWeights = new float[] {FastMath.abs(voronoiWeight1), FastMath.abs(voronoiWeight2), 
+											  FastMath.abs(voronoiWeight3), FastMath.abs(voronoiWeight4)};
+		float weight;
+		float sc = voronoiWeights[0] + voronoiWeights[1] + voronoiWeights[2] + voronoiWeights[3];
+		if (sc != 0.0f) {
+			sc = outscale / sc;
 		}
 
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
+		byte[] data = new byte[width * height * depth * bytesPerPixel];
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i / noisesize;
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j / noisesize;
 				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) {
+					NoiseGenerator.NoiseFunctions.voronoi(texvec[0], texvec[1], texvec[2], da, pa, mexp, distm);
+					texres.intensity = sc * FastMath.abs(voronoiWeight1 * da[0] + voronoiWeight2 * da[1] + voronoiWeight3 * da[2] + voronoiWeight4 * da[3]);
+					if(texres.intensity>1.0f) {
+						texres.intensity = 1.0f;
+					} else if(texres.intensity<0.0f) {
+						texres.intensity = 0.0f;
+					}
+					
+					if (colorBand != null) {//colorband ALWAYS goes first and covers the color (if set)
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
+					} else if (voronoiColorType != 0) {
+						texres.red = texres.green = texres.blue = 0.0f;
+						for(int m=0; m<12; m+=3) {
+							weight = voronoiWeights[m/3];
+							this.cellNoiseV(pa[m], pa[m + 1], pa[m + 2], hashPoint);
+							texres.red += weight * hashPoint[0];
+							texres.green += weight * hashPoint[1];
+							texres.blue += weight * hashPoint[2];
+						}
+						if (voronoiColorType >= 2) {
 							float t1 = (da[1] - da[0]) * 10.0f;
-							if (t1 > 1) {
+							if (t1 > 1.0f) {
 								t1 = 1.0f;
 							}
-							if (vn_coltype == 3) {
-								t1 *= texres.tin;
+							if (voronoiColorType == 3) {
+								t1 *= texres.intensity;
 							} else {
 								t1 *= sc;
 							}
-							texres.tr *= t1;
-							texres.tg *= t1;
-							texres.tb *= t1;
+							texres.red *= t1;
+							texres.green *= t1;
+							texres.blue *= 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);
+							texres.red *= sc;
+							texres.green *= sc;
+							texres.blue *= sc;
 						}
 					}
 
-					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));
+					if (voronoiColorType != 0 || colorBand != null) {
+						this.applyBrightnessAndContrast(bacd, texres);
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
 					} else {
-						noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
-						data.put((byte) (texres.tin * 255.0f));
+						this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
+						data[index++] = (byte) (texres.intensity * 255.0f);
 					}
 				}
 			}
 		}
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
+		dataArray.add(BufferUtils.createByteBuffer(data));
 		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
+	
+	/**
+     * Returns a vector/point/color in ca, using point hasharray directly
+     */
+    private void cellNoiseV(float x, float y, float z, float[] hashPoint) {
+        int xi = (int) Math.floor(x);
+        int yi = (int) Math.floor(y);
+        int zi = (int) Math.floor(z);
+        NoiseMath.hash(xi, yi, zi, hashPoint);
+    }
 }

+ 138 - 33
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorWood.java

@@ -33,10 +33,9 @@ package com.jme3.scene.plugins.blender.textures;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 
+import com.jme3.math.FastMath;
 import com.jme3.scene.plugins.blender.DataRepository;
 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.TexResult;
 import com.jme3.texture.Image;
 import com.jme3.texture.Image.Format;
 import com.jme3.texture.Texture;
@@ -48,7 +47,21 @@ import com.jme3.util.BufferUtils;
  * @author Marcin Roguski (Kaelthas)
  */
 public class TextureGeneratorWood extends TextureGenerator {
-
+	// tex->noisebasis2
+    protected static final int TEX_SIN = 0;
+    protected static final int TEX_SAW = 1;
+    protected static final int TEX_TRI = 2;
+    
+    // tex->stype
+    protected static final int TEX_BAND = 0;
+    protected static final int TEX_RING = 1;
+    protected static final int TEX_BANDNOISE = 2;
+    protected static final int TEX_RINGNOISE = 3;
+    
+    // tex->noisetype
+    protected static final int TEX_NOISESOFT = 0;
+    protected static final int TEX_NOISEPERL = 1;
+    
 	/**
 	 * Constructor stores the given noise generator.
 	 * @param noiseGenerator the noise generator
@@ -59,53 +72,145 @@ public class TextureGeneratorWood extends TextureGenerator {
 
 	@Override
 	protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) {
-		// preparing the proper data
-		float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
-		float bright = ((Number) tex.getFieldValue("bright")).floatValue();
-		float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
-		float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth;
 		float[] texvec = new float[] { 0, 0, 0 };
-		TexResult texres = new TexResult();
-		int halfW = width;
-		int halfH = height;
-		int halfD = depth;
-		width <<= 1;
-		height <<= 1;
-		depth <<= 1;
+		TextureResult texres = new TextureResult();
+		int halfW = width >> 1;
+		int halfH = height >> 1;
+		int halfD = depth >> 1;
+		float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
 		
-		ColorBand colorBand = this.readColorband(tex, dataRepository);
+		float[][] colorBand = this.computeColorband(tex, dataRepository);
 		Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
 		int bytesPerPixel = colorBand != null ? 3 : 1;
-
-		ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel);
+		WoodIntensityData woodIntensityData = new WoodIntensityData(tex);
+		BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
+		
+		int index = 0;
+		byte[] data = new byte[width * height * depth * bytesPerPixel];
 		for (int i = -halfW; i < halfW; ++i) {
 			texvec[0] = wDelta * i;
 			for (int j = -halfH; j < halfH; ++j) {
 				texvec[1] = hDelta * j;
 				for(int k = -halfD; k < halfD; ++k) {
 					texvec[2] = dDelta * k;
-					texres.tin = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
+					texres.intensity = this.woodIntensity(woodIntensityData, texvec[0], texvec[1], texvec[2]);
+					
 					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));
+						int colorbandIndex = (int) (texres.intensity * 1000.0f);
+						texres.red = colorBand[colorbandIndex][0];
+						texres.green = colorBand[colorbandIndex][1];
+						texres.blue = colorBand[colorbandIndex][2];
+						
+						this.applyBrightnessAndContrast(bacd, texres);
+						
+						data[index++] = (byte) (texres.red * 255.0f);
+						data[index++] = (byte) (texres.green * 255.0f);
+						data[index++] = (byte) (texres.blue * 255.0f);
 					} else {
-						noiseGenerator.brightnesAndContrast(texres, contrast, bright);
-						data.put((byte) (texres.tin * 255));
+						this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
+						data[index++] = (byte) (texres.intensity * 255.0f);
 					}
 				}
 			}
 		}
+		
 		ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
-		dataArray.add(data);
+		dataArray.add(BufferUtils.createByteBuffer(data));
 		return new Texture3D(new Image(format, width, height, depth, dataArray));
 	}
+	
+    protected static WaveForm[] waveformFunctions = new WaveForm[3];
+    static {
+        waveformFunctions[0] = new WaveForm() {// sinus (TEX_SIN)
+
+            @Override
+            public float execute(float x) {
+                return 0.5f + 0.5f * (float) Math.sin(x);
+            }
+        };
+        waveformFunctions[1] = new WaveForm() {// saw (TEX_SAW)
+
+            @Override
+            public float execute(float x) {
+                int n = (int) (x * FastMath.INV_TWO_PI);
+                x -= n * FastMath.TWO_PI;
+                if (x < 0.0f) {
+                    x += FastMath.TWO_PI;
+                }
+                return x * FastMath.INV_TWO_PI;
+            }
+        };
+        waveformFunctions[2] = new WaveForm() {// triangle (TEX_TRI)
+
+            @Override
+            public float execute(float x) {
+                return 1.0f - 2.0f * FastMath.abs((float) Math.floor(x * FastMath.INV_TWO_PI + 0.5f) - x * FastMath.INV_TWO_PI);
+            }
+        };
+    }
+
+    /**
+     * Computes basic wood intensity value at x,y,z.
+     * @param woodIntData
+     * @param x X coordinate of the texture pixel
+     * @param y Y coordinate of the texture pixel
+     * @param z Z coordinate of the texture pixel
+     * @return wood intensity at position [x, y, z]
+     */
+    public float woodIntensity(WoodIntensityData woodIntData, float x, float y, float z) {
+        float result;
+
+        switch(woodIntData.woodType) {
+	        case TEX_BAND:
+	        	result = woodIntData.waveformFunction.execute((x + y + z) * 10.0f);
+	        	break;
+	        case TEX_RING:
+	        	result = woodIntData.waveformFunction.execute((float) Math.sqrt(x * x + y * y + z * z) * 20.0f);
+	        	break;
+	        case TEX_BANDNOISE:
+	        	result = woodIntData.turbul * NoiseGenerator.NoiseFunctions.noise(x, y, z, woodIntData.noisesize, 0, woodIntData.noisebasis, woodIntData.isHard);
+	            result = woodIntData.waveformFunction.execute((x + y + z) * 10.0f + result);
+	        	break;
+	        case TEX_RINGNOISE:
+	        	result = woodIntData.turbul * NoiseGenerator.NoiseFunctions.noise(x, y, z, woodIntData.noisesize, 0, woodIntData.noisebasis, woodIntData.isHard);
+	            result = woodIntData.waveformFunction.execute((float) Math.sqrt(x * x + y * y + z * z) * 20.0f + result);
+	        	break;
+        	default:
+        		result = 0;
+        }
+        return result;
+    }
+    
+    /**
+     * A class that collects the data for wood intensity calculations.
+     * @author Marcin Roguski (Kaelthas)
+     */
+    private static class WoodIntensityData {
+    	public final WaveForm waveformFunction;
+    	public final int noisebasis;
+    	public final float noisesize;
+    	public final float turbul;
+    	public final int noiseType;
+    	public final int woodType;
+    	public final boolean isHard;
+        
+    	public WoodIntensityData(Structure tex) {
+    		int waveform = ((Number) tex.getFieldValue("noisebasis2")).intValue();//wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2
+    		if (waveform > TEX_TRI || waveform < TEX_SIN) {
+                waveform = 0; // check to be sure noisebasis2 is initialized ahead of time
+            }
+    		waveformFunction = waveformFunctions[waveform];
+    		noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
+            woodType = ((Number) tex.getFieldValue("stype")).intValue();
+            noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
+            turbul = ((Number) tex.getFieldValue("turbul")).floatValue();
+            noiseType = ((Number) tex.getFieldValue("noisetype")).intValue();
+            isHard = noiseType != TEX_NOISESOFT;
+		}
+    }
+    
+    protected static interface WaveForm {
+
+        float execute(float x);
+    }
 }

+ 188 - 510
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java

@@ -34,8 +34,6 @@ package com.jme3.scene.plugins.blender.textures;
 import java.awt.color.ColorSpace;
 import java.awt.image.BufferedImage;
 import java.awt.image.ColorConvertOp;
-import java.io.IOException;
-import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -58,7 +56,6 @@ import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
 import com.jme3.scene.plugins.blender.DataRepository;
 import com.jme3.scene.plugins.blender.DataRepository.LoadedFeatureDataType;
 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
-import com.jme3.scene.plugins.blender.file.DynamicArray;
 import com.jme3.scene.plugins.blender.file.FileBlockHeader;
 import com.jme3.scene.plugins.blender.file.Pointer;
 import com.jme3.scene.plugins.blender.file.Structure;
@@ -78,7 +75,7 @@ import com.jme3.util.BufferUtils;
  */
 public class TextureHelper extends AbstractBlenderHelper {
 	private static final Logger	LOGGER				= Logger.getLogger(TextureHelper.class.getName());
-	
+
 	// texture types
 	public static final int		TEX_NONE			= 0;
 	public static final int		TEX_CLOUDS			= 1;
@@ -95,8 +92,8 @@ public class TextureHelper extends AbstractBlenderHelper {
 	public static final int		TEX_VORONOI			= 12;
 	public static final int		TEX_DISTNOISE		= 13;
 	public static final int 	TEX_POINTDENSITY 	= 14;//v. 25+
-    public static final int 	TEX_VOXELDATA 		= 15;//v. 25+
-    
+	public static final int 	TEX_VOXELDATA 		= 15;//v. 25+
+
 	// mapto
 	public static final int		MAP_COL				= 1;
 	public static final int		MAP_NORM			= 2;
@@ -132,27 +129,9 @@ public class TextureHelper extends AbstractBlenderHelper {
 	public static final int		MTEX_BLEND_COLOR	= 13;
 	public static final int		MTEX_NUM_BLENDTYPES	= 14;
 
-	// variables used in rampBlend method
-	public static final int		MA_RAMP_BLEND		= 0;
-	public static final int		MA_RAMP_ADD			= 1;
-	public static final int		MA_RAMP_MULT		= 2;
-	public static final int		MA_RAMP_SUB			= 3;
-	public static final int		MA_RAMP_SCREEN		= 4;
-	public static final int		MA_RAMP_DIV			= 5;
-	public static final int		MA_RAMP_DIFF		= 6;
-	public static final int		MA_RAMP_DARK		= 7;
-	public static final int		MA_RAMP_LIGHT		= 8;
-	public static final int		MA_RAMP_OVERLAY		= 9;
-	public static final int		MA_RAMP_DODGE		= 10;
-	public static final int		MA_RAMP_BURN		= 11;
-	public static final int		MA_RAMP_HUE			= 12;
-	public static final int		MA_RAMP_SAT			= 13;
-	public static final int		MA_RAMP_VAL			= 14;
-	public static final int		MA_RAMP_COLOR		= 15;
-
 	protected NoiseGenerator noiseGenerator;
 	private Map<Integer, TextureGenerator> textureGenerators = new HashMap<Integer, TextureGenerator>();
-	
+
 	/**
 	 * This constructor parses the given blender version and stores the result.
 	 * It creates noise generator and texture generators.
@@ -196,42 +175,42 @@ public class TextureHelper extends AbstractBlenderHelper {
 		int width = dataRepository.getBlenderKey().getGeneratedTextureWidth();
 		int height = dataRepository.getBlenderKey().getGeneratedTextureHeight();
 		int depth = dataRepository.getBlenderKey().getGeneratedTextureDepth();
-		
+
 		switch (type) {
-			case TEX_IMAGE:// (it is first because probably this will be most commonly used)
-				Pointer pImage = (Pointer) tex.getFieldValue("ima");
-                if (pImage.isNotNull()){
-                    Structure image = pImage.fetchData(dataRepository.getInputStream()).get(0);
-                    result = this.getTextureFromImage(image, dataRepository);
-                }
-				break;
-			case TEX_CLOUDS:
-			case TEX_WOOD:
-			case TEX_MARBLE:
-			case TEX_MAGIC:
-			case TEX_BLEND:
-			case TEX_STUCCI:
-			case TEX_NOISE:
-			case TEX_MUSGRAVE:
-			case TEX_VORONOI:
-			case TEX_DISTNOISE:
-				TextureGenerator textureGenerator = textureGenerators.get(Integer.valueOf(type));
-				result = textureGenerator.generate(tex, width, height, depth, dataRepository);
-				break;
-			case TEX_NONE:// No texture, do nothing
-				break;
-			case TEX_POINTDENSITY:
-                LOGGER.warning("Point density texture loading currently not supported!");
-                break;
-            case TEX_VOXELDATA:
-                LOGGER.warning("Voxel data texture loading currently not supported!");
-                break;
-			case TEX_PLUGIN:
-			case TEX_ENVMAP:// TODO: implement envmap texture
-				LOGGER.log(Level.WARNING, "Unsupported texture type: {0} for texture: {1}", new Object[]{type, tex.getName()});
-				break;
-			default:
-				throw new BlenderFileException("Unknown texture type: " + type + " for texture: " + tex.getName());
+		case TEX_IMAGE:// (it is first because probably this will be most commonly used)
+			Pointer pImage = (Pointer) tex.getFieldValue("ima");
+			if (pImage.isNotNull()){
+				Structure image = pImage.fetchData(dataRepository.getInputStream()).get(0);
+				result = this.getTextureFromImage(image, dataRepository);
+			}
+			break;
+		case TEX_CLOUDS:
+		case TEX_WOOD:
+		case TEX_MARBLE:
+		case TEX_MAGIC:
+		case TEX_BLEND:
+		case TEX_STUCCI:
+		case TEX_NOISE:
+		case TEX_MUSGRAVE:
+		case TEX_VORONOI:
+		case TEX_DISTNOISE:
+			TextureGenerator textureGenerator = textureGenerators.get(Integer.valueOf(type));
+			result = textureGenerator.generate(tex, width, height, depth, dataRepository);
+			break;
+		case TEX_NONE:// No texture, do nothing
+			break;
+		case TEX_POINTDENSITY:
+			LOGGER.warning("Point density texture loading currently not supported!");
+			break;
+		case TEX_VOXELDATA:
+			LOGGER.warning("Voxel data texture loading currently not supported!");
+			break;
+		case TEX_PLUGIN:
+		case TEX_ENVMAP:// TODO: implement envmap texture
+			LOGGER.log(Level.WARNING, "Unsupported texture type: {0} for texture: {1}", new Object[]{type, tex.getName()});
+			break;
+		default:
+			throw new BlenderFileException("Unknown texture type: " + type + " for texture: " + tex.getName());
 		}
 		if (result != null) {
 			result.setName(tex.getName());
@@ -282,7 +261,7 @@ public class TextureHelper extends AbstractBlenderHelper {
 			newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
 			newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
 			newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
-            newData.put(dataIndex++, (byte) 255.0f);//1.0f * 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));
@@ -312,88 +291,87 @@ public class TextureHelper extends AbstractBlenderHelper {
 	 * @return texture intensity for the current pixel
 	 */
 	protected float setupMaterialColor(ByteBuffer data, Format imageFormat, boolean neg, float[] materialColor) {
-		// at least one byte is always taken :)
 		float tin = 0.0f;
-		byte pixelValue = data.get();
+		byte pixelValue = data.get();// at least one byte is always taken :)
 		float firstPixelValue = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
 		switch (imageFormat) {
-			case ABGR8:
-				pixelValue = data.get();
-				materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
-				pixelValue = data.get();
-				materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
-				pixelValue = data.get();
-				materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
-				break;
-			case BGR8:
-				materialColor[2] = firstPixelValue;
-				pixelValue = data.get();
-				materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
-				pixelValue = data.get();
-				materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
-				break;
-			case RGB8:
-				materialColor[0] = firstPixelValue;
-				pixelValue = data.get();
-				materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
-				pixelValue = data.get();
-				materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
-				break;
-			case RGBA8:
-				materialColor[0] = firstPixelValue;
-				pixelValue = data.get();
-				materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
-				pixelValue = data.get();
-				materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
-				data.get(); // ignore alpha
-				break;
-			case Luminance8:
-				tin = neg ? 1.0f - firstPixelValue : firstPixelValue;
-				neg = false;//do not negate the materialColor, it must be unchanged
-				break;
-			case Luminance8Alpha8:
-				tin = neg ? 1.0f - firstPixelValue : firstPixelValue;
-				neg = false;//do not negate the materialColor, it must be unchanged
-				data.get(); // ignore alpha
-				break;
-			case Luminance16:
-			case Luminance16Alpha16:
-			case Alpha16:
-			case Alpha8:
-			case ARGB4444:
-			case Depth:
-			case Depth16:
-			case Depth24:
-			case Depth32:
-			case Depth32F:
-			case DXT1:
-			case DXT1A:
-			case DXT3:
-			case DXT5:
-			case Intensity16:
-			case Intensity8:
-			case LATC:
-			case LTC:
-			case Luminance16F:
-			case Luminance16FAlpha16F:
-			case Luminance32F:
-			case RGB10:
-			case RGB111110F:
-			case RGB16:
-			case RGB16F:
-			case RGB16F_to_RGB111110F:
-			case RGB16F_to_RGB9E5:
-			case RGB32F:
-			case RGB565:
-			case RGB5A1:
-			case RGB9E5:
-			case RGBA16:
-			case RGBA16F:
-			case RGBA32F:
-				LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", imageFormat);
-				break;
-			default:
-				throw new IllegalStateException("Unknown image format type: " + imageFormat);
+		case ABGR8:
+			pixelValue = data.get();
+			materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
+			pixelValue = data.get();
+			materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
+			pixelValue = data.get();
+			materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
+			break;
+		case BGR8:
+			materialColor[2] = firstPixelValue;
+			pixelValue = data.get();
+			materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
+			pixelValue = data.get();
+			materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
+			break;
+		case RGB8:
+			materialColor[0] = firstPixelValue;
+			pixelValue = data.get();
+			materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
+			pixelValue = data.get();
+			materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
+			break;
+		case RGBA8:
+			materialColor[0] = firstPixelValue;
+			pixelValue = data.get();
+			materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
+			pixelValue = data.get();
+			materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
+			data.get(); // ignore alpha
+			break;
+		case Luminance8:
+			tin = neg ? 1.0f - firstPixelValue : firstPixelValue;
+			neg = false;//do not negate the materialColor, it must be unchanged
+			break;
+		case Luminance8Alpha8:
+			tin = neg ? 1.0f - firstPixelValue : firstPixelValue;
+			neg = false;//do not negate the materialColor, it must be unchanged
+			data.get(); // ignore alpha
+			break;
+		case Luminance16:
+		case Luminance16Alpha16:
+		case Alpha16:
+		case Alpha8:
+		case ARGB4444:
+		case Depth:
+		case Depth16:
+		case Depth24:
+		case Depth32:
+		case Depth32F:
+		case DXT1:
+		case DXT1A:
+		case DXT3:
+		case DXT5:
+		case Intensity16:
+		case Intensity8:
+		case LATC:
+		case LTC:
+		case Luminance16F:
+		case Luminance16FAlpha16F:
+		case Luminance32F:
+		case RGB10:
+		case RGB111110F:
+		case RGB16:
+		case RGB16F:
+		case RGB16F_to_RGB111110F:
+		case RGB16F_to_RGB9E5:
+		case RGB32F:
+		case RGB565:
+		case RGB5A1:
+		case RGB9E5:
+		case RGBA16:
+		case RGBA16F:
+		case RGBA32F:
+			LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", imageFormat);
+			break;
+		default:
+			throw new IllegalStateException("Unknown image format type: " + imageFormat);
 		}
 		if (neg) {
 			materialColor[0] = 1.0f - materialColor[0];
@@ -422,64 +400,59 @@ public class TextureHelper extends AbstractBlenderHelper {
 	 *        the data repository
 	 */
 	protected void blendPixel(float[] result, float[] materialColor, float[] color, float textureIntensity, float textureFactor, int blendtype, DataRepository dataRepository) {
-		float facm, col;
-
+		float oneMinusFactor, col;
+		textureIntensity *= textureFactor;
+		
 		switch (blendtype) {
 			case MTEX_BLEND:
-				textureIntensity *= textureFactor;
-				facm = 1.0f - textureIntensity;
-				result[0] = textureIntensity * color[0] + facm * materialColor[0];
-				result[1] = textureIntensity * color[1] + facm * materialColor[1];
-				result[2] = textureIntensity * color[2] + facm * materialColor[2];
+				oneMinusFactor = 1.0f - textureIntensity;
+				result[0] = textureIntensity * color[0] + oneMinusFactor * materialColor[0];
+				result[1] = textureIntensity * color[1] + oneMinusFactor * materialColor[1];
+				result[2] = textureIntensity * color[2] + oneMinusFactor * materialColor[2];
 				break;
 			case MTEX_MUL:
-				textureIntensity *= textureFactor;
-				facm = 1.0f - textureFactor;
-				result[0] = (facm + textureIntensity * materialColor[0]) * color[0];
-				result[1] = (facm + textureIntensity * materialColor[1]) * color[1];
-				result[2] = (facm + textureIntensity * materialColor[2]) * color[2];
+				oneMinusFactor = 1.0f - textureFactor;
+				result[0] = (oneMinusFactor + textureIntensity * materialColor[0]) * color[0];
+				result[1] = (oneMinusFactor + textureIntensity * materialColor[1]) * color[1];
+				result[2] = (oneMinusFactor + textureIntensity * materialColor[2]) * color[2];
 				break;
 			case MTEX_DIV:
-				textureIntensity *= textureFactor;
-				facm = 1.0f - textureIntensity;
+				oneMinusFactor = 1.0f - textureIntensity;
 				if (color[0] != 0.0) {
-					result[0] = (facm * materialColor[0] + textureIntensity * materialColor[0] / color[0]) * 0.5f;
+					result[0] = (oneMinusFactor * materialColor[0] + textureIntensity * materialColor[0] / color[0]) * 0.5f;
 				}
 				if (color[1] != 0.0) {
-					result[1] = (facm * materialColor[1] + textureIntensity * materialColor[1] / color[1]) * 0.5f;
+					result[1] = (oneMinusFactor * materialColor[1] + textureIntensity * materialColor[1] / color[1]) * 0.5f;
 				}
 				if (color[2] != 0.0) {
-					result[2] = (facm * materialColor[2] + textureIntensity * materialColor[2] / color[2]) * 0.5f;
+					result[2] = (oneMinusFactor * materialColor[2] + textureIntensity * materialColor[2] / color[2]) * 0.5f;
 				}
 				break;
 			case MTEX_SCREEN:
-				textureIntensity *= textureFactor;
-				facm = 1.0f - textureFactor;
-				result[0] = 1.0f - (facm + textureIntensity * (1.0f - materialColor[0])) * (1.0f - color[0]);
-				result[1] = 1.0f - (facm + textureIntensity * (1.0f - materialColor[1])) * (1.0f - color[1]);
-				result[2] = 1.0f - (facm + textureIntensity * (1.0f - materialColor[2])) * (1.0f - color[2]);
+				oneMinusFactor = 1.0f - textureFactor;
+				result[0] = 1.0f - (oneMinusFactor + textureIntensity * (1.0f - materialColor[0])) * (1.0f - color[0]);
+				result[1] = 1.0f - (oneMinusFactor + textureIntensity * (1.0f - materialColor[1])) * (1.0f - color[1]);
+				result[2] = 1.0f - (oneMinusFactor + textureIntensity * (1.0f - materialColor[2])) * (1.0f - color[2]);
 				break;
 			case MTEX_OVERLAY:
-				textureIntensity *= textureFactor;
-				facm = 1.0f - textureFactor;
+				oneMinusFactor = 1.0f - textureFactor;
 				if (materialColor[0] < 0.5f) {
-					result[0] = color[0] * (facm + 2.0f * textureIntensity * materialColor[0]);
+					result[0] = color[0] * (oneMinusFactor + 2.0f * textureIntensity * materialColor[0]);
 				} else {
-					result[0] = 1.0f - (facm + 2.0f * textureIntensity * (1.0f - materialColor[0])) * (1.0f - color[0]);
+					result[0] = 1.0f - (oneMinusFactor + 2.0f * textureIntensity * (1.0f - materialColor[0])) * (1.0f - color[0]);
 				}
 				if (materialColor[1] < 0.5f) {
-					result[1] = color[1] * (facm + 2.0f * textureIntensity * materialColor[1]);
+					result[1] = color[1] * (oneMinusFactor + 2.0f * textureIntensity * materialColor[1]);
 				} else {
-					result[1] = 1.0f - (facm + 2.0f * textureIntensity * (1.0f - materialColor[1])) * (1.0f - color[1]);
+					result[1] = 1.0f - (oneMinusFactor + 2.0f * textureIntensity * (1.0f - materialColor[1])) * (1.0f - color[1]);
 				}
 				if (materialColor[2] < 0.5f) {
-					result[2] = color[2] * (facm + 2.0f * textureIntensity * materialColor[2]);
+					result[2] = color[2] * (oneMinusFactor + 2.0f * textureIntensity * materialColor[2]);
 				} else {
-					result[2] = 1.0f - (facm + 2.0f * textureIntensity * (1.0f - materialColor[2])) * (1.0f - color[2]);
+					result[2] = 1.0f - (oneMinusFactor + 2.0f * textureIntensity * (1.0f - materialColor[2])) * (1.0f - color[2]);
 				}
 				break;
 			case MTEX_SUB:
-				textureIntensity *= textureFactor;
 				result[0] = materialColor[0] - textureIntensity * color[0];
 				result[1] = materialColor[1] - textureIntensity * color[1];
 				result[2] = materialColor[2] - textureIntensity * color[2];
@@ -488,20 +461,17 @@ public class TextureHelper extends AbstractBlenderHelper {
 				result[2] = FastMath.clamp(result[2], 0.0f, 1.0f);
 				break;
 			case MTEX_ADD:
-				textureIntensity *= textureFactor;
 				result[0] = (textureIntensity * color[0] + materialColor[0]) * 0.5f;
 				result[1] = (textureIntensity * color[1] + materialColor[1]) * 0.5f;
 				result[2] = (textureIntensity * color[2] + materialColor[2]) * 0.5f;
 				break;
 			case MTEX_DIFF:
-				textureIntensity *= textureFactor;
-				facm = 1.0f - textureIntensity;
-				result[0] = facm * color[0] + textureIntensity * Math.abs(materialColor[0] - color[0]);
-				result[1] = facm * color[1] + textureIntensity * Math.abs(materialColor[1] - color[1]);
-				result[2] = facm * color[2] + textureIntensity * Math.abs(materialColor[2] - color[2]);
+				oneMinusFactor = 1.0f - textureIntensity;
+				result[0] = oneMinusFactor * materialColor[0] + textureIntensity * Math.abs(materialColor[0] - color[0]);
+				result[1] = oneMinusFactor * materialColor[1] + textureIntensity * Math.abs(materialColor[1] - color[1]);
+				result[2] = oneMinusFactor * materialColor[2] + textureIntensity * Math.abs(materialColor[2] - color[2]);
 				break;
 			case MTEX_DARK:
-				textureIntensity *= textureFactor;
 				col = textureIntensity * color[0];
 				result[0] = col < materialColor[0] ? col : materialColor[0];
 				col = textureIntensity * color[1];
@@ -510,7 +480,6 @@ public class TextureHelper extends AbstractBlenderHelper {
 				result[2] = col < materialColor[2] ? col : materialColor[2];
 				break;
 			case MTEX_LIGHT:
-				textureIntensity *= textureFactor;
 				col = textureIntensity * color[0];
 				result[0] = col > materialColor[0] ? col : materialColor[0];
 				col = textureIntensity * color[1];
@@ -519,24 +488,11 @@ public class TextureHelper extends AbstractBlenderHelper {
 				result[2] = col > materialColor[2] ? col : materialColor[2];
 				break;
 			case MTEX_BLEND_HUE:
-				textureIntensity *= textureFactor;
-				System.arraycopy(materialColor, 0, result, 0, 3);
-				this.rampBlend(MA_RAMP_HUE, result, textureIntensity, color, dataRepository);
-				break;
 			case MTEX_BLEND_SAT:
-				textureIntensity *= textureFactor;
-				System.arraycopy(materialColor, 0, result, 0, 3);
-				this.rampBlend(MA_RAMP_SAT, result, textureIntensity, color, dataRepository);
-				break;
 			case MTEX_BLEND_VAL:
-				textureIntensity *= textureFactor;
-				System.arraycopy(materialColor, 0, result, 0, 3);
-				this.rampBlend(MA_RAMP_VAL, result, textureIntensity, color, dataRepository);
-				break;
 			case MTEX_BLEND_COLOR:
-				textureIntensity *= textureFactor;
 				System.arraycopy(materialColor, 0, result, 0, 3);
-				this.rampBlend(MA_RAMP_COLOR, result, textureIntensity, color, dataRepository);
+				this.rampBlend(blendtype, result, textureIntensity, color, dataRepository);
 				break;
 			default:
 				throw new IllegalStateException("Unknown blend type: " + blendtype);
@@ -544,10 +500,10 @@ public class TextureHelper extends AbstractBlenderHelper {
 	}
 
 	/**
-	 * The method that performs the ramp blending (whatever it is :P - copied from blender sources).
+	 * The method that performs the ramp blending.
 	 * 
 	 * @param type
-	 *        the ramp type
+	 *        the blend type
 	 * @param rgb
 	 *        the rgb value where the result is stored
 	 * @param fac
@@ -558,239 +514,60 @@ public class TextureHelper extends AbstractBlenderHelper {
 	 *        the data repository
 	 */
 	protected void rampBlend(int type, float[] rgb, float fac, float[] col, DataRepository dataRepository) {
-		float tmp, facm = 1.0f - fac;
+		float oneMinusFactor = 1.0f - fac;
 		MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class);
 
-		switch (type) {
-			case MA_RAMP_HUE:
-				if (rgb.length == 3) {
+		if (rgb.length >= 3) {
+			switch (type) {
+				case MTEX_BLEND_HUE: {
 					float[] colorTransformResult = new float[3];
 					materialHelper.rgbToHsv(col[0], col[1], col[2], colorTransformResult);
 					if (colorTransformResult[1] != 0.0f) {
 						float colH = colorTransformResult[0];
 						materialHelper.rgbToHsv(rgb[0], rgb[1], rgb[2], colorTransformResult);
 						materialHelper.hsvToRgb(colH, colorTransformResult[1], colorTransformResult[2], colorTransformResult);
-						rgb[0] = facm * rgb[0] + fac * colorTransformResult[0];
-						rgb[1] = facm * rgb[1] + fac * colorTransformResult[1];
-						rgb[2] = facm * rgb[2] + fac * colorTransformResult[2];
+						rgb[0] = oneMinusFactor * rgb[0] + fac * colorTransformResult[0];
+						rgb[1] = oneMinusFactor * rgb[1] + fac * colorTransformResult[1];
+						rgb[2] = oneMinusFactor * rgb[2] + fac * colorTransformResult[2];
 					}
+					break;
 				}
-				break;
-			case MA_RAMP_SAT:
-				if (rgb.length == 3) {
+				case MTEX_BLEND_SAT: {
 					float[] colorTransformResult = new float[3];
 					materialHelper.rgbToHsv(rgb[0], rgb[1], rgb[2], colorTransformResult);
-					float rH = colorTransformResult[0];
-					float rS = colorTransformResult[1];
-					float rV = colorTransformResult[2];
-					if (rS != 0) {
+					float h = colorTransformResult[0];
+					float s = colorTransformResult[1];
+					float v = colorTransformResult[2];
+					if (s != 0.0f) {
 						materialHelper.rgbToHsv(col[0], col[1], col[2], colorTransformResult);
-						materialHelper.hsvToRgb(rH, (facm * rS + fac * colorTransformResult[1]), rV, rgb);
+						materialHelper.hsvToRgb(h, (oneMinusFactor * s + fac * colorTransformResult[1]), v, rgb);
 					}
+					break;
 				}
-				break;
-			case MA_RAMP_VAL:
-				if (rgb.length == 3) {
+				case MTEX_BLEND_VAL: {
 					float[] rgbToHsv = new float[3];
 					float[] colToHsv = new float[3];
 					materialHelper.rgbToHsv(rgb[0], rgb[1], rgb[2], rgbToHsv);
 					materialHelper.rgbToHsv(col[0], col[1], col[2], colToHsv);
-					materialHelper.hsvToRgb(rgbToHsv[0], rgbToHsv[1], (facm * rgbToHsv[2] + fac * colToHsv[2]), rgb);
+					materialHelper.hsvToRgb(rgbToHsv[0], rgbToHsv[1], (oneMinusFactor * rgbToHsv[2] + fac * colToHsv[2]), rgb);
+					break;
 				}
-				break;
-			case MA_RAMP_COLOR:
-				if (rgb.length == 3) {
+				case MTEX_BLEND_COLOR: {
 					float[] rgbToHsv = new float[3];
 					float[] colToHsv = new float[3];
 					materialHelper.rgbToHsv(col[0], col[1], col[2], colToHsv);
 					if (colToHsv[2] != 0) {
 						materialHelper.rgbToHsv(rgb[0], rgb[1], rgb[2], rgbToHsv);
 						materialHelper.hsvToRgb(colToHsv[0], colToHsv[1], rgbToHsv[2], rgbToHsv);
-						rgb[0] = facm * rgb[0] + fac * rgbToHsv[0];
-						rgb[1] = facm * rgb[1] + fac * rgbToHsv[1];
-						rgb[2] = facm * rgb[2] + fac * rgbToHsv[2];
-					}
-				}
-				break;
-			case MA_RAMP_BLEND:
-				rgb[0] = facm * rgb[0] + fac * col[0];
-				if (rgb.length == 3) {
-					rgb[1] = facm * rgb[1] + fac * col[1];
-					rgb[2] = facm * rgb[2] + fac * col[2];
-				}
-				break;
-			case MA_RAMP_ADD:
-				rgb[0] += fac * col[0];
-				if (rgb.length == 3) {
-					rgb[1] += fac * col[1];
-					rgb[2] += fac * col[2];
-				}
-				break;
-			case MA_RAMP_MULT:
-				rgb[0] *= facm + fac * col[0];
-				if (rgb.length == 3) {
-					rgb[1] *= facm + fac * col[1];
-					rgb[2] *= facm + fac * col[2];
-				}
-				break;
-			case MA_RAMP_SCREEN:
-				rgb[0] = 1.0f - (facm + fac * (1.0f - col[0])) * (1.0f - rgb[0]);
-				if (rgb.length == 3) {
-					rgb[1] = 1.0f - (facm + fac * (1.0f - col[1])) * (1.0f - rgb[1]);
-					rgb[2] = 1.0f - (facm + fac * (1.0f - col[2])) * (1.0f - rgb[2]);
-				}
-				break;
-			case MA_RAMP_OVERLAY:
-				if (rgb[0] < 0.5f) {
-					rgb[0] *= facm + 2.0f * fac * col[0];
-				} else {
-					rgb[0] = 1.0f - (facm + 2.0f * fac * (1.0f - col[0])) * (1.0f - rgb[0]);
-				}
-				if (rgb.length == 3) {
-					if (rgb[1] < 0.5f) {
-						rgb[1] *= facm + 2.0f * fac * col[1];
-					} else {
-						rgb[1] = 1.0f - (facm + 2.0f * fac * (1.0f - col[1])) * (1.0f - rgb[1]);
-					}
-					if (rgb[2] < 0.5f) {
-						rgb[2] *= facm + 2.0f * fac * col[2];
-					} else {
-						rgb[2] = 1.0f - (facm + 2.0f * fac * (1.0f - col[2])) * (1.0f - rgb[2]);
-					}
-				}
-				break;
-			case MA_RAMP_SUB:
-				rgb[0] -= fac * col[0];
-				if (rgb.length == 3) {
-					rgb[1] -= fac * col[1];
-					rgb[2] -= fac * col[2];
-				}
-				break;
-			case MA_RAMP_DIV:
-				if (col[0] != 0.0) {
-					rgb[0] = facm * rgb[0] + fac * rgb[0] / col[0];
-				}
-				if (rgb.length == 3) {
-					if (col[1] != 0.0) {
-						rgb[1] = facm * rgb[1] + fac * rgb[1] / col[1];
-					}
-					if (col[2] != 0.0) {
-						rgb[2] = facm * rgb[2] + fac * rgb[2] / col[2];
-					}
-				}
-				break;
-			case MA_RAMP_DIFF:
-				rgb[0] = facm * rgb[0] + fac * Math.abs(rgb[0] - col[0]);
-				if (rgb.length == 3) {
-					rgb[1] = facm * rgb[1] + fac * Math.abs(rgb[1] - col[1]);
-					rgb[2] = facm * rgb[2] + fac * Math.abs(rgb[2] - col[2]);
-				}
-				break;
-			case MA_RAMP_DARK:
-				tmp = fac * col[0];
-				if (tmp < rgb[0]) {
-					rgb[0] = tmp;
-				}
-				if (rgb.length == 3) {
-					tmp = fac * col[1];
-					if (tmp < rgb[1]) {
-						rgb[1] = tmp;
-					}
-					tmp = fac * col[2];
-					if (tmp < rgb[2]) {
-						rgb[2] = tmp;
-					}
-				}
-				break;
-			case MA_RAMP_LIGHT:
-				tmp = fac * col[0];
-				if (tmp > rgb[0]) {
-					rgb[0] = tmp;
-				}
-				if (rgb.length == 3) {
-					tmp = fac * col[1];
-					if (tmp > rgb[1]) {
-						rgb[1] = tmp;
-					}
-					tmp = fac * col[2];
-					if (tmp > rgb[2]) {
-						rgb[2] = tmp;
-					}
-				}
-				break;
-			case MA_RAMP_DODGE:
-				if (rgb[0] != 0.0) {
-					tmp = 1.0f - fac * col[0];
-					if (tmp <= 0.0) {
-						rgb[0] = 1.0f;
-					} else if ((tmp = rgb[0] / tmp) > 1.0) {
-						rgb[0] = 1.0f;
-					} else {
-						rgb[0] = tmp;
-					}
-				}
-				if (rgb.length == 3) {
-					if (rgb[1] != 0.0) {
-						tmp = 1.0f - fac * col[1];
-						if (tmp <= 0.0) {
-							rgb[1] = 1.0f;
-						} else if ((tmp = rgb[1] / tmp) > 1.0) {
-							rgb[1] = 1.0f;
-						} else {
-							rgb[1] = tmp;
-						}
-					}
-					if (rgb[2] != 0.0) {
-						tmp = 1.0f - fac * col[2];
-						if (tmp <= 0.0) {
-							rgb[2] = 1.0f;
-						} else if ((tmp = rgb[2] / tmp) > 1.0) {
-							rgb[2] = 1.0f;
-						} else {
-							rgb[2] = tmp;
-						}
-					}
-
-				}
-				break;
-			case MA_RAMP_BURN:
-				tmp = facm + fac * col[0];
-				if (tmp <= 0.0) {
-					rgb[0] = 0.0f;
-				} else if ((tmp = 1.0f - (1.0f - rgb[0]) / tmp) < 0.0) {
-					rgb[0] = 0.0f;
-				} else if (tmp > 1.0) {
-					rgb[0] = 1.0f;
-				} else {
-					rgb[0] = tmp;
-				}
-
-				if (rgb.length == 3) {
-					tmp = facm + fac * col[1];
-					if (tmp <= 0.0) {
-						rgb[1] = 0.0f;
-					} else if ((tmp = 1.0f - (1.0f - rgb[1]) / tmp) < 0.0) {
-						rgb[1] = 0.0f;
-					} else if (tmp > 1.0) {
-						rgb[1] = 1.0f;
-					} else {
-						rgb[1] = tmp;
-					}
-
-					tmp = facm + fac * col[2];
-					if (tmp <= 0.0) {
-						rgb[2] = 0.0f;
-					} else if ((tmp = 1.0f - (1.0f - rgb[2]) / tmp) < 0.0) {
-						rgb[2] = 0.0f;
-					} else if (tmp > 1.0) {
-						rgb[2] = 1.0f;
-					} else {
-						rgb[2] = tmp;
+						rgb[0] = oneMinusFactor * rgb[0] + fac * rgbToHsv[0];
+						rgb[1] = oneMinusFactor * rgb[1] + fac * rgbToHsv[1];
+						rgb[2] = oneMinusFactor * rgb[2] + fac * rgbToHsv[2];
 					}
+					break;
 				}
-				break;
-			default:
-				throw new IllegalStateException("Unknown ramp type: " + type);
+				default:
+					throw new IllegalStateException("Unknown ramp type: " + type);
+			}
 		}
 	}
 
@@ -863,7 +640,7 @@ public class TextureHelper extends AbstractBlenderHelper {
 		}
 		return image.getRGB(x, y) & 0xff;
 	}
-    
+
 	/**
 	 * This method transforms given vector's coordinates into ARGB color (A is always = 255).
 	 * @param x X factor of the vector
@@ -871,13 +648,13 @@ public class TextureHelper extends AbstractBlenderHelper {
 	 * @param z Z factor of the vector
 	 * @return color representation of the given vector
 	 */
-    protected int vectorToColor(float x, float y, float z) {
-        int r = Math.round(255 * (x + 1f) / 2f);
-        int g = Math.round(255 * (y + 1f) / 2f);
-        int b = Math.round(255 * (z + 1f) / 2f);
-        return (255 << 24) + (r << 16) + (g << 8) + b;
-    }
-	
+	protected int vectorToColor(float x, float y, float z) {
+		int r = Math.round(255 * (x + 1f) / 2f);
+		int g = Math.round(255 * (y + 1f) / 2f);
+		int b = Math.round(255 * (z + 1f) / 2f);
+		return (255 << 24) + (r << 16) + (g << 8) + b;
+	}
+
 	/**
 	 * This class returns a texture read from the file or from packed blender data.
 	 * 
@@ -933,7 +710,7 @@ public class TextureHelper extends AbstractBlenderHelper {
 		AssetManager assetManager = dataRepository.getAssetManager();
 		name = name.replaceAll("\\\\", "\\/");
 		Texture result = null;
-		
+
 		List<String> assetNames = new ArrayList<String>();
 		if (name.startsWith("//")) {
 			String relativePath = name.substring(1);
@@ -946,14 +723,14 @@ public class TextureHelper extends AbstractBlenderHelper {
 			String[] paths = name.split("\\/");
 			StringBuilder sb = new StringBuilder(paths[paths.length-1]);//the asset name
 			assetNames.add(paths[paths.length-1]);
-			
+
 			for(int i=paths.length-2;i>=0;--i) {
 				sb.insert(0, '/');
 				sb.insert(0, paths[i]);
 				assetNames.add(sb.toString());
 			}
 		}
-		
+
 		//now try to locate the asset
 		for(String assetName : assetNames) {
 			try {
@@ -966,107 +743,8 @@ public class TextureHelper extends AbstractBlenderHelper {
 		return result;
 	}
 
-	/**
-	 * This method closes the given stream.
-	 * 
-	 * @param is
-	 *        the input stream that is to be closed
-	 */
-	protected void closeStream(InputStream is) {
-		if (is != null) {
-			try {
-				is.close();
-			} catch (IOException e) {
-				LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
-			}
-		}
-	}
-	
 	@Override
 	public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) {
 		return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0;
 	}
-
-	/**
-	 * Image types that can be loaded. AWT: png, jpg, jped or bmp TGA: tga DDS: DirectX image files
-	 * 
-	 * @author Marcin Roguski (Kaelthas)
-	 */
-	public static enum ImageType {
-		AWT, TGA, DDS;
-	}
-
-	/**
-	 * The result pixel of generated texture computations;
-	 * 
-	 * @author Marcin Roguski (Kaelthas)
-	 */
-	protected static class TexResult implements Cloneable {
-		public float	tin, tr, tg, tb, ta;
-		public int		talpha;
-		public float[]	nor;
-
-		@Override
-		public Object clone() throws CloneNotSupportedException {
-			return super.clone();
-		}
-	}
-
-	/**
-	 * A class constaining the colorband data.
-	 * 
-	 * @author Marcin Roguski (Kaelthas)
-	 */
-	protected static class ColorBand {
-		public int		flag, tot, cur, ipotype;
-		public CBData[]	data	= new CBData[32];
-
-		/**
-		 * Constructor. Loads the data from the given structure.
-		 * 
-		 * @param cbdataStructure
-		 *        the colorband structure
-		 */
-		@SuppressWarnings("unchecked")
-		public ColorBand(Structure colorbandStructure) {
-			this.flag = ((Number) colorbandStructure.getFieldValue("flag")).intValue();
-			this.tot = ((Number) colorbandStructure.getFieldValue("tot")).intValue();
-			this.cur = ((Number) colorbandStructure.getFieldValue("cur")).intValue();
-			this.ipotype = ((Number) colorbandStructure.getFieldValue("ipotype")).intValue();
-			DynamicArray<Structure> data = (DynamicArray<Structure>) colorbandStructure.getFieldValue("data");
-			for (int i = 0; i < data.getTotalSize(); ++i) {
-				this.data[i] = new CBData(data.get(i));
-			}
-		}
-	}
-
-	/**
-	 * Class to store the single colorband unit data.
-	 * 
-	 * @author Marcin Roguski (Kaelthas)
-	 */
-	protected static class CBData implements Cloneable {
-		public float	r, g, b, a, pos;
-		public int		cur;
-
-		/**
-		 * Constructor. Loads the data from the given structure.
-		 * 
-		 * @param cbdataStructure
-		 *        the structure containing the CBData object
-		 */
-		public CBData(Structure cbdataStructure) {
-			this.r = ((Number) cbdataStructure.getFieldValue("r")).floatValue();
-			this.g = ((Number) cbdataStructure.getFieldValue("g")).floatValue();
-			this.b = ((Number) cbdataStructure.getFieldValue("b")).floatValue();
-			this.a = ((Number) cbdataStructure.getFieldValue("a")).floatValue();
-			this.pos = ((Number) cbdataStructure.getFieldValue("pos")).floatValue();
-			this.cur = ((Number) cbdataStructure.getFieldValue("cur")).intValue();
-		}
-
-		@Override
-		public Object clone() throws CloneNotSupportedException {
-			return super.clone();
-		}
-	}
 }

+ 48 - 1
engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java

@@ -320,7 +320,54 @@ public class UVCoordinatesGenerator {
 		}
 
 		public void merge(BoundingTube boundingTube) {
-			// TODO: implement
+			//get tubes (tube1.radius >= tube2.radius)
+			BoundingTube tube1, tube2;
+			if(this.radius>=boundingTube.radius) {
+				tube1 = this;
+				tube2 = boundingTube;
+			} else {
+				tube1 = boundingTube;
+				tube2 = this;
+			}
+			float r1 = tube1.radius;
+			float r2 = tube2.radius;
+			
+			//get the distance between tubes projected on XY plane
+			Vector3f distance = boundingTube.center.subtract(this.center);
+			distance.z = 0;
+			float d = distance.length();
+			
+			//calculate union depending on tubes location
+			if(d>=r1+r2) {//tube2 is outside or touches tube1
+				
+			} else if(d<r1+r2 && d>r1-r2) {//tube2 crosses tube1
+				
+			} else {//tube2 is inside tube1
+				
+			}
+			
+			if(d >= this.radius + boundingTube.radius || 
+			  (d < this.radius + boundingTube.radius && d > this.radius - boundingTube.radius)) {
+				
+			}
+			
+			float centerZ = distance.z;
+			
+			float maxz = this.center.z + height*0.5f;
+			float minz = this.center.z - height*0.5f;
+			
+			distance.z = this.center.z = 0;
+			
+			Vector3f distanceNormal = distance.normalize();
+			Vector3f start = this.center.subtract(distanceNormal.multLocal(this.radius));
+			distanceNormal.normalizeLocal();
+			Vector3f stop = start.add(distance).addLocal(distanceNormal.multLocal(this.radius+boundingTube.radius));
+			this.center = start.add(stop.subtractLocal(start)).multLocal(0.5f);
+			this.center.z = centerZ;
+			this.radius = this.center.subtract(start).length();
+			maxz = Math.max(maxz, boundingTube.center.z + boundingTube.height*0.5f);
+			minz = Math.min(minz, boundingTube.center.z - boundingTube.height*0.5f);
+			this.height = maxz - minz;
 		}
 
 		public float getRadius() {

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini