OSDN Git Service

Generated textures refactoring.
authorKaelthas_Spellsinger@o2.pl <Kaelthas_Spellsinger@o2.pl@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Thu, 8 Sep 2011 20:42:42 +0000 (20:42 +0000)
committerKaelthas_Spellsinger@o2.pl <Kaelthas_Spellsinger@o2.pl@75d07b2b-3a1a-0410-a2c5-0572b91ccdca>
Thu, 8 Sep 2011 20:42:42 +0000 (20:42 +0000)
 * 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: http://jmonkeyengine.googlecode.com/svn/trunk@8222 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

16 files changed:
engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/ImageLoader.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/NoiseGenerator.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGenerator.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorBlend.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorClouds.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorDistnoise.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMagic.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMarble.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMusgrave.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorNoise.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorStucci.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorVoronoi.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorWood.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java
engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java

index c3cd83f..f27c27d 100644 (file)
@@ -201,6 +201,10 @@ public class MaterialHelper extends AbstractBlenderHelper {
                MaterialContext materialContext = new MaterialContext(structure, dataRepository);\r
                LOGGER.log(Level.INFO, "Material's name: {0}", materialContext.name);\r
 \r
+               DiffuseShader diffuseShader = this.getDiffuseShader(structure);\r
+               ColorRGBA diffuseColor = this.getDiffuseColor(structure, diffuseShader);\r
+               float[] diffuseColorArray = new float[] {diffuseColor.r, diffuseColor.g, diffuseColor.b};\r
+               \r
                // texture\r
                Map<String, Texture> texturesMap = new HashMap<String, Texture>();\r
                Type firstTextureType = null;\r
@@ -236,7 +240,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
                                                        int blendType = ((Number) mtex.getFieldValue("blendtype")).intValue();\r
                                                        float[] color = new float[] { ((Number) mtex.getFieldValue("r")).floatValue(), ((Number) mtex.getFieldValue("g")).floatValue(), ((Number) mtex.getFieldValue("b")).floatValue() };\r
                                                        float colfac = ((Number) mtex.getFieldValue("colfac")).floatValue();\r
-                                                       texture = textureHelper.blendTexture(new float[] {1, 1, 1}, texture, color, colfac, blendType, negateTexture, dataRepository);\r
+                                                       texture = textureHelper.blendTexture(diffuseColorArray, texture, color, colfac, blendType, negateTexture, dataRepository);\r
                                                        texture.setWrap(WrapMode.Repeat);\r
                                                        //TODO: textures merging\r
                                                        if (materialContext.shadeless) {\r
@@ -289,7 +293,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
                        if (materialContext.vertexColor) {\r
                                result.setBoolean(materialContext.shadeless ? "VertexColor" : "UseVertexColor", true);\r
                        }\r
-                       ColorRGBA diffuseColor = null;\r
+                       \r
                        if (materialContext.shadeless) {\r
                                // color of shadeless? doesn't seem to work in blender ..\r
                                diffuseColor = ColorRGBA.White.clone();\r
@@ -297,9 +301,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
                                result.setBoolean("UseMaterialColors", Boolean.TRUE);\r
 \r
                                // setting the colors\r
-                               DiffuseShader diffuseShader = this.getDiffuseShader(structure);\r
                                result.setBoolean("Minnaert", diffuseShader == DiffuseShader.MINNAERT);\r
-                               diffuseColor = this.getDiffuseColor(structure, diffuseShader);\r
                                if (!materialContext.transparent) {\r
                                        diffuseColor.a = 1;\r
                                }\r
index dd99a81..37f76e9 100644 (file)
@@ -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;
+       }
 }
index e441cd1..3b0b5f2 100644 (file)
@@ -1,32 +1,33 @@
 /*\r
- *\r
- * $Id: noise.c 14611 2008-04-29 08:24:33Z campbellbarton $\r
- *\r
- * ***** BEGIN GPL LICENSE BLOCK *****\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software Foundation,\r
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
- *\r
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.\r
+ * Copyright (c) 2009-2010 jMonkeyEngine\r
  * All rights reserved.\r
  *\r
- * The Original Code is: all of this file.\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are\r
+ * met:\r
+ *\r
+ * * Redistributions of source code must retain the above copyright\r
+ *   notice, this list of conditions and the following disclaimer.\r
  *\r
- * Contributor(s): none yet.\r
+ * * Redistributions in binary form must reproduce the above copyright\r
+ *   notice, this list of conditions and the following disclaimer in the\r
+ *   documentation and/or other materials provided with the distribution.\r
  *\r
- * ***** END GPL LICENSE BLOCK *****\r
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors\r
+ *   may be used to endorse or promote products derived from this software\r
+ *   without specific prior written permission.\r
  *\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
  */\r
 package com.jme3.scene.plugins.blender.textures;\r
 \r
@@ -42,9 +43,7 @@ import com.jme3.math.FastMath;
 import com.jme3.scene.plugins.blender.AbstractBlenderHelper;\r
 import com.jme3.scene.plugins.blender.DataRepository;\r
 import com.jme3.scene.plugins.blender.file.Structure;\r
-import com.jme3.scene.plugins.blender.textures.TextureHelper.CBData;\r
-import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;\r
-import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;\r
+import com.jme3.scene.plugins.blender.textures.TextureGeneratorMusgrave.MusgraveData;\r
 \r
 /**\r
  * This generator is responsible for creating various noises used to create\r
@@ -54,22 +53,8 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
  * @author Marcin Roguski (Kaelthas)\r
  */\r
 /*package*/ class NoiseGenerator extends AbstractBlenderHelper {\r
-\r
     private static final Logger LOGGER = Logger.getLogger(NoiseGenerator.class.getName());\r
-\r
-    // return value\r
-    protected static final int TEX_INT = 0;\r
-    protected static final int TEX_RGB = 1;\r
-    protected static final int TEX_NOR = 2;\r
-\r
-    // noisetype\r
-    protected static final int TEX_NOISESOFT = 0;\r
-    protected static final int TEX_NOISEPERL = 1;\r
-\r
-    // tex->stype\r
-    protected static final int TEX_DEFAULT = 0;\r
-    protected static final int TEX_COLOR = 1;\r
-\r
+    \r
     // flag\r
     protected static final int TEX_COLORBAND = 1;\r
     protected static final int TEX_FLIPBLEND = 2;\r
@@ -82,31 +67,6 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
     protected static final int TEX_REPEAT_YMIR = 256;\r
     protected static final int TEX_FLAG_MASK = TEX_COLORBAND | TEX_FLIPBLEND | TEX_NEGALPHA | TEX_CHECKER_ODD | TEX_CHECKER_EVEN | TEX_PRV_ALPHA | TEX_PRV_NOR | TEX_REPEAT_XMIR | TEX_REPEAT_YMIR;\r
 \r
-    // tex->noisebasis2\r
-    protected static final int TEX_SIN = 0;\r
-    protected static final int TEX_SAW = 1;\r
-    protected static final int TEX_TRI = 2;\r
-\r
-    // tex->stype\r
-    protected static final int TEX_SOFT = 0;\r
-    protected static final int TEX_SHARP = 1;\r
-    protected static final int TEX_SHARPER = 2;\r
-\r
-    // tex->stype\r
-    protected static final int TEX_BAND = 0;\r
-    protected static final int TEX_RING = 1;\r
-    protected static final int TEX_BANDNOISE = 2;\r
-    protected static final int TEX_RINGNOISE = 3;\r
-\r
-    // tex->stype\r
-    protected static final int TEX_LIN = 0;\r
-    protected static final int TEX_QUAD = 1;\r
-    protected static final int TEX_EASE = 2;\r
-    protected static final int TEX_DIAG = 3;\r
-    protected static final int TEX_SPHERE = 4;\r
-    protected static final int TEX_HALO = 5;\r
-    protected static final int TEX_RAD = 6;\r
-\r
     // tex->stype\r
     protected static final int TEX_PLASTIC = 0;\r
     protected static final int TEX_WALLIN = 1;\r
@@ -169,136 +129,127 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
             }\r
         }\r
     }\r
-    protected static Map<Integer, AbstractNoiseFunc> noiseFunctions = new HashMap<Integer, AbstractNoiseFunc>();\r
-\r
+    \r
+    protected static Map<Integer, NoiseFunction> noiseFunctions = new HashMap<Integer, NoiseFunction>();\r
     static {\r
-        // orgBlenderNoise (*Was BLI_hnoise(), removed noisesize, so other functions can call it without scaling.*)\r
-        noiseFunctions.put(Integer.valueOf(0), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(0), new NoiseFunction() {\r
+               // originalBlenderNoise\r
             @Override\r
             public float execute(float x, float y, float z) {\r
-                return this.orgBlenderNoise(x, y, z);\r
+                return NoiseFunctions.originalBlenderNoise(x, y, z);\r
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
-                return 2.0f * this.orgBlenderNoise(x, y, z) - 1.0f;\r
+            public float executeSigned(float x, float y, float z) {\r
+                return 2.0f * NoiseFunctions.originalBlenderNoise(x, y, z) - 1.0f;\r
             }\r
         });\r
-        // orgPerlinNoise (*For use with BLI_gNoise/gTurbulence, returns signed noise.*)\r
-        noiseFunctions.put(Integer.valueOf(1), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(1), new NoiseFunction() {\r
+               // orgPerlinNoise\r
             @Override\r
             public float execute(float x, float y, float z) {\r
-                return 0.5f + 0.5f * this.noise3Perlin(new float[]{x, y, z});\r
+                return 0.5f + 0.5f * NoiseFunctions.noise3Perlin(x, y, z);\r
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
-                return this.noise3Perlin(new float[]{x, y, z});\r
+            public float executeSigned(float x, float y, float z) {\r
+                return NoiseFunctions.noise3Perlin(x, y, z);\r
             }\r
         });\r
-        // newPerlin (* for use with BLI_gNoise()/BLI_gTurbulence(), returns unsigned improved perlin noise *)\r
-        noiseFunctions.put(Integer.valueOf(2), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(2), new NoiseFunction() {\r
+               // newPerlin\r
             @Override\r
             public float execute(float x, float y, float z) {\r
-                return 0.5f + 0.5f * this.newPerlin(x, y, z);\r
+                return 0.5f + 0.5f * NoiseFunctions.newPerlin(x, y, z);\r
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
+            public float executeSigned(float x, float y, float z) {\r
                 return this.execute(x, y, z);\r
             }\r
         });\r
-        // voronoi_F1\r
-        noiseFunctions.put(Integer.valueOf(3), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(3), new NoiseFunction() {\r
+               // voronoi_F1\r
             @Override\r
             public float execute(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return da[0];\r
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
+            public float executeSigned(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return 2.0f * da[0] - 1.0f;\r
             }\r
         });\r
-        // voronoi_F2\r
-        noiseFunctions.put(Integer.valueOf(4), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(4), new NoiseFunction() {\r
+               // voronoi_F2\r
             @Override\r
             public float execute(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return da[1];\r
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
+            public float executeSigned(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return 2.0f * da[1] - 1.0f;\r
             }\r
         });\r
-        // voronoi_F3\r
-        noiseFunctions.put(Integer.valueOf(5), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(5), new NoiseFunction() {\r
+               // voronoi_F3\r
             @Override\r
             public float execute(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return da[2];\r
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
+            public float executeSigned(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return 2.0f * da[2] - 1.0f;\r
             }\r
         });\r
-        // voronoi_F4\r
-        noiseFunctions.put(Integer.valueOf(6), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(6), new NoiseFunction() {\r
+               // voronoi_F4\r
             @Override\r
             public float execute(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return da[3];\r
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
+            public float executeSigned(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return 2.0f * da[3] - 1.0f;\r
             }\r
         });\r
-        // voronoi_F1F2\r
-        noiseFunctions.put(Integer.valueOf(7), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(7), new NoiseFunction() {\r
+               // voronoi_F1F2\r
             @Override\r
             public float execute(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return da[1] - da[0];\r
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
+            public float executeSigned(float x, float y, float z) {\r
                 float[] da = new float[4], pa = new float[12];\r
-                AbstractNoiseFunc.voronoi(x, y, z, da, pa, 1, 0);\r
+                NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);\r
                 return 2.0f * (da[1] - da[0]) - 1.0f;\r
             }\r
         });\r
-        // voronoi_Cr\r
-        noiseFunctions.put(Integer.valueOf(8), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(8), new NoiseFunction() {\r
+               // voronoi_Cr\r
             @Override\r
             public float execute(float x, float y, float z) {\r
                 float t = 10 * noiseFunctions.get(Integer.valueOf(7)).execute(x, y, z);// voronoi_F1F2\r
@@ -306,14 +257,13 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
+            public float executeSigned(float x, float y, float z) {\r
                 float t = 10.0f * noiseFunctions.get(Integer.valueOf(7)).execute(x, y, z);// voronoi_F1F2\r
                 return t > 1.0f ? 1.0f : 2.0f * t - 1.0f;\r
             }\r
         });\r
-        // cellNoise\r
-        noiseFunctions.put(Integer.valueOf(14), new AbstractNoiseFunc() {\r
-\r
+        noiseFunctions.put(Integer.valueOf(14), new NoiseFunction() {\r
+               // cellNoise\r
             @Override\r
             public float execute(float x, float y, float z) {\r
                 int xi = (int) Math.floor(x);\r
@@ -325,42 +275,38 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
             }\r
 \r
             @Override\r
-            public float executeS(float x, float y, float z) {\r
+            public float executeSigned(float x, float y, float z) {\r
                 return 2.0f * this.execute(x, y, z) - 1.0f;\r
             }\r
         });\r
     }\r
     /** Distance metrics for voronoi. e parameter only used in Minkovsky. */\r
-    protected static Map<Integer, DistanceFunc> distanceFunctions = new HashMap<Integer, NoiseGenerator.DistanceFunc>();\r
+    protected static Map<Integer, DistanceFunction> distanceFunctions = new HashMap<Integer, NoiseGenerator.DistanceFunction>();\r
 \r
     static {\r
-        // real distance\r
-        distanceFunctions.put(Integer.valueOf(0), new DistanceFunc() {\r
-\r
+        distanceFunctions.put(Integer.valueOf(0), new DistanceFunction() {\r
+               // real distance\r
             @Override\r
             public float execute(float x, float y, float z, float e) {\r
                 return (float) Math.sqrt(x * x + y * y + z * z);\r
             }\r
         });\r
-        // distance squared\r
-        distanceFunctions.put(Integer.valueOf(1), new DistanceFunc() {\r
-\r
+        distanceFunctions.put(Integer.valueOf(1), new DistanceFunction() {\r
+               // distance squared\r
             @Override\r
             public float execute(float x, float y, float z, float e) {\r
                 return x * x + y * y + z * z;\r
             }\r
         });\r
-        // manhattan/taxicab/cityblock distance\r
-        distanceFunctions.put(Integer.valueOf(2), new DistanceFunc() {\r
-\r
+        distanceFunctions.put(Integer.valueOf(2), new DistanceFunction() {\r
+               // manhattan/taxicab/cityblock distance\r
             @Override\r
             public float execute(float x, float y, float z, float e) {\r
                 return FastMath.abs(x) + FastMath.abs(y) + FastMath.abs(z);\r
             }\r
         });\r
-        // Chebychev\r
-        distanceFunctions.put(Integer.valueOf(3), new DistanceFunc() {\r
-\r
+        distanceFunctions.put(Integer.valueOf(3), new DistanceFunction() {\r
+               // Chebychev\r
             @Override\r
             public float execute(float x, float y, float z, float e) {\r
                 x = FastMath.abs(x);\r
@@ -370,18 +316,16 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
                 return z > t ? z : t;\r
             }\r
         });\r
-        // minkovsky preset exponent 0.5 (MinkovskyH)\r
-        distanceFunctions.put(Integer.valueOf(4), new DistanceFunc() {\r
-\r
+        distanceFunctions.put(Integer.valueOf(4), new DistanceFunction() {\r
+               // Minkovsky, preset exponent 0.5 (MinkovskyH)\r
             @Override\r
             public float execute(float x, float y, float z, float e) {\r
                 float d = (float) (Math.sqrt(FastMath.abs(x)) + Math.sqrt(FastMath.abs(y)) + Math.sqrt(FastMath.abs(z)));\r
                 return d * d;\r
             }\r
         });\r
-        // minkovsky preset exponent 4 (Minkovsky4)\r
-        distanceFunctions.put(Integer.valueOf(5), new DistanceFunc() {\r
-\r
+        distanceFunctions.put(Integer.valueOf(5), new DistanceFunction() {\r
+               // Minkovsky, preset exponent 0.25 (Minkovsky4)\r
             @Override\r
             public float execute(float x, float y, float z, float e) {\r
                 x *= x;\r
@@ -390,43 +334,37 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
                 return (float) Math.sqrt(Math.sqrt(x * x + y * y + z * z));\r
             }\r
         });\r
-        // Minkovsky, general case, slow, maybe too slow to be useful\r
-        distanceFunctions.put(Integer.valueOf(6), new DistanceFunc() {\r
-\r
+        distanceFunctions.put(Integer.valueOf(6), new DistanceFunction() {\r
+               // Minkovsky, general case\r
             @Override\r
             public float execute(float x, float y, float z, float e) {\r
                 return (float) Math.pow(Math.pow(FastMath.abs(x), e) + Math.pow(FastMath.abs(y), e) + Math.pow(FastMath.abs(z), e), 1.0f / e);\r
             }\r
         });\r
     }\r
+    \r
     protected static Map<Integer, MusgraveFunction> musgraveFunctions = new HashMap<Integer, NoiseGenerator.MusgraveFunction>();\r
-\r
     static {\r
         musgraveFunctions.put(Integer.valueOf(TEX_MFRACTAL), new MusgraveFunction() {\r
 \r
             @Override\r
-            public float execute(Structure tex, float x, float y, float z) {\r
-                float mg_H = ((Number) tex.getFieldValue("mg_H")).floatValue();\r
-                float mg_lacunarity = ((Number) tex.getFieldValue("mg_lacunarity")).floatValue();\r
-                float mg_octaves = ((Number) tex.getFieldValue("mg_octaves")).floatValue();\r
-                int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();\r
-\r
-                float rmd, value = 1.0f, pwr = 1.0f, pwHL = (float) Math.pow(mg_lacunarity, -mg_H);\r
-                AbstractNoiseFunc abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noisebasis));\r
+            public float execute(MusgraveData musgraveData, float x, float y, float z) {\r
+                float rmd, value = 1.0f, pwr = 1.0f, pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);\r
+                NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));\r
                 if (abstractNoiseFunc == null) {\r
                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));\r
                 }\r
 \r
-                for (int i = 0; i < (int) mg_octaves; ++i) {\r
-                    value *= pwr * abstractNoiseFunc.executeS(x, y, z) + 1.0f;\r
+                for (int i = 0; i < (int) musgraveData.octaves; ++i) {\r
+                    value *= pwr * abstractNoiseFunc.executeSigned(x, y, z) + 1.0f;\r
                     pwr *= pwHL;\r
-                    x *= mg_lacunarity;\r
-                    y *= mg_lacunarity;\r
-                    z *= mg_lacunarity;\r
+                    x *= musgraveData.lacunarity;\r
+                    y *= musgraveData.lacunarity;\r
+                    z *= musgraveData.lacunarity;\r
                 }\r
-                rmd = (float) (mg_octaves - Math.floor(mg_octaves));\r
+                rmd = (float) (musgraveData.octaves - Math.floor(musgraveData.octaves));\r
                 if (rmd != 0.0f) {\r
-                    value *= rmd * abstractNoiseFunc.executeS(x, y, z) * pwr + 1.0f;\r
+                    value *= rmd * abstractNoiseFunc.executeSigned(x, y, z) * pwr + 1.0f;\r
                 }\r
                 return value;\r
             }\r
@@ -434,38 +372,32 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
         musgraveFunctions.put(Integer.valueOf(TEX_RIDGEDMF), new MusgraveFunction() {\r
 \r
             @Override\r
-            public float execute(Structure tex, float x, float y, float z) {\r
-                float mg_H = ((Number) tex.getFieldValue("mg_H")).floatValue();\r
-                float mg_lacunarity = ((Number) tex.getFieldValue("mg_lacunarity")).floatValue();\r
-                float mg_octaves = ((Number) tex.getFieldValue("mg_octaves")).floatValue();\r
-                float mg_offset = ((Number) tex.getFieldValue("mg_offset")).floatValue();\r
-                int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();\r
-                float mg_gain = ((Number) tex.getFieldValue("mg_gain")).floatValue();\r
+            public float execute(MusgraveData musgraveData, float x, float y, float z) {\r
                 float result, signal, weight;\r
-                float pwHL = (float) Math.pow(mg_lacunarity, -mg_H);\r
-                float pwr = pwHL; /* starts with i=1 instead of 0 */\r
+                float pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);\r
+                float pwr = pwHL;\r
 \r
-                AbstractNoiseFunc abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noisebasis));\r
+                NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));\r
                 if (abstractNoiseFunc == null) {\r
                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));\r
                 }\r
 \r
-                signal = mg_offset - FastMath.abs(abstractNoiseFunc.executeS(x, y, z));\r
+                signal = musgraveData.offset - FastMath.abs(abstractNoiseFunc.executeSigned(x, y, z));\r
                 signal *= signal;\r
                 result = signal;\r
                 weight = 1.0f;\r
 \r
-                for (int i = 1; i < (int) mg_octaves; ++i) {\r
-                    x *= mg_lacunarity;\r
-                    y *= mg_lacunarity;\r
-                    z *= mg_lacunarity;\r
-                    weight = signal * mg_gain;\r
+                for (int i = 1; i < (int) musgraveData.octaves; ++i) {\r
+                    x *= musgraveData.lacunarity;\r
+                    y *= musgraveData.lacunarity;\r
+                    z *= musgraveData.lacunarity;\r
+                    weight = signal * musgraveData.gain;\r
                     if (weight > 1.0f) {\r
                         weight = 1.0f;\r
                     } else if (weight < 0.0) {\r
                         weight = 0.0f;\r
                     }\r
-                    signal = mg_offset - FastMath.abs(abstractNoiseFunc.executeS(x, y, z));\r
+                    signal = musgraveData.offset - FastMath.abs(abstractNoiseFunc.executeSigned(x, y, z));\r
                     signal *= signal;\r
                     signal *= weight;\r
                     result += signal * pwr;\r
@@ -477,43 +409,37 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
         musgraveFunctions.put(Integer.valueOf(TEX_HYBRIDMF), new MusgraveFunction() {\r
 \r
             @Override\r
-            public float execute(Structure tex, float x, float y, float z) {\r
-                float mg_H = ((Number) tex.getFieldValue("mg_H")).floatValue();\r
-                float mg_lacunarity = ((Number) tex.getFieldValue("mg_lacunarity")).floatValue();\r
-                float mg_octaves = ((Number) tex.getFieldValue("mg_octaves")).floatValue();\r
-                float mg_offset = ((Number) tex.getFieldValue("mg_offset")).floatValue();\r
-                int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();\r
-                float mg_gain = ((Number) tex.getFieldValue("mg_gain")).floatValue();\r
+            public float execute(MusgraveData musgraveData, float x, float y, float z) {\r
                 float result, signal, weight, rmd;\r
-                float pwHL = (float) Math.pow(mg_lacunarity, -mg_H);\r
-                float pwr = pwHL; /* starts with i=1 instead of 0 */\r
-                AbstractNoiseFunc abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noisebasis));\r
+                float pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);\r
+                float pwr = pwHL;\r
+                NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));\r
                 if (abstractNoiseFunc == null) {\r
                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));\r
                 }\r
 \r
-                result = abstractNoiseFunc.executeS(x, y, z) + mg_offset;\r
-                weight = mg_gain * result;\r
-                x *= mg_lacunarity;\r
-                y *= mg_lacunarity;\r
-                z *= mg_lacunarity;\r
+                result = abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset;\r
+                weight = musgraveData.gain * result;\r
+                x *= musgraveData.lacunarity;\r
+                y *= musgraveData.lacunarity;\r
+                z *= musgraveData.lacunarity;\r
 \r
-                for (int i = 1; weight > 0.001f && i < (int) mg_octaves; ++i) {\r
+                for (int i = 1; weight > 0.001f && i < (int) musgraveData.octaves; ++i) {\r
                     if (weight > 1.0f) {\r
                         weight = 1.0f;\r
                     }\r
-                    signal = (abstractNoiseFunc.executeS(x, y, z) + mg_offset) * pwr;\r
+                    signal = (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr;\r
                     pwr *= pwHL;\r
                     result += weight * signal;\r
-                    weight *= mg_gain * signal;\r
-                    x *= mg_lacunarity;\r
-                    y *= mg_lacunarity;\r
-                    z *= mg_lacunarity;\r
+                    weight *= musgraveData.gain * signal;\r
+                    x *= musgraveData.lacunarity;\r
+                    y *= musgraveData.lacunarity;\r
+                    z *= musgraveData.lacunarity;\r
                 }\r
 \r
-                rmd = mg_octaves - (float) Math.floor(mg_octaves);\r
+                rmd = musgraveData.octaves - (float) Math.floor(musgraveData.octaves);\r
                 if (rmd != 0.0f) {\r
-                    result += rmd * (abstractNoiseFunc.executeS(x, y, z) + mg_offset) * pwr;\r
+                    result += rmd * (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr;\r
                 }\r
                 return result;\r
             }\r
@@ -521,29 +447,25 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
         musgraveFunctions.put(Integer.valueOf(TEX_FBM), new MusgraveFunction() {\r
 \r
             @Override\r
-            public float execute(Structure tex, float x, float y, float z) {\r
-                float mg_H = ((Number) tex.getFieldValue("mg_H")).floatValue();\r
-                float mg_lacunarity = ((Number) tex.getFieldValue("mg_lacunarity")).floatValue();\r
-                float mg_octaves = ((Number) tex.getFieldValue("mg_octaves")).floatValue();\r
-                int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();\r
-                float rmd, value = 0.0f, pwr = 1.0f, pwHL = (float) Math.pow(mg_lacunarity, -mg_H);\r
-\r
-                AbstractNoiseFunc abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noisebasis));\r
+            public float execute(MusgraveData musgraveData, float x, float y, float z) {\r
+                float rmd, value = 0.0f, pwr = 1.0f, pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);\r
+\r
+                NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));\r
                 if (abstractNoiseFunc == null) {\r
                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));\r
                 }\r
 \r
-                for (int i = 0; i < (int) mg_octaves; ++i) {\r
-                    value += abstractNoiseFunc.executeS(x, y, z) * pwr;\r
+                for (int i = 0; i < (int) musgraveData.octaves; ++i) {\r
+                    value += abstractNoiseFunc.executeSigned(x, y, z) * pwr;\r
                     pwr *= pwHL;\r
-                    x *= mg_lacunarity;\r
-                    y *= mg_lacunarity;\r
-                    z *= mg_lacunarity;\r
+                    x *= musgraveData.lacunarity;\r
+                    y *= musgraveData.lacunarity;\r
+                    z *= musgraveData.lacunarity;\r
                 }\r
 \r
-                rmd = (float) (mg_octaves - Math.floor(mg_octaves));\r
+                rmd = (float) (musgraveData.octaves - Math.floor(musgraveData.octaves));\r
                 if (rmd != 0.f) {\r
-                    value += rmd * abstractNoiseFunc.executeS(x, y, z) * pwr;\r
+                    value += rmd * abstractNoiseFunc.executeSigned(x, y, z) * pwr;\r
                 }\r
                 return value;\r
             }\r
@@ -551,677 +473,102 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
         musgraveFunctions.put(Integer.valueOf(TEX_HTERRAIN), new MusgraveFunction() {\r
 \r
             @Override\r
-            public float execute(Structure tex, float x, float y, float z) {\r
-                float mg_H = ((Number) tex.getFieldValue("mg_H")).floatValue();\r
-                float mg_lacunarity = ((Number) tex.getFieldValue("mg_lacunarity")).floatValue();\r
-                float mg_octaves = ((Number) tex.getFieldValue("mg_octaves")).floatValue();\r
-                int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();\r
-                float mg_offset = ((Number) tex.getFieldValue("mg_offset")).floatValue();\r
+            public float execute(MusgraveData musgraveData, float x, float y, float z) {\r
                 float value, increment, rmd;\r
-                float pwHL = (float) Math.pow(mg_lacunarity, -mg_H);\r
-                float pwr = pwHL; /* starts with i=1 instead of 0 */\r
-                AbstractNoiseFunc abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noisebasis));\r
+                float pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);\r
+                float pwr = pwHL;\r
+                NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));\r
                 if (abstractNoiseFunc == null) {\r
                     abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));\r
                 }\r
 \r
-                /* first unscaled octave of function; later octaves are scaled */\r
-                value = mg_offset + abstractNoiseFunc.executeS(x, y, z);\r
-                x *= mg_lacunarity;\r
-                y *= mg_lacunarity;\r
-                z *= mg_lacunarity;\r
+                value = musgraveData.offset + abstractNoiseFunc.executeSigned(x, y, z);\r
+                x *= musgraveData.lacunarity;\r
+                y *= musgraveData.lacunarity;\r
+                z *= musgraveData.lacunarity;\r
 \r
-                for (int i = 1; i < (int) mg_octaves; ++i) {\r
-                    increment = (abstractNoiseFunc.executeS(x, y, z) + mg_offset) * pwr * value;\r
+                for (int i = 1; i < (int) musgraveData.octaves; ++i) {\r
+                    increment = (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr * value;\r
                     value += increment;\r
                     pwr *= pwHL;\r
-                    x *= mg_lacunarity;\r
-                    y *= mg_lacunarity;\r
-                    z *= mg_lacunarity;\r
+                    x *= musgraveData.lacunarity;\r
+                    y *= musgraveData.lacunarity;\r
+                    z *= musgraveData.lacunarity;\r
                 }\r
 \r
-                rmd = mg_octaves - (float) Math.floor(mg_octaves);\r
+                rmd = musgraveData.octaves - (float) Math.floor(musgraveData.octaves);\r
                 if (rmd != 0.0) {\r
-                    increment = (abstractNoiseFunc.executeS(x, y, z) + mg_offset) * pwr * value;\r
+                    increment = (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr * value;\r
                     value += rmd * increment;\r
                 }\r
                 return value;\r
             }\r
         });\r
     }\r
-\r
-    /**\r
-     * THE FOLLOWING METHODS HELP IN COMPUTATION OF THE TEXTURES.\r
-     */\r
-    protected void brightnesAndContrast(TexResult texres, float contrast, float brightness) {\r
-        texres.tin = (texres.tin - 0.5f) * contrast + brightness - 0.5f;\r
-        if (texres.tin < 0.0f) {\r
-            texres.tin = 0.0f;\r
-        } else if (texres.tin > 1.0f) {\r
-            texres.tin = 1.0f;\r
-        }\r
-    }\r
-\r
-    protected void brightnesAndContrastRGB(Structure tex, TexResult texres) {\r
-        float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();\r
-        float bright = ((Number) tex.getFieldValue("bright")).floatValue();\r
-        float rfac = ((Number) tex.getFieldValue("rfac")).floatValue();\r
-        float gfac = ((Number) tex.getFieldValue("gfac")).floatValue();\r
-        float bfac = ((Number) tex.getFieldValue("bfac")).floatValue();\r
-\r
-        texres.tr = rfac * ((texres.tr - 0.5f) * contrast + bright - 0.5f);\r
-        if (texres.tr < 0.0f) {\r
-            texres.tr = 0.0f;\r
-        }\r
-        texres.tg = gfac * ((texres.tg - 0.5f) * contrast + bright - 0.5f);\r
-        if (texres.tg < 0.0f) {\r
-            texres.tg = 0.0f;\r
-        }\r
-        texres.tb = bfac * ((texres.tb - 0.5f) * contrast + bright - 0.5f);\r
-        if (texres.tb < 0.0f) {\r
-            texres.tb = 0.0f;\r
-        }\r
-    }\r
-\r
-    /* this allows colorbanded textures to control normals as well */\r
-    public void texNormalDerivate(ColorBand colorBand, TexResult texres, DataRepository dataRepository) {\r
-        if (texres.nor != null) {\r
-            TexResult fakeTexresult;\r
-            try {\r
-                fakeTexresult = (TexResult) texres.clone();\r
-            } catch (CloneNotSupportedException e) {\r
-                throw new IllegalStateException("Texture result class MUST support cloning!", e);\r
-            }\r
-\r
-            float fac0 = fakeTexresult.tr + fakeTexresult.tg + fakeTexresult.tb;\r
-            fakeTexresult.tin = texres.nor[0];\r
-            this.doColorband(colorBand, fakeTexresult, dataRepository);\r
-\r
-            float fac1 = fakeTexresult.tr + fakeTexresult.tg + fakeTexresult.tb;\r
-            fakeTexresult.tin = texres.nor[1];\r
-            this.doColorband(colorBand, fakeTexresult, dataRepository);\r
-\r
-            float fac2 = fakeTexresult.tr + fakeTexresult.tg + fakeTexresult.tb;\r
-            fakeTexresult.tin = texres.nor[2];\r
-            this.doColorband(colorBand, fakeTexresult, dataRepository);\r
-\r
-            float fac3 = fakeTexresult.tr + fakeTexresult.tg + fakeTexresult.tb;\r
-\r
-            texres.nor[0] = 0.3333f * (fac0 - fac1);\r
-            texres.nor[1] = 0.3333f * (fac0 - fac2);\r
-            texres.nor[2] = 0.3333f * (fac0 - fac3);\r
-\r
-            texres.nor[0] = texres.tin - texres.nor[0];\r
-            texres.nor[1] = texres.tin - texres.nor[1];\r
-            texres.nor[2] = texres.tin - texres.nor[2];\r
-        }\r
-    }\r
-\r
-    /**\r
-     * This method calculates the colorband for the texture.\r
-     * @param colorBand\r
-     *        the colorband data\r
-     * @param texres\r
-     *        the texture pixel result\r
-     * @param dataRepository\r
-     *        the data repository\r
-     * @return <b>true</b> if calculation suceedess and <b>false</b> otherwise\r
-     */\r
-    public boolean doColorband(ColorBand colorBand, TexResult texres, DataRepository dataRepository) {\r
-        CBData cbd1, cbd2, cbd0, cbd3;\r
-        int i1 = 0, i2 = 0, a;\r
-        float fac, mfac;\r
-        float[] t = new float[4];\r
-\r
-        if (colorBand == null || colorBand.tot == 0) {\r
-            return true;\r
-        }\r
-\r
-        cbd1 = colorBand.data[0];\r
-        if (colorBand.tot == 1) {\r
-            texres.tr = cbd1.r;\r
-            texres.tg = cbd1.g;\r
-            texres.tb = cbd1.b;\r
-            texres.ta = cbd1.a;\r
-        } else {\r
-            if (texres.tin <= cbd1.pos && colorBand.ipotype < 2) {\r
-                texres.tr = cbd1.r;\r
-                texres.tg = cbd1.g;\r
-                texres.tb = cbd1.b;\r
-                texres.ta = cbd1.a;\r
-            } else {\r
-                /* we're looking for first pos > in */\r
-                for (a = 0; a < colorBand.tot; ++a, ++i1) {\r
-                    cbd1 = colorBand.data[i1];\r
-                    if (cbd1.pos > texres.tin) {\r
-                        break;\r
-                    }\r
-                }\r
-\r
-                if (a == colorBand.tot) {\r
-                    cbd2 = colorBand.data[i1 - 1];\r
-                    try {\r
-                        cbd1 = (CBData) cbd2.clone();\r
-                    } catch (CloneNotSupportedException e) {\r
-                        throw new IllegalStateException("Clone not supported for " + CBData.class.getName() + " class! Fix that!");\r
-                    }\r
-                    cbd1.pos = 1.0f;\r
-                } else if (a == 0) {\r
-                    try {\r
-                        cbd2 = (CBData) cbd1.clone();\r
-                    } catch (CloneNotSupportedException e) {\r
-                        throw new IllegalStateException("Clone not supported for " + CBData.class.getName() + " class! Fix that!");\r
-                    }\r
-                    cbd2.pos = 0.0f;\r
-                } else {\r
-                    cbd2 = colorBand.data[i1 - 1];\r
-                }\r
-\r
-                if (texres.tin >= cbd1.pos && colorBand.ipotype < 2) {\r
-                    texres.tr = cbd1.r;\r
-                    texres.tg = cbd1.g;\r
-                    texres.tb = cbd1.b;\r
-                    texres.ta = cbd1.a;\r
-                } else {\r
-\r
-                    if (cbd2.pos != cbd1.pos) {\r
-                        fac = (texres.tin - cbd1.pos) / (cbd2.pos - cbd1.pos);\r
-                    } else {\r
-                        fac = 0.0f;\r
-                    }\r
-\r
-                    if (colorBand.ipotype == 4) {\r
-                        /* constant */\r
-                        texres.tr = cbd2.r;\r
-                        texres.tg = cbd2.g;\r
-                        texres.tb = cbd2.b;\r
-                        texres.ta = cbd2.a;\r
-                        return true;\r
-                    }\r
-\r
-                    if (colorBand.ipotype >= 2) {\r
-                        /* ipo from right to left: 3 2 1 0 */\r
-\r
-                        if (a >= colorBand.tot - 1) {\r
-                            cbd0 = cbd1;\r
-                        } else {\r
-                            cbd0 = colorBand.data[i1 + 1];\r
-                        }\r
-                        if (a < 2) {\r
-                            cbd3 = cbd2;\r
-                        } else {\r
-                            cbd3 = colorBand.data[i2 - 1];\r
-                        }\r
-\r
-                        fac = FastMath.clamp(fac, 0.0f, 1.0f);\r
-\r
-                        if (colorBand.ipotype == 3) {\r
-                            this.setFourIpo(fac, t, KEY_CARDINAL);\r
-                        } else {\r
-                            this.setFourIpo(fac, t, KEY_BSPLINE);\r
-                        }\r
-\r
-                        texres.tr = t[3] * cbd3.r + t[2] * cbd2.r + t[1] * cbd1.r + t[0] * cbd0.r;\r
-                        texres.tg = t[3] * cbd3.g + t[2] * cbd2.g + t[1] * cbd1.g + t[0] * cbd0.g;\r
-                        texres.tb = t[3] * cbd3.b + t[2] * cbd2.b + t[1] * cbd1.b + t[0] * cbd0.b;\r
-                        texres.ta = t[3] * cbd3.a + t[2] * cbd2.a + t[1] * cbd1.a + t[0] * cbd0.a;\r
-                        texres.tr = FastMath.clamp(texres.tr, 0.0f, 1.0f);\r
-                        texres.tg = FastMath.clamp(texres.tg, 0.0f, 1.0f);\r
-                        texres.tb = FastMath.clamp(texres.tb, 0.0f, 1.0f);\r
-                        texres.ta = FastMath.clamp(texres.ta, 0.0f, 1.0f);\r
-                    } else {\r
-\r
-                        if (colorBand.ipotype == 1) { /* EASE */\r
-                            mfac = fac * fac;\r
-                            fac = 3.0f * mfac - 2.0f * mfac * fac;\r
-                        }\r
-                        mfac = 1.0f - fac;\r
-\r
-                        texres.tr = mfac * cbd1.r + fac * cbd2.r;\r
-                        texres.tg = mfac * cbd1.g + fac * cbd2.g;\r
-                        texres.tb = mfac * cbd1.b + fac * cbd2.b;\r
-                        texres.ta = mfac * cbd1.a + fac * cbd2.a;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return true;\r
-    }\r
-\r
-    protected void setFourIpo(float d, float[] data, int type) {\r
-        if (type == KEY_LINEAR) {\r
-            data[0] = 0.0f;\r
-            data[1] = 1.0f - d;\r
-            data[2] = d;\r
-            data[3] = 0.0f;\r
-        } else {\r
-            float d2 = d * d;\r
-            float d3 = d2 * d;\r
-            if (type == KEY_CARDINAL) {\r
-                float fc = 0.71f;\r
-                data[0] = -fc * d3 + 2.0f * fc * d2 - fc * d;\r
-                data[1] = (2.0f - fc) * d3 + (fc - 3.0f) * d2 + 1.0f;\r
-                data[2] = (fc - 2.0f) * d3 + (3.0f - 2.0f * fc) * d2 + fc * d;\r
-                data[3] = fc * d3 - fc * d2;\r
-            } else if (type == KEY_BSPLINE) {\r
-                data[0] = -0.16666666f * d3 + 0.5f * d2 - 0.5f * d + 0.16666666f;\r
-                data[1] = 0.5f * d3 - d2 + 0.6666666f;\r
-                data[2] = -0.5f * d3 + 0.5f * d2 + 0.5f * d + 0.16666666f;\r
-                data[3] = 0.16666666f * d3;\r
-            }\r
-        }\r
-    }\r
-\r
-    interface IWaveForm {\r
-\r
-        float execute(float x);\r
-    }\r
-    protected static IWaveForm[] waveformFunctions = new IWaveForm[3];\r
-\r
-    static {\r
-        waveformFunctions[0] = new IWaveForm() {// tex_sin\r
-\r
-            @Override\r
-            public float execute(float x) {\r
-                return 0.5f + 0.5f * (float) Math.sin(x);\r
-            }\r
-        };\r
-        waveformFunctions[1] = new IWaveForm() {// tex_saw\r
-\r
-            @Override\r
-            public float execute(float x) {\r
-                int n = (int) (x / FastMath.TWO_PI);\r
-                x -= n * FastMath.TWO_PI;\r
-                if (x < 0.0f) {\r
-                    x += FastMath.TWO_PI;\r
-                }\r
-                return x / FastMath.TWO_PI;\r
-            }\r
-        };\r
-        waveformFunctions[2] = new IWaveForm() {// tex_tri\r
-\r
-            @Override\r
-            public float execute(float x) {\r
-                return 1.0f - 2.0f * FastMath.abs((float) Math.floor(x * 1.0f / FastMath.TWO_PI + 0.5f) - x * 1.0f / FastMath.TWO_PI);\r
-            }\r
-        };\r
-    }\r
-\r
-    /* computes basic wood intensity value at x,y,z */\r
-    public float woodInt(Structure tex, float x, float y, float z, DataRepository dataRepository) {\r
-        int noisebasis2 = ((Number) tex.getFieldValue("noisebasis2")).intValue();\r
-        int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();\r
-        int stype = ((Number) tex.getFieldValue("stype")).intValue();\r
-        float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();\r
-        float turbul = ((Number) tex.getFieldValue("turbul")).floatValue();\r
-        int noiseType = ((Number) tex.getFieldValue("noisetype")).intValue();\r
-        float wi = 0;\r
-        int waveform = noisebasis2; /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */\r
-        int wt = stype; /* wood type: TEX_BAND=0, TEX_RING=1, TEX_BANDNOISE=2, TEX_RINGNOISE=3 */\r
-\r
-        if (waveform > TEX_TRI || waveform < TEX_SIN) {\r
-            waveform = 0; /* check to be sure noisebasis2 is initialized ahead of time */\r
-        }\r
-\r
-        if (wt == TEX_BAND) {\r
-            wi = waveformFunctions[waveform].execute((x + y + z) * 10.0f);\r
-        } else if (wt == TEX_RING) {\r
-            wi = waveformFunctions[waveform].execute((float) Math.sqrt(x * x + y * y + z * z) * 20.0f);\r
-        } else if (wt == TEX_BANDNOISE) {\r
-            wi = turbul * this.bliGNoise(noisesize, x, y, z, noiseType != TEX_NOISESOFT, noisebasis);\r
-            wi = waveformFunctions[waveform].execute((x + y + z) * 10.0f + wi);\r
-        } else if (wt == TEX_RINGNOISE) {\r
-            wi = turbul * this.bliGNoise(noisesize, x, y, z, noiseType != TEX_NOISESOFT, noisebasis);\r
-            wi = waveformFunctions[waveform].execute((float) Math.sqrt(x * x + y * y + z * z) * 20.0f + wi);\r
-        }\r
-        return wi;\r
-    }\r
-\r
-    /* computes basic marble intensity at x,y,z */\r
-    public float marbleInt(Structure tex, float x, float y, float z, DataRepository dataRepository) {\r
-        float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();\r
-        int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();\r
-        int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();\r
-        int stype = ((Number) tex.getFieldValue("stype")).intValue();/* marble type: TEX_SOFT=0, TEX_SHARP=1,TEX_SHAPER=2 */\r
-        float turbul = ((Number) tex.getFieldValue("turbul")).floatValue();\r
-        int noisetype = ((Number) tex.getFieldValue("noisetype")).intValue();\r
-        int waveform = ((Number) tex.getFieldValue("noisebasis2")).intValue(); /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */\r
-\r
-        if (waveform > TEX_TRI || waveform < TEX_SIN) {\r
-            waveform = 0; /* check to be sure noisebasis2 isn't initialized ahead of time */\r
-        }\r
-\r
-        float n = 5.0f * (x + y + z);\r
-        float mi = n + turbul * this.bliGTurbulence(noisesize, x, y, z, noisedepth, noisetype != TEX_NOISESOFT, noisebasis);\r
-\r
-        if (stype >= NoiseGenerator.TEX_SOFT) { /* TEX_SOFT always true */\r
-            mi = waveformFunctions[waveform].execute(mi);\r
-            if (stype == TEX_SHARP) {\r
-                mi = (float) Math.sqrt(mi);\r
-            } else if (stype == TEX_SHARPER) {\r
-                mi = (float) Math.sqrt(Math.sqrt(mi));\r
-            }\r
-        }\r
-        return mi;\r
-    }\r
-\r
-    public void voronoi(float x, float y, float z, float[] da, float[] pa, float me, int dtype) {\r
-        AbstractNoiseFunc.voronoi(x, y, z, da, pa, me, dtype);\r
-    }\r
-\r
-    public void cellNoiseV(float x, float y, float z, float[] ca) {\r
-        AbstractNoiseFunc.cellNoiseV(x, y, z, ca);\r
-    }\r
-\r
-    /**\r
-     * THE FOLLOWING METHODS HELP IN NOISE COMPUTATIONS\r
-     */\r
-    /**\r
-     * Separated from orgBlenderNoise above, with scaling.\r
-     * @param noisesize\r
-     * @param x\r
-     * @param y\r
-     * @param z\r
-     * @return\r
-     */\r
-    private float bliHnoise(float noisesize, float x, float y, float z) {\r
-        if (noisesize == 0.0) {\r
-            return 0.0f;\r
-        }\r
-        x = (1.0f + x) / noisesize;\r
-        y = (1.0f + y) / noisesize;\r
-        z = (1.0f + z) / noisesize;\r
-        return noiseFunctions.get(0).execute(x, y, z);\r
-    }\r
-\r
-    /**\r
-     * @param noisesize\r
-     * @param x\r
-     * @param y\r
-     * @param z\r
-     * @param nr\r
-     * @return\r
-     */\r
-    public float bliTurbulence(float noisesize, float x, float y, float z, int nr) {\r
-        float d = 0.5f, div = 1.0f;\r
-\r
-        float s = this.bliHnoise(noisesize, x, y, z);\r
-        while (nr > 0) {\r
-            s += d * this.bliHnoise(noisesize * d, x, y, z);\r
-            div += d;\r
-            d *= 0.5;\r
-            --nr;\r
-        }\r
-        return s / div;\r
-    }\r
-\r
-    /**\r
-     * @param noisesize\r
-     * @param x\r
-     * @param y\r
-     * @param z\r
-     * @param nr\r
-     * @return\r
-     */\r
-    public float bliTurbulence1(float noisesize, float x, float y, float z, int nr) {\r
-        float s, d = 0.5f, div = 1.0f;\r
-\r
-        s = FastMath.abs((-1.0f + 2.0f * this.bliHnoise(noisesize, x, y, z)));\r
-        while (nr > 0) {\r
-            s += Math.abs(d * (-1.0f + 2.0f * this.bliHnoise(noisesize * d, x, y, z)));\r
-            div += d;\r
-            d *= 0.5;\r
-            --nr;\r
-        }\r
-        return s / div;\r
-    }\r
-\r
-    /**\r
-     * @param noisesize\r
-     * @param x\r
-     * @param y\r
-     * @param z\r
-     * @return\r
-     */\r
-    public float bliHnoisep(float noisesize, float x, float y, float z) {\r
-        return noiseFunctions.get(Integer.valueOf(0)).noise3Perlin(new float[]{x / noisesize, y / noisesize, z / noisesize});\r
-    }\r
-\r
-    /**\r
-     * @param point\r
-     * @param lofreq\r
-     * @param hifreq\r
-     * @return\r
-     */\r
-    public float turbulencePerlin(float[] point, float lofreq, float hifreq) {\r
-        float freq, t = 0, p[] = new float[]{point[0] + 123.456f, point[1], point[2]};\r
-        for (freq = lofreq; freq < hifreq; freq *= 2.) {\r
-            t += Math.abs(noiseFunctions.get(Integer.valueOf(0)).noise3Perlin(p)) / freq;\r
-            p[0] *= 2.0f;\r
-            p[1] *= 2.0f;\r
-            p[2] *= 2.0f;\r
-        }\r
-        return t - 0.3f; /* readjust to make mean value = 0.0 */\r
-    }\r
-\r
-    /**\r
-     * @param noisesize\r
-     * @param x\r
-     * @param y\r
-     * @param z\r
-     * @param nr\r
-     * @return\r
-     */\r
-    public float turbulencep(float noisesize, float x, float y, float z, int nr) {\r
-        float[] vec = new float[]{x / noisesize, y / noisesize, z / noisesize};\r
-        ++nr;\r
-        return this.turbulencePerlin(vec, 1.0f, (1 << nr));\r
-    }\r
-\r
-    /**\r
-     * Newnoise: generic noise function for use with different noisebases\r
-     * @param x\r
-     * @param y\r
-     * @param z\r
-     * @param oct\r
-     * @param isHard\r
-     * @param noisebasis\r
-     * @return\r
-     */\r
-    public float bliGNoise(float noisesize, float x, float y, float z, boolean isHard, int noisebasis) {\r
-        AbstractNoiseFunc abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noisebasis));\r
-        if (abstractNoiseFunc == null) {\r
-            abstractNoiseFunc = noiseFunctions.get(0);\r
-            noisebasis = 0;\r
-        }\r
-        if (noisebasis == 0) {// add one to make return value same as BLI_hnoise\r
-            x += 1;\r
-            y += 1;\r
-            z += 1;\r
-        }\r
-\r
-        if (noisesize != 0.0) {\r
-            noisesize = 1.0f / noisesize;\r
-            x *= noisesize;\r
-            y *= noisesize;\r
-            z *= noisesize;\r
-        }\r
-        if (isHard) {\r
-            return Math.abs(2.0f * abstractNoiseFunc.execute(x, y, z) - 1.0f);\r
-        }\r
-        return abstractNoiseFunc.execute(x, y, z);\r
-    }\r
-\r
-    /**\r
-     * Newnoise: generic turbulence function for use with different noisebasis\r
-     * @param x\r
-     * @param y\r
-     * @param z\r
-     * @param oct\r
-     * @param isHard\r
-     * @param noisebasis\r
-     * @return\r
-     */\r
-    public float bliGTurbulence(float noisesize, float x, float y, float z, int oct, boolean isHard, int noisebasis) {\r
-        AbstractNoiseFunc abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noisebasis));\r
-        if (abstractNoiseFunc == null) {\r
-            abstractNoiseFunc = noiseFunctions.get(0);\r
-            noisebasis = 0;\r
-        }\r
-        if (noisebasis == 0) {// add one to make return value same as BLI_hnoise\r
-            x += 1;\r
-            y += 1;\r
-            z += 1;\r
-        }\r
-        float sum = 0, t, amp = 1, fscale = 1;\r
-\r
-        if (noisesize != 0.0) {\r
-            noisesize = 1.0f / noisesize;\r
-            x *= noisesize;\r
-            y *= noisesize;\r
-            z *= noisesize;\r
-        }\r
-        for (int i = 0; i <= oct; ++i, amp *= 0.5, fscale *= 2) {\r
-            t = abstractNoiseFunc.execute(fscale * x, fscale * y, fscale * z);\r
-            if (isHard) {\r
-                t = FastMath.abs(2.0f * t - 1.0f);\r
-            }\r
-            sum += t * amp;\r
-        }\r
-\r
-        sum *= (float) (1 << oct) / (float) ((1 << oct + 1) - 1);\r
-        return sum;\r
-    }\r
-\r
-    /**\r
-     * "Variable Lacunarity Noise" A distorted variety of Perlin noise. This method is used to calculate distorted noise\r
-     * texture.\r
-     * @param x\r
-     * @param y\r
-     * @param z\r
-     * @param distortion\r
-     * @param nbas1\r
-     * @param nbas2\r
-     * @return\r
-     */\r
-    public float mgVLNoise(float x, float y, float z, float distortion, int nbas1, int nbas2) {\r
-        AbstractNoiseFunc abstractNoiseFunc1 = noiseFunctions.get(Integer.valueOf(nbas1));\r
-        if (abstractNoiseFunc1 == null) {\r
-            abstractNoiseFunc1 = noiseFunctions.get(Integer.valueOf(0));\r
-        }\r
-        AbstractNoiseFunc abstractNoiseFunc2 = noiseFunctions.get(Integer.valueOf(nbas2));\r
-        if (abstractNoiseFunc2 == null) {\r
-            abstractNoiseFunc2 = noiseFunctions.get(Integer.valueOf(0));\r
-        }\r
-        // get a random vector and scale the randomization\r
-        float rx = abstractNoiseFunc1.execute(x + 13.5f, y + 13.5f, z + 13.5f) * distortion;\r
-        float ry = abstractNoiseFunc1.execute(x, y, z) * distortion;\r
-        float rz = abstractNoiseFunc1.execute(x - 13.5f, y - 13.5f, z - 13.5f) * distortion;\r
-        return abstractNoiseFunc2.executeS(x + rx, y + ry, z + rz); //distorted-domain noise\r
-    }\r
-\r
-    public void mgMFractalOrfBmTex(Structure tex, float[] texvec, ColorBand colorBand, TexResult texres, DataRepository dataRepository) {\r
-        int stype = ((Number) tex.getFieldValue("stype")).intValue();\r
-        float nsOutscale = ((Number) tex.getFieldValue("ns_outscale")).floatValue();\r
-        float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();\r
-        float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();\r
-        float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();\r
-        float brightness = ((Number) tex.getFieldValue("bright")).floatValue();\r
-\r
-        MusgraveFunction mgravefunc = stype == TEX_MFRACTAL ? musgraveFunctions.get(Integer.valueOf(stype)) : musgraveFunctions.get(Integer.valueOf(TEX_FBM));\r
-\r
-        texres.tin = nsOutscale * mgravefunc.execute(tex, texvec[0], texvec[1], texvec[2]);\r
-        if (texres.nor != null) {\r
-            float offs = nabla / noisesize; // also scaling of texvec\r
-            // calculate bumpnormal\r
-            texres.nor[0] = nsOutscale * mgravefunc.execute(tex, texvec[0] + offs, texvec[1], texvec[2]);\r
-            texres.nor[1] = nsOutscale * mgravefunc.execute(tex, texvec[0], texvec[1] + offs, texvec[2]);\r
-            texres.nor[2] = nsOutscale * mgravefunc.execute(tex, texvec[0], texvec[1], texvec[2] + offs);\r
-            this.texNormalDerivate(colorBand, texres, dataRepository);\r
-        }\r
-        this.brightnesAndContrast(texres, contrast, brightness);\r
-    }\r
-\r
-    public void mgRidgedOrHybridMFTex(Structure tex, float[] texvec, ColorBand colorBand, TexResult texres, DataRepository dataRepository) {\r
-        int stype = ((Number) tex.getFieldValue("stype")).intValue();\r
-        float nsOutscale = ((Number) tex.getFieldValue("ns_outscale")).floatValue();\r
-        float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();\r
-        float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();\r
-        float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();\r
-        float brightness = ((Number) tex.getFieldValue("bright")).floatValue();\r
-\r
-        MusgraveFunction mgravefunc = stype == TEX_RIDGEDMF ? musgraveFunctions.get(Integer.valueOf(stype)) : musgraveFunctions.get(Integer.valueOf(TEX_HYBRIDMF));\r
-\r
-        texres.tin = nsOutscale * mgravefunc.execute(tex, texvec[0], texvec[1], texvec[2]);\r
-        if (texres.nor != null) {\r
-            float offs = nabla / noisesize; // also scaling of texvec\r
-            // calculate bumpnormal\r
-            texres.nor[0] = nsOutscale * mgravefunc.execute(tex, texvec[0] + offs, texvec[1], texvec[2]);\r
-            texres.nor[1] = nsOutscale * mgravefunc.execute(tex, texvec[0], texvec[1] + offs, texvec[2]);\r
-            texres.nor[2] = nsOutscale * mgravefunc.execute(tex, texvec[0], texvec[1], texvec[2] + offs);\r
-            this.texNormalDerivate(colorBand, texres, dataRepository);\r
-        }\r
-        this.brightnesAndContrast(texres, contrast, brightness);\r
-    }\r
-\r
-    public void mgHTerrainTex(Structure tex, float[] texvec, ColorBand colorBand, TexResult texres, DataRepository dataRepository) {\r
-        float nsOutscale = ((Number) tex.getFieldValue("ns_outscale")).floatValue();\r
-        float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();\r
-        float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();\r
-        float contrast = ((Number) tex.getFieldValue("contrast")).floatValue();\r
-        float brightness = ((Number) tex.getFieldValue("bright")).floatValue();\r
-\r
-        MusgraveFunction musgraveFunction = musgraveFunctions.get(Integer.valueOf(TEX_HTERRAIN));\r
-        texres.tin = nsOutscale * musgraveFunction.execute(tex, texvec[0], texvec[1], texvec[2]);\r
-        if (texres.nor != null) {\r
-            float offs = nabla / noisesize; // also scaling of texvec\r
-            // calculate bumpnormal\r
-            texres.nor[0] = nsOutscale * musgraveFunction.execute(tex, texvec[0] + offs, texvec[1], texvec[2]);\r
-            texres.nor[1] = nsOutscale * musgraveFunction.execute(tex, texvec[0], texvec[1] + offs, texvec[2]);\r
-            texres.nor[2] = nsOutscale * musgraveFunction.execute(tex, texvec[0], texvec[1], texvec[2] + offs);\r
-            this.texNormalDerivate(colorBand, texres, dataRepository);\r
-        }\r
-        this.brightnesAndContrast(texres, contrast, brightness);\r
-    }\r
-\r
-    /**\r
-     * This class is abstract to the noise functions computations. It has two methods. One calculates the Signed (with\r
-     * 'S' at the end) and the other Unsigned value.\r
-     * @author Marcin Roguski (Kaelthas)\r
-     */\r
-    protected static abstract class AbstractNoiseFunc {\r
-\r
-        /**\r
-         * This method calculates the unsigned value of the noise.\r
-         * @param x\r
-         *        the x texture coordinate\r
-         * @param y\r
-         *        the y texture coordinate\r
-         * @param z\r
-         *        the z texture coordinate\r
-         * @return value of the noise\r
-         */\r
-        public abstract float execute(float x, float y, float z);\r
-\r
-        /**\r
-         * This method calculates the signed value of the noise.\r
-         * @param x\r
-         *        the x texture coordinate\r
-         * @param y\r
-         *        the y texture coordinate\r
-         * @param z\r
-         *        the z texture coordinate\r
-         * @return value of the noise\r
-         */\r
-        public abstract float executeS(float x, float y, float z);\r
-\r
-        /*\r
+    \r
+    public static class NoiseFunctions {\r
+       public static float noise(float x, float y, float z, float noiseSize, int noiseDepth, int noiseBasis, boolean isHard) {\r
+               NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noiseBasis));\r
+               if (abstractNoiseFunc == null) {\r
+                   abstractNoiseFunc = noiseFunctions.get(0);\r
+                   noiseBasis = 0;\r
+               }\r
+               \r
+               if (noiseBasis == 0) {\r
+                       ++x;\r
+                   ++y;\r
+                   ++z;\r
+               }\r
+\r
+               if (noiseSize != 0.0) {\r
+                   noiseSize = 1.0f / noiseSize;\r
+                   x *= noiseSize;\r
+                   y *= noiseSize;\r
+                   z *= noiseSize;\r
+               }\r
+               float result = abstractNoiseFunc.execute(x, y, z);\r
+               return isHard ? Math.abs(2.0f * result - 1.0f) : result;\r
+       }\r
+       \r
+       public static float turbulence(float x, float y, float z, float noiseSize, int noiseDepth, int noiseBasis, boolean isHard) {\r
+               NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noiseBasis));\r
+               if (abstractNoiseFunc == null) {\r
+                   abstractNoiseFunc = noiseFunctions.get(0);\r
+                   noiseBasis = 0;\r
+               }\r
+               \r
+               if (noiseBasis == 0) {\r
+                   ++x;\r
+                   ++y;\r
+                   ++z;\r
+               }\r
+               if (noiseSize != 0.0) {\r
+                   noiseSize = 1.0f / noiseSize;\r
+                   x *= noiseSize;\r
+                   y *= noiseSize;\r
+                   z *= noiseSize;\r
+               }\r
+               \r
+               float sum = 0, t, amp = 1, fscale = 1;\r
+               for (int i = 0; i <= noiseDepth; ++i, amp *= 0.5, fscale *= 2) {\r
+                   t = abstractNoiseFunc.execute(fscale * x, fscale * y, fscale * z);\r
+                   if (isHard) {\r
+                       t = FastMath.abs(2.0f * t - 1.0f);\r
+                   }\r
+                   sum += t * amp;\r
+               }\r
+\r
+               sum *= (float) (1 << noiseDepth) / (float) ((1 << noiseDepth + 1) - 1);\r
+               return sum;\r
+       }\r
+       \r
+       /**\r
          * Not 'pure' Worley, but the results are virtually the same. Returns distances in da and point coords in pa\r
          */\r
-        protected static void voronoi(float x, float y, float z, float[] da, float[] pa, float me, int dtype) {\r
-            float xd, yd, zd, d, p[];\r
+        public static void voronoi(float x, float y, float z, float[] da, float[] pa, float distanceExponent, int distanceType) {\r
+            float xd, yd, zd, d, p[] = new float[3];\r
 \r
-            DistanceFunc distanceFunc = distanceFunctions.get(Integer.valueOf(dtype));\r
+            DistanceFunction distanceFunc = distanceFunctions.get(Integer.valueOf(distanceType));\r
             if (distanceFunc == null) {\r
                 distanceFunc = distanceFunctions.get(Integer.valueOf(0));\r
             }\r
@@ -1230,14 +577,14 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
             int yi = (int) FastMath.floor(y);\r
             int zi = (int) FastMath.floor(z);\r
             da[0] = da[1] = da[2] = da[3] = 1e10f;\r
-            for (int xx = xi - 1; xx <= xi + 1; ++xx) {\r
-                for (int yy = yi - 1; yy <= yi + 1; ++yy) {\r
-                    for (int zz = zi - 1; zz <= zi + 1; ++zz) {\r
-                        p = AbstractNoiseFunc.hashPoint(xx, yy, zz);\r
-                        xd = x - (p[0] + xx);\r
-                        yd = y - (p[1] + yy);\r
-                        zd = z - (p[2] + zz);\r
-                        d = distanceFunc.execute(xd, yd, zd, me);\r
+            for (int i = xi - 1; i <= xi + 1; ++i) {\r
+                for (int j = yi - 1; j <= yi + 1; ++j) {\r
+                    for (int k = zi - 1; k <= zi + 1; ++k) {\r
+                        NoiseMath.hash(i, j, k, p);\r
+                        xd = x - (p[0] + i);\r
+                        yd = y - (p[1] + j);\r
+                        zd = z - (p[2] + k);\r
+                        d = distanceFunc.execute(xd, yd, zd, distanceExponent);\r
                         if (d < da[0]) {\r
                             da[3] = da[2];\r
                             da[2] = da[1];\r
@@ -1252,9 +599,9 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
                             pa[3] = pa[0];\r
                             pa[4] = pa[1];\r
                             pa[5] = pa[2];\r
-                            pa[0] = p[0] + xx;\r
-                            pa[1] = p[1] + yy;\r
-                            pa[2] = p[2] + zz;\r
+                            pa[0] = p[0] + i;\r
+                            pa[1] = p[1] + j;\r
+                            pa[2] = p[2] + k;\r
                         } else if (d < da[1]) {\r
                             da[3] = da[2];\r
                             da[2] = da[1];\r
@@ -1265,108 +612,119 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
                             pa[6] = pa[3];\r
                             pa[7] = pa[4];\r
                             pa[8] = pa[5];\r
-                            pa[3] = p[0] + xx;\r
-                            pa[4] = p[1] + yy;\r
-                            pa[5] = p[2] + zz;\r
+                            pa[3] = p[0] + i;\r
+                            pa[4] = p[1] + j;\r
+                            pa[5] = p[2] + k;\r
                         } else if (d < da[2]) {\r
                             da[3] = da[2];\r
                             da[2] = d;\r
                             pa[9] = pa[6];\r
                             pa[10] = pa[7];\r
                             pa[11] = pa[8];\r
-                            pa[6] = p[0] + xx;\r
-                            pa[7] = p[1] + yy;\r
-                            pa[8] = p[2] + zz;\r
+                            pa[6] = p[0] + i;\r
+                            pa[7] = p[1] + j;\r
+                            pa[8] = p[2] + k;\r
                         } else if (d < da[3]) {\r
                             da[3] = d;\r
-                            pa[9] = p[0] + xx;\r
-                            pa[10] = p[1] + yy;\r
-                            pa[11] = p[2] + zz;\r
+                            pa[9] = p[0] + i;\r
+                            pa[10] = p[1] + j;\r
+                            pa[11] = p[2] + k;\r
                         }\r
                     }\r
                 }\r
             }\r
         }\r
-\r
-        // needed for voronoi\r
-        protected static float[] hashPoint(int x, int y, int z) {\r
-            float[] result = new float[3];\r
-            result[0] = hashpntf[3 * hash[hash[hash[z & 255] + y & 255] + x & 255]];\r
-            result[1] = hashpntf[3 * hash[hash[hash[z & 255] + y & 255] + x & 255] + 1];\r
-            result[2] = hashpntf[3 * hash[hash[hash[z & 255] + y & 255] + x & 255] + 2];\r
-            return result;\r
-        }\r
-\r
-        public float noise3Perlin(float[] vec) {\r
-            int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;\r
-            float rx0, rx1, ry0, ry1, rz0, rz1, sx, sy, sz, a, b, c, d, t, u, v;\r
-            int i, j;\r
-\r
-            t = vec[0] + 10000.0f;\r
-            bx0 = (int) t & 255;\r
-            bx1 = bx0 + 1 & 255;\r
-            rx0 = t - (int) t;\r
-            rx1 = rx0 - 1.0f;\r
+        \r
+        // instead of adding another permutation array, just use hash table defined above\r
+        public static float newPerlin(float x, float y, float z) {\r
+            int A, AA, AB, B, BA, BB;\r
+            float floorX = (float) Math.floor(x), floorY = (float) Math.floor(y), floorZ = (float) Math.floor(z);\r
+            int intX = (int) floorX & 0xFF, intY = (int) floorY & 0xFF, intZ = (int) floorZ & 0xFF;\r
+            x -= floorX;\r
+            y -= floorY;\r
+            z -= floorZ;\r
+            //computing fading curves\r
+            floorX = NoiseMath.npfade(x);\r
+            floorY = NoiseMath.npfade(y);\r
+            floorZ = NoiseMath.npfade(z);\r
+            A = hash[intX] + intY;\r
+            AA = hash[A] + intZ;\r
+            AB = hash[A + 1] + intZ;\r
+            B = hash[intX + 1] + intY;\r
+            BA = hash[B] + intZ;\r
+            BB = hash[B + 1] + intZ;\r
+            return  NoiseMath.lerp(floorZ, NoiseMath.lerp(floorY, NoiseMath.lerp(floorX, NoiseMath.grad(hash[AA], x, y, z),\r
+                       NoiseMath.grad(hash[BA], x - 1, y, z)),\r
+                       NoiseMath.lerp(floorX, NoiseMath.grad(hash[AB], x, y - 1, z),\r
+                       NoiseMath.grad(hash[BB], x - 1, y - 1, z))),\r
+                       NoiseMath.lerp(floorY, NoiseMath.lerp(floorX, NoiseMath.grad(hash[AA + 1], x, y, z - 1),\r
+                       NoiseMath.grad(hash[BA + 1], x - 1, y, z - 1)),\r
+                       NoiseMath.lerp(floorX, NoiseMath.grad(hash[AB + 1], x, y - 1, z - 1), \r
+                       NoiseMath.grad(hash[BB + 1], x - 1, y - 1, z - 1))));\r
+        }\r
+\r
+        public static float noise3Perlin(float x, float y, float z) {\r
+            float t = x + 10000.0f;\r
+            int bx0 = (int) t & 0xFF;\r
+            int bx1 = bx0 + 1 & 0xFF;\r
+            float rx0 = t - (int) t;\r
+            float rx1 = rx0 - 1.0f;\r
             \r
-            t = vec[0] + 10000.0f;\r
-            by0 = (int) t & 255;\r
-            by1 = by0 + 1 & 255;\r
-            ry0 = t - (int) t;\r
-            ry1 = ry0 - 1.0f;\r
+            t = y + 10000.0f;\r
+            int by0 = (int) t & 0xFF;\r
+            int by1 = by0 + 1 & 0xFF;\r
+            float ry0 = t - (int) t;\r
+            float ry1 = ry0 - 1.0f;\r
             \r
-            t = vec[0] + 10000.0f;\r
-            bz0 = (int) t & 255;\r
-            bz1 = bz0 + 1 & 255;\r
-            rz0 = t - (int) t;\r
-            rz1 = rz0 - 1.0f;\r
-\r
-            i = p[bx0];\r
-            j = p[bx1];\r
-\r
-            b00 = p[i + by0];\r
-            b10 = p[j + by0];\r
-            b01 = p[i + by1];\r
-            b11 = p[j + by1];\r
-\r
-            // lerp moved to improved perlin above\r
-\r
-            sx = this.surve(rx0);\r
-            sy = this.surve(ry0);\r
-            sz = this.surve(rz0);\r
-\r
-            float[] q = new float[3];\r
-            q = g[b00 + bz0];\r
-            u = this.at(rx0, ry0, rz0, q);\r
+            t = z + 10000.0f;\r
+            int bz0 = (int) t & 0xFF;\r
+            int bz1 = bz0 + 1 & 0xFF;\r
+            float rz0 = t - (int) t;\r
+            float rz1 = rz0 - 1.0f;\r
+\r
+            int i = p[bx0];\r
+            int j = p[bx1];\r
+\r
+            int b00 = p[i + by0];\r
+            int b10 = p[j + by0];\r
+            int b01 = p[i + by1];\r
+            int b11 = p[j + by1];\r
+\r
+            float sx = NoiseMath.surve(rx0);\r
+            float sy = NoiseMath.surve(ry0);\r
+            float sz = NoiseMath.surve(rz0);\r
+\r
+            float[] q = g[b00 + bz0];\r
+            float u = NoiseMath.at(rx0, ry0, rz0, q);\r
             q = g[b10 + bz0];\r
-            v = this.at(rx1, ry0, rz0, q);\r
-            a = this.lerp(sx, u, v);\r
+            float v = NoiseMath.at(rx1, ry0, rz0, q);\r
+            float a = NoiseMath.lerp(sx, u, v);\r
 \r
             q = g[b01 + bz0];\r
-            u = this.at(rx0, ry1, rz0, q);\r
+            u = NoiseMath.at(rx0, ry1, rz0, q);\r
             q = g[b11 + bz0];\r
-            v = this.at(rx1, ry1, rz0, q);\r
-            b = this.lerp(sx, u, v);\r
+            v = NoiseMath.at(rx1, ry1, rz0, q);\r
+            float b = NoiseMath.lerp(sx, u, v);\r
 \r
-            c = this.lerp(sy, a, b); // interpolate in y at lo x\r
+            float c = NoiseMath.lerp(sy, a, b);\r
 \r
             q = g[b00 + bz1];\r
-            u = this.at(rx0, ry0, rz1, q);\r
+            u = NoiseMath.at(rx0, ry0, rz1, q);\r
             q = g[b10 + bz1];\r
-            v = this.at(rx1, ry0, rz1, q);\r
-            a = this.lerp(sx, u, v);\r
+            v = NoiseMath.at(rx1, ry0, rz1, q);\r
+            a = NoiseMath.lerp(sx, u, v);\r
 \r
             q = g[b01 + bz1];\r
-            u = this.at(rx0, ry1, rz1, q);\r
+            u = NoiseMath.at(rx0, ry1, rz1, q);\r
             q = g[b11 + bz1];\r
-            v = this.at(rx1, ry1, rz1, q);\r
-            b = this.lerp(sx, u, v);\r
+            v = NoiseMath.at(rx1, ry1, rz1, q);\r
+            b = NoiseMath.lerp(sx, u, v);\r
 \r
-            d = this.lerp(sy, a, b); // interpolate in y at hi x\r
-\r
-            return 1.5f * this.lerp(sz, c, d); // interpolate in z\r
+            float d = NoiseMath.lerp(sy, a, b);\r
+            return 1.5f * NoiseMath.lerp(sz, c, d);\r
         }\r
 \r
-        public float orgBlenderNoise(float x, float y, float z) {\r
+        public static float originalBlenderNoise(float x, float y, float z) {\r
             float n = 0.5f;\r
 \r
             int ix = (int) Math.floor(x);\r
@@ -1394,47 +752,25 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
             cn4 = 1.0f - 3.0f * cn4 - 2.0f * cn4 * jx;\r
             cn5 = 1.0f - 3.0f * cn5 - 2.0f * cn5 * jy;\r
             cn6 = 1.0f - 3.0f * cn6 - 2.0f * cn6 * jz;\r
-\r
-            int b00 = hash[hash[ix & 255] + (iy & 255)];\r
-            int b10 = hash[hash[ix + 1 & 255] + (iy & 255)];\r
-            int b01 = hash[hash[ix & 255] + (iy + 1 & 255)];\r
-            int b11 = hash[hash[ix + 1 & 255] + (iy + 1 & 255)];\r
-\r
-            int b20 = iz & 255;\r
-            int b21 = iz + 1 & 255;\r
-\r
-            // 0\r
-            float i = cn1 * cn2 * cn3;\r
-            int hIndex = 3 * hash[b20 + b00];\r
-            n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * oz);\r
-            // 1\r
-            i = cn1 * cn2 * cn6;\r
-            hIndex = 3 * hash[b21 + b00];\r
-            n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * jz);\r
-            // 2\r
-            i = cn1 * cn5 * cn3;\r
-            hIndex = 3 * hash[b20 + b01];\r
-            n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * oz);\r
-            // 3\r
-            i = cn1 * cn5 * cn6;\r
-            hIndex = 3 * hash[b21 + b01];\r
-            n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * jz);\r
-            // 4\r
-            i = cn4 * cn2 * cn3;\r
-            hIndex = 3 * hash[b20 + b10];\r
-            n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * oz);\r
-            // 5\r
-            i = cn4 * cn2 * cn6;\r
-            hIndex = 3 * hash[b21 + b10];\r
-            n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * jz);\r
-            // 6\r
-            i = cn4 * cn5 * cn3;\r
-            hIndex = 3 * hash[b20 + b11];\r
-            n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * oz);\r
-            // 7\r
-            i = cn4 * cn5 * cn6;\r
-            hIndex = 3 * hash[b21 + b11];\r
-            n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * jz);\r
+            float[] cn = new float[] {cn1 * cn2 * cn3, cn1 * cn2 * cn6, cn1 * cn5 * cn3, cn1 * cn5 * cn6,\r
+                                         cn4 * cn2 * cn3, cn4 * cn2 * cn6, cn4 * cn5 * cn3, cn4 * cn5 * cn6,};\r
+            \r
+            int b00 = hash[hash[ix & 0xFF] + (iy & 0xFF)];\r
+            int b01 = hash[hash[ix & 0xFF] + (iy + 1 & 0xFF)];\r
+            int b10 = hash[hash[ix + 1 & 0xFF] + (iy & 0xFF)];\r
+            int b11 = hash[hash[ix + 1 & 0xFF] + (iy + 1 & 0xFF)];\r
+            int[] b1 = new int[] {b00, b00, b01, b01, b10, b10, b11, b11};\r
+            \r
+            int[] b2 = new int[] {iz & 0xFF, iz + 1 & 0xFF};\r
+            \r
+            float[] xFactor = new float[] {ox, ox, ox, ox, jx, jx, jx, jx};\r
+            float[] yFactor = new float[] {oy, oy, jy, jy, oy, oy, jy, jy};\r
+            float[] zFactor = new float[] {oz, jz, oz, jz, oz, jz, oz, jz};\r
+            \r
+            for(int i=0;i<8;++i) {\r
+               int hIndex = 3 * hash[b1[i] + b2[i%2]];\r
+               n += cn[i] * (hashvectf[hIndex] * xFactor[i] + hashvectf[hIndex + 1] * yFactor[i] + hashvectf[hIndex + 2] * zFactor[i]);\r
+            }\r
 \r
             if (n < 0.0f) {\r
                 n = 0.0f;\r
@@ -1443,79 +779,67 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
             }\r
             return n;\r
         }\r
+    }\r
 \r
-        // instead of adding another permutation array, just use hash table defined above\r
-        public float newPerlin(float x, float y, float z) {\r
-            int A, AA, AB, B, BA, BB;\r
-            float u = (float) Math.floor(x), v = (float) Math.floor(y), w = (float) Math.floor(z);\r
-            int X = (int) u & 255, Y = (int) v & 255, Z = (int) w & 255; // FIND UNIT CUBE THAT CONTAINS POINT\r
-            x -= u; // FIND RELATIVE X,Y,Z\r
-            y -= v; // OF POINT IN CUBE.\r
-            z -= w;\r
-            u = this.npfade(x); // COMPUTE FADE CURVES\r
-            v = this.npfade(y); // FOR EACH OF X,Y,Z.\r
-            w = this.npfade(z);\r
-            A = hash[X] + Y;\r
-            AA = hash[A] + Z;\r
-            AB = hash[A + 1] + Z; // HASH COORDINATES OF\r
-            B = hash[X + 1] + Y;\r
-            BA = hash[B] + Z;\r
-            BB = hash[B + 1] + Z; // THE 8 CUBE CORNERS,\r
-            return this.lerp(w, this.lerp(v, this.lerp(u, this.grad(hash[AA], x, y, z), // AND ADD\r
-                    this.grad(hash[BA], x - 1, y, z)), // BLENDED\r
-                    this.lerp(u, this.grad(hash[AB], x, y - 1, z), // RESULTS\r
-                    this.grad(hash[BB], x - 1, y - 1, z))),// FROM 8\r
-                    this.lerp(v, this.lerp(u, this.grad(hash[AA + 1], x, y, z - 1), // CORNERS\r
-                    this.grad(hash[BA + 1], x - 1, y, z - 1)), // OF CUBE\r
-                    this.lerp(u, this.grad(hash[AB + 1], x, y - 1, z - 1), this.grad(hash[BB + 1], x - 1, y - 1, z - 1))));\r
-        }\r
+    /**\r
+     * This class is abstract to the noise functions computations. It has two methods. One calculates the Signed (with\r
+     * 'S' at the end) and the other Unsigned value.\r
+     * @author Marcin Roguski (Kaelthas)\r
+     */\r
+    interface NoiseFunction {\r
 \r
         /**\r
-         * Returns a vector/point/color in ca, using point hasharray directly\r
+         * This method calculates the unsigned value of the noise.\r
+         * @param x\r
+         *        the x texture coordinate\r
+         * @param y\r
+         *        the y texture coordinate\r
+         * @param z\r
+         *        the z texture coordinate\r
+         * @return value of the noise\r
          */\r
-        protected static void cellNoiseV(float x, float y, float z, float[] ca) {\r
-            int xi = (int) Math.floor(x);\r
-            int yi = (int) Math.floor(y);\r
-            int zi = (int) Math.floor(z);\r
-            float[] p = AbstractNoiseFunc.hashPoint(xi, yi, zi);\r
-            ca[0] = p[0];\r
-            ca[1] = p[1];\r
-            ca[2] = p[2];\r
-        }\r
+        float execute(float x, float y, float z);\r
 \r
-        protected float lerp(float t, float a, float b) {\r
+        /**\r
+         * This method calculates the signed value of the noise.\r
+         * @param x\r
+         *        the x texture coordinate\r
+         * @param y\r
+         *        the y texture coordinate\r
+         * @param z\r
+         *        the z texture coordinate\r
+         * @return value of the noise\r
+         */\r
+        float executeSigned(float x, float y, float z);\r
+    }\r
+    \r
+    public static class NoiseMath {\r
+       public static float lerp(float t, float a, float b) {\r
             return a + t * (b - a);\r
         }\r
 \r
-        protected float npfade(float t) {\r
+       public static float npfade(float t) {\r
             return t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f);\r
         }\r
 \r
-        protected float grad(int hash, float x, float y, float z) {\r
-            int h = hash & 0x0F; // CONVERT LO 4 BITS OF HASH CODE\r
-            float u = h < 8 ? x : y, // INTO 12 GRADIENT DIRECTIONS.\r
-                    v = h < 4 ? y : h == 12 || h == 14 ? x : z;\r
+       public static float grad(int hash, float x, float y, float z) {\r
+            int h = hash & 0x0F;\r
+            float u = h < 8 ? x : y, v = h < 4 ? y : h == 12 || h == 14 ? x : z;\r
             return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);\r
         }\r
 \r
-        /**\r
-         * Dot product of two vectors.\r
-         * @param a\r
-         *        the first vector\r
-         * @param b\r
-         *        the second vector\r
-         * @return the dot product of two vectors\r
-         */\r
-        protected float dot(float[] a, float[] b) {\r
-            return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\r
-        }\r
-\r
-        protected float surve(float t) {\r
+       public static float surve(float t) {\r
             return t * t * (3.0f - 2.0f * t);\r
         }\r
 \r
-        protected float at(float rx, float ry, float rz, float[] q) {\r
-            return rx * q[0] + ry * q[1] + rz * q[2];\r
+       public static float at(float x, float y, float z, float[] q) {\r
+            return x * q[0] + y * q[1] + z * q[2];\r
+        }\r
+       \r
+       public static void hash(int x, int y, int z, float[] result) {\r
+            result[0] = hashpntf[3 * hash[hash[hash[z & 0xFF] + y & 0xFF] + x & 0xFF]];\r
+            result[1] = hashpntf[3 * hash[hash[hash[z & 0xFF] + y & 0xFF] + x & 0xFF] + 1];\r
+            result[2] = hashpntf[3 * hash[hash[hash[z & 0xFF] + y & 0xFF] + x & 0xFF] + 2];\r
         }\r
     }\r
     \r
@@ -1528,7 +852,7 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
      * This interface is used for distance calculation classes. Distance metrics for voronoi. e parameter only used in\r
      * Minkovsky.\r
      */\r
-    interface DistanceFunc {\r
+    interface DistanceFunction {\r
 \r
         /**\r
          * This method calculates the distance for voronoi algorithms.\r
@@ -1547,6 +871,6 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
 \r
     interface MusgraveFunction {\r
 \r
-        float execute(Structure tex, float x, float y, float z);\r
+        float execute(MusgraveData musgraveData, float x, float y, float z);\r
     }\r
 }\r
index f479b56..ac23b37 100644 (file)
@@ -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();
+               }
+       }
 }
index 7798dfb..bb2bb83 100644 (file)
@@ -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);
+       }
 }
index 9b3cbd5..ffb6abd 100644 (file)
@@ -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));
        }
 }
index a7bd7fc..a1ffab9 100644 (file)
@@ -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
+    }
 }
index 6045365..9b2002f 100644 (file)
@@ -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);
        }
 }
index d84784e..af88771 100644 (file)
@@ -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;
+               }
+    }
 }
index 02c58b0..8877ef4 100644 (file)
@@ -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();
+               }
+    }
 }
index 2c9429a..9213906 100644 (file)
@@ -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));
        }
 }
index 85f5cf8..4da0d02 100644 (file)
@@ -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));
        }
 }
index 890de25..0448b29 100644 (file)
@@ -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);
+    }
 }
index 4466f5f..f9bd7f9 100644 (file)
@@ -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);
+    }
 }
index a5717d0..18cbae3 100644 (file)
@@ -34,8 +34,6 @@ package com.jme3.scene.plugins.blender.textures;
 import java.awt.color.ColorSpace;\r
 import java.awt.image.BufferedImage;\r
 import java.awt.image.ColorConvertOp;\r
-import java.io.IOException;\r
-import java.io.InputStream;\r
 import java.nio.ByteBuffer;\r
 import java.util.ArrayList;\r
 import java.util.HashMap;\r
@@ -58,7 +56,6 @@ import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
 import com.jme3.scene.plugins.blender.DataRepository;\r
 import com.jme3.scene.plugins.blender.DataRepository.LoadedFeatureDataType;\r
 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;\r
-import com.jme3.scene.plugins.blender.file.DynamicArray;\r
 import com.jme3.scene.plugins.blender.file.FileBlockHeader;\r
 import com.jme3.scene.plugins.blender.file.Pointer;\r
 import com.jme3.scene.plugins.blender.file.Structure;\r
@@ -78,7 +75,7 @@ import com.jme3.util.BufferUtils;
  */\r
 public class TextureHelper extends AbstractBlenderHelper {\r
        private static final Logger     LOGGER                          = Logger.getLogger(TextureHelper.class.getName());\r
-       \r
+\r
        // texture types\r
        public static final int         TEX_NONE                        = 0;\r
        public static final int         TEX_CLOUDS                      = 1;\r
@@ -95,8 +92,8 @@ public class TextureHelper extends AbstractBlenderHelper {
        public static final int         TEX_VORONOI                     = 12;\r
        public static final int         TEX_DISTNOISE           = 13;\r
        public static final int         TEX_POINTDENSITY        = 14;//v. 25+\r
-    public static final int    TEX_VOXELDATA           = 15;//v. 25+\r
-    \r
+       public static final int         TEX_VOXELDATA           = 15;//v. 25+\r
+\r
        // mapto\r
        public static final int         MAP_COL                         = 1;\r
        public static final int         MAP_NORM                        = 2;\r
@@ -132,27 +129,9 @@ public class TextureHelper extends AbstractBlenderHelper {
        public static final int         MTEX_BLEND_COLOR        = 13;\r
        public static final int         MTEX_NUM_BLENDTYPES     = 14;\r
 \r
-       // variables used in rampBlend method\r
-       public static final int         MA_RAMP_BLEND           = 0;\r
-       public static final int         MA_RAMP_ADD                     = 1;\r
-       public static final int         MA_RAMP_MULT            = 2;\r
-       public static final int         MA_RAMP_SUB                     = 3;\r
-       public static final int         MA_RAMP_SCREEN          = 4;\r
-       public static final int         MA_RAMP_DIV                     = 5;\r
-       public static final int         MA_RAMP_DIFF            = 6;\r
-       public static final int         MA_RAMP_DARK            = 7;\r
-       public static final int         MA_RAMP_LIGHT           = 8;\r
-       public static final int         MA_RAMP_OVERLAY         = 9;\r
-       public static final int         MA_RAMP_DODGE           = 10;\r
-       public static final int         MA_RAMP_BURN            = 11;\r
-       public static final int         MA_RAMP_HUE                     = 12;\r
-       public static final int         MA_RAMP_SAT                     = 13;\r
-       public static final int         MA_RAMP_VAL                     = 14;\r
-       public static final int         MA_RAMP_COLOR           = 15;\r
-\r
        protected NoiseGenerator noiseGenerator;\r
        private Map<Integer, TextureGenerator> textureGenerators = new HashMap<Integer, TextureGenerator>();\r
-       \r
+\r
        /**\r
         * This constructor parses the given blender version and stores the result.\r
         * It creates noise generator and texture generators.\r
@@ -196,42 +175,42 @@ public class TextureHelper extends AbstractBlenderHelper {
                int width = dataRepository.getBlenderKey().getGeneratedTextureWidth();\r
                int height = dataRepository.getBlenderKey().getGeneratedTextureHeight();\r
                int depth = dataRepository.getBlenderKey().getGeneratedTextureDepth();\r
-               \r
+\r
                switch (type) {\r
-                       case TEX_IMAGE:// (it is first because probably this will be most commonly used)\r
-                               Pointer pImage = (Pointer) tex.getFieldValue("ima");\r
-                if (pImage.isNotNull()){\r
-                    Structure image = pImage.fetchData(dataRepository.getInputStream()).get(0);\r
-                    result = this.getTextureFromImage(image, dataRepository);\r
-                }\r
-                               break;\r
-                       case TEX_CLOUDS:\r
-                       case TEX_WOOD:\r
-                       case TEX_MARBLE:\r
-                       case TEX_MAGIC:\r
-                       case TEX_BLEND:\r
-                       case TEX_STUCCI:\r
-                       case TEX_NOISE:\r
-                       case TEX_MUSGRAVE:\r
-                       case TEX_VORONOI:\r
-                       case TEX_DISTNOISE:\r
-                               TextureGenerator textureGenerator = textureGenerators.get(Integer.valueOf(type));\r
-                               result = textureGenerator.generate(tex, width, height, depth, dataRepository);\r
-                               break;\r
-                       case TEX_NONE:// No texture, do nothing\r
-                               break;\r
-                       case TEX_POINTDENSITY:\r
-                LOGGER.warning("Point density texture loading currently not supported!");\r
-                break;\r
-            case TEX_VOXELDATA:\r
-                LOGGER.warning("Voxel data texture loading currently not supported!");\r
-                break;\r
-                       case TEX_PLUGIN:\r
-                       case TEX_ENVMAP:// TODO: implement envmap texture\r
-                               LOGGER.log(Level.WARNING, "Unsupported texture type: {0} for texture: {1}", new Object[]{type, tex.getName()});\r
-                               break;\r
-                       default:\r
-                               throw new BlenderFileException("Unknown texture type: " + type + " for texture: " + tex.getName());\r
+               case TEX_IMAGE:// (it is first because probably this will be most commonly used)\r
+                       Pointer pImage = (Pointer) tex.getFieldValue("ima");\r
+                       if (pImage.isNotNull()){\r
+                               Structure image = pImage.fetchData(dataRepository.getInputStream()).get(0);\r
+                               result = this.getTextureFromImage(image, dataRepository);\r
+                       }\r
+                       break;\r
+               case TEX_CLOUDS:\r
+               case TEX_WOOD:\r
+               case TEX_MARBLE:\r
+               case TEX_MAGIC:\r
+               case TEX_BLEND:\r
+               case TEX_STUCCI:\r
+               case TEX_NOISE:\r
+               case TEX_MUSGRAVE:\r
+               case TEX_VORONOI:\r
+               case TEX_DISTNOISE:\r
+                       TextureGenerator textureGenerator = textureGenerators.get(Integer.valueOf(type));\r
+                       result = textureGenerator.generate(tex, width, height, depth, dataRepository);\r
+                       break;\r
+               case TEX_NONE:// No texture, do nothing\r
+                       break;\r
+               case TEX_POINTDENSITY:\r
+                       LOGGER.warning("Point density texture loading currently not supported!");\r
+                       break;\r
+               case TEX_VOXELDATA:\r
+                       LOGGER.warning("Voxel data texture loading currently not supported!");\r
+                       break;\r
+               case TEX_PLUGIN:\r
+               case TEX_ENVMAP:// TODO: implement envmap texture\r
+                       LOGGER.log(Level.WARNING, "Unsupported texture type: {0} for texture: {1}", new Object[]{type, tex.getName()});\r
+                       break;\r
+               default:\r
+                       throw new BlenderFileException("Unknown texture type: " + type + " for texture: " + tex.getName());\r
                }\r
                if (result != null) {\r
                        result.setName(tex.getName());\r
@@ -282,7 +261,7 @@ public class TextureHelper extends AbstractBlenderHelper {
                        newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));\r
                        newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));\r
                        newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));\r
-            newData.put(dataIndex++, (byte) 255.0f);//1.0f * 255.0f\r
+                       newData.put(dataIndex++, (byte) 255.0f);//1.0f * 255.0f\r
                }\r
                if(texture.getType()==Texture.Type.TwoDimensional) {\r
                        return new Texture2D(new Image(Format.RGBA8, width, height, newData));\r
@@ -312,88 +291,87 @@ public class TextureHelper extends AbstractBlenderHelper {
         * @return texture intensity for the current pixel\r
         */\r
        protected float setupMaterialColor(ByteBuffer data, Format imageFormat, boolean neg, float[] materialColor) {\r
-               // at least one byte is always taken :)\r
                float tin = 0.0f;\r
-               byte pixelValue = data.get();\r
+               byte pixelValue = data.get();// at least one byte is always taken :)\r
                float firstPixelValue = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
                switch (imageFormat) {\r
-                       case ABGR8:\r
-                               pixelValue = data.get();\r
-                               materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
-                               pixelValue = data.get();\r
-                               materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
-                               pixelValue = data.get();\r
-                               materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
-                               break;\r
-                       case BGR8:\r
-                               materialColor[2] = firstPixelValue;\r
-                               pixelValue = data.get();\r
-                               materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
-                               pixelValue = data.get();\r
-                               materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
-                               break;\r
-                       case RGB8:\r
-                               materialColor[0] = firstPixelValue;\r
-                               pixelValue = data.get();\r
-                               materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
-                               pixelValue = data.get();\r
-                               materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
-                               break;\r
-                       case RGBA8:\r
-                               materialColor[0] = firstPixelValue;\r
-                               pixelValue = data.get();\r
-                               materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
-                               pixelValue = data.get();\r
-                               materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
-                               data.get(); // ignore alpha\r
-                               break;\r
-                       case Luminance8:\r
-                               tin = neg ? 1.0f - firstPixelValue : firstPixelValue;\r
-                               neg = false;//do not negate the materialColor, it must be unchanged\r
-                               break;\r
-                       case Luminance8Alpha8:\r
-                               tin = neg ? 1.0f - firstPixelValue : firstPixelValue;\r
-                               neg = false;//do not negate the materialColor, it must be unchanged\r
-                               data.get(); // ignore alpha\r
-                               break;\r
-                       case Luminance16:\r
-                       case Luminance16Alpha16:\r
-                       case Alpha16:\r
-                       case Alpha8:\r
-                       case ARGB4444:\r
-                       case Depth:\r
-                       case Depth16:\r
-                       case Depth24:\r
-                       case Depth32:\r
-                       case Depth32F:\r
-                       case DXT1:\r
-                       case DXT1A:\r
-                       case DXT3:\r
-                       case DXT5:\r
-                       case Intensity16:\r
-                       case Intensity8:\r
-                       case LATC:\r
-                       case LTC:\r
-                       case Luminance16F:\r
-                       case Luminance16FAlpha16F:\r
-                       case Luminance32F:\r
-                       case RGB10:\r
-                       case RGB111110F:\r
-                       case RGB16:\r
-                       case RGB16F:\r
-                       case RGB16F_to_RGB111110F:\r
-                       case RGB16F_to_RGB9E5:\r
-                       case RGB32F:\r
-                       case RGB565:\r
-                       case RGB5A1:\r
-                       case RGB9E5:\r
-                       case RGBA16:\r
-                       case RGBA16F:\r
-                       case RGBA32F:\r
-                               LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", imageFormat);\r
-                               break;\r
-                       default:\r
-                               throw new IllegalStateException("Unknown image format type: " + imageFormat);\r
+               case ABGR8:\r
+                       pixelValue = data.get();\r
+                       materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
+                       pixelValue = data.get();\r
+                       materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
+                       pixelValue = data.get();\r
+                       materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
+                       break;\r
+               case BGR8:\r
+                       materialColor[2] = firstPixelValue;\r
+                       pixelValue = data.get();\r
+                       materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
+                       pixelValue = data.get();\r
+                       materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
+                       break;\r
+               case RGB8:\r
+                       materialColor[0] = firstPixelValue;\r
+                       pixelValue = data.get();\r
+                       materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
+                       pixelValue = data.get();\r
+                       materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
+                       break;\r
+               case RGBA8:\r
+                       materialColor[0] = firstPixelValue;\r
+                       pixelValue = data.get();\r
+                       materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
+                       pixelValue = data.get();\r
+                       materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;\r
+                       data.get(); // ignore alpha\r
+                       break;\r
+               case Luminance8:\r
+                       tin = neg ? 1.0f - firstPixelValue : firstPixelValue;\r
+                       neg = false;//do not negate the materialColor, it must be unchanged\r
+                       break;\r
+               case Luminance8Alpha8:\r
+                       tin = neg ? 1.0f - firstPixelValue : firstPixelValue;\r
+                       neg = false;//do not negate the materialColor, it must be unchanged\r
+                       data.get(); // ignore alpha\r
+                       break;\r
+               case Luminance16:\r
+               case Luminance16Alpha16:\r
+               case Alpha16:\r
+               case Alpha8:\r
+               case ARGB4444:\r
+               case Depth:\r
+               case Depth16:\r
+               case Depth24:\r
+               case Depth32:\r
+               case Depth32F:\r
+               case DXT1:\r
+               case DXT1A:\r
+               case DXT3:\r
+               case DXT5:\r
+               case Intensity16:\r
+               case Intensity8:\r
+               case LATC:\r
+               case LTC:\r
+               case Luminance16F:\r
+               case Luminance16FAlpha16F:\r
+               case Luminance32F:\r
+               case RGB10:\r
+               case RGB111110F:\r
+               case RGB16:\r
+               case RGB16F:\r
+               case RGB16F_to_RGB111110F:\r
+               case RGB16F_to_RGB9E5:\r
+               case RGB32F:\r
+               case RGB565:\r
+               case RGB5A1:\r
+               case RGB9E5:\r
+               case RGBA16:\r
+               case RGBA16F:\r
+               case RGBA32F:\r
+                       LOGGER.log(Level.WARNING, "Image type not yet supported for blending: {0}", imageFormat);\r
+                       break;\r
+               default:\r
+                       throw new IllegalStateException("Unknown image format type: " + imageFormat);\r
                }\r
                if (neg) {\r
                        materialColor[0] = 1.0f - materialColor[0];\r
@@ -422,64 +400,59 @@ public class TextureHelper extends AbstractBlenderHelper {
         *        the data repository\r
         */\r
        protected void blendPixel(float[] result, float[] materialColor, float[] color, float textureIntensity, float textureFactor, int blendtype, DataRepository dataRepository) {\r
-               float facm, col;\r
-\r
+               float oneMinusFactor, col;\r
+               textureIntensity *= textureFactor;\r
+               \r
                switch (blendtype) {\r
                        case MTEX_BLEND:\r
-                               textureIntensity *= textureFactor;\r
-                               facm = 1.0f - textureIntensity;\r
-                               result[0] = textureIntensity * color[0] + facm * materialColor[0];\r
-                               result[1] = textureIntensity * color[1] + facm * materialColor[1];\r
-                               result[2] = textureIntensity * color[2] + facm * materialColor[2];\r
+                               oneMinusFactor = 1.0f - textureIntensity;\r
+                               result[0] = textureIntensity * color[0] + oneMinusFactor * materialColor[0];\r
+                               result[1] = textureIntensity * color[1] + oneMinusFactor * materialColor[1];\r
+                               result[2] = textureIntensity * color[2] + oneMinusFactor * materialColor[2];\r
                                break;\r
                        case MTEX_MUL:\r
-                               textureIntensity *= textureFactor;\r
-                               facm = 1.0f - textureFactor;\r
-                               result[0] = (facm + textureIntensity * materialColor[0]) * color[0];\r
-                               result[1] = (facm + textureIntensity * materialColor[1]) * color[1];\r
-                               result[2] = (facm + textureIntensity * materialColor[2]) * color[2];\r
+                               oneMinusFactor = 1.0f - textureFactor;\r
+                               result[0] = (oneMinusFactor + textureIntensity * materialColor[0]) * color[0];\r
+                               result[1] = (oneMinusFactor + textureIntensity * materialColor[1]) * color[1];\r
+                               result[2] = (oneMinusFactor + textureIntensity * materialColor[2]) * color[2];\r
                                break;\r
                        case MTEX_DIV:\r
-                               textureIntensity *= textureFactor;\r
-                               facm = 1.0f - textureIntensity;\r
+                               oneMinusFactor = 1.0f - textureIntensity;\r
                                if (color[0] != 0.0) {\r
-                                       result[0] = (facm * materialColor[0] + textureIntensity * materialColor[0] / color[0]) * 0.5f;\r
+                                       result[0] = (oneMinusFactor * materialColor[0] + textureIntensity * materialColor[0] / color[0]) * 0.5f;\r
                                }\r
                                if (color[1] != 0.0) {\r
-                                       result[1] = (facm * materialColor[1] + textureIntensity * materialColor[1] / color[1]) * 0.5f;\r
+                                       result[1] = (oneMinusFactor * materialColor[1] + textureIntensity * materialColor[1] / color[1]) * 0.5f;\r
                                }\r
                                if (color[2] != 0.0) {\r
-                                       result[2] = (facm * materialColor[2] + textureIntensity * materialColor[2] / color[2]) * 0.5f;\r
+                                       result[2] = (oneMinusFactor * materialColor[2] + textureIntensity * materialColor[2] / color[2]) * 0.5f;\r
                                }\r
                                break;\r
                        case MTEX_SCREEN:\r
-                               textureIntensity *= textureFactor;\r
-                               facm = 1.0f - textureFactor;\r
-                               result[0] = 1.0f - (facm + textureIntensity * (1.0f - materialColor[0])) * (1.0f - color[0]);\r
-                               result[1] = 1.0f - (facm + textureIntensity * (1.0f - materialColor[1])) * (1.0f - color[1]);\r
-                               result[2] = 1.0f - (facm + textureIntensity * (1.0f - materialColor[2])) * (1.0f - color[2]);\r
+                               oneMinusFactor = 1.0f - textureFactor;\r
+                               result[0] = 1.0f - (oneMinusFactor + textureIntensity * (1.0f - materialColor[0])) * (1.0f - color[0]);\r
+                               result[1] = 1.0f - (oneMinusFactor + textureIntensity * (1.0f - materialColor[1])) * (1.0f - color[1]);\r
+                               result[2] = 1.0f - (oneMinusFactor + textureIntensity * (1.0f - materialColor[2])) * (1.0f - color[2]);\r
                                break;\r
                        case MTEX_OVERLAY:\r
-                               textureIntensity *= textureFactor;\r
-                               facm = 1.0f - textureFactor;\r
+                               oneMinusFactor = 1.0f - textureFactor;\r
                                if (materialColor[0] < 0.5f) {\r
-                                       result[0] = color[0] * (facm + 2.0f * textureIntensity * materialColor[0]);\r
+                                       result[0] = color[0] * (oneMinusFactor + 2.0f * textureIntensity * materialColor[0]);\r
                                } else {\r
-                                       result[0] = 1.0f - (facm + 2.0f * textureIntensity * (1.0f - materialColor[0])) * (1.0f - color[0]);\r
+                                       result[0] = 1.0f - (oneMinusFactor + 2.0f * textureIntensity * (1.0f - materialColor[0])) * (1.0f - color[0]);\r
                                }\r
                                if (materialColor[1] < 0.5f) {\r
-                                       result[1] = color[1] * (facm + 2.0f * textureIntensity * materialColor[1]);\r
+                                       result[1] = color[1] * (oneMinusFactor + 2.0f * textureIntensity * materialColor[1]);\r
                                } else {\r
-                                       result[1] = 1.0f - (facm + 2.0f * textureIntensity * (1.0f - materialColor[1])) * (1.0f - color[1]);\r
+                                       result[1] = 1.0f - (oneMinusFactor + 2.0f * textureIntensity * (1.0f - materialColor[1])) * (1.0f - color[1]);\r
                                }\r
                                if (materialColor[2] < 0.5f) {\r
-                                       result[2] = color[2] * (facm + 2.0f * textureIntensity * materialColor[2]);\r
+                                       result[2] = color[2] * (oneMinusFactor + 2.0f * textureIntensity * materialColor[2]);\r
                                } else {\r
-                                       result[2] = 1.0f - (facm + 2.0f * textureIntensity * (1.0f - materialColor[2])) * (1.0f - color[2]);\r
+                                       result[2] = 1.0f - (oneMinusFactor + 2.0f * textureIntensity * (1.0f - materialColor[2])) * (1.0f - color[2]);\r
                                }\r
                                break;\r
                        case MTEX_SUB:\r
-                               textureIntensity *= textureFactor;\r
                                result[0] = materialColor[0] - textureIntensity * color[0];\r
                                result[1] = materialColor[1] - textureIntensity * color[1];\r
                                result[2] = materialColor[2] - textureIntensity * color[2];\r
@@ -488,20 +461,17 @@ public class TextureHelper extends AbstractBlenderHelper {
                                result[2] = FastMath.clamp(result[2], 0.0f, 1.0f);\r
                                break;\r
                        case MTEX_ADD:\r
-                               textureIntensity *= textureFactor;\r
                                result[0] = (textureIntensity * color[0] + materialColor[0]) * 0.5f;\r
                                result[1] = (textureIntensity * color[1] + materialColor[1]) * 0.5f;\r
                                result[2] = (textureIntensity * color[2] + materialColor[2]) * 0.5f;\r
                                break;\r
                        case MTEX_DIFF:\r
-                               textureIntensity *= textureFactor;\r
-                               facm = 1.0f - textureIntensity;\r
-                               result[0] = facm * color[0] + textureIntensity * Math.abs(materialColor[0] - color[0]);\r
-                               result[1] = facm * color[1] + textureIntensity * Math.abs(materialColor[1] - color[1]);\r
-                               result[2] = facm * color[2] + textureIntensity * Math.abs(materialColor[2] - color[2]);\r
+                               oneMinusFactor = 1.0f - textureIntensity;\r
+                               result[0] = oneMinusFactor * materialColor[0] + textureIntensity * Math.abs(materialColor[0] - color[0]);\r
+                               result[1] = oneMinusFactor * materialColor[1] + textureIntensity * Math.abs(materialColor[1] - color[1]);\r
+                               result[2] = oneMinusFactor * materialColor[2] + textureIntensity * Math.abs(materialColor[2] - color[2]);\r
                                break;\r
                        case MTEX_DARK:\r
-                               textureIntensity *= textureFactor;\r
                                col = textureIntensity * color[0];\r
                                result[0] = col < materialColor[0] ? col : materialColor[0];\r
                                col = textureIntensity * color[1];\r
@@ -510,7 +480,6 @@ public class TextureHelper extends AbstractBlenderHelper {
                                result[2] = col < materialColor[2] ? col : materialColor[2];\r
                                break;\r
                        case MTEX_LIGHT:\r
-                               textureIntensity *= textureFactor;\r
                                col = textureIntensity * color[0];\r
                                result[0] = col > materialColor[0] ? col : materialColor[0];\r
                                col = textureIntensity * color[1];\r
@@ -519,24 +488,11 @@ public class TextureHelper extends AbstractBlenderHelper {
                                result[2] = col > materialColor[2] ? col : materialColor[2];\r
                                break;\r
                        case MTEX_BLEND_HUE:\r
-                               textureIntensity *= textureFactor;\r
-                               System.arraycopy(materialColor, 0, result, 0, 3);\r
-                               this.rampBlend(MA_RAMP_HUE, result, textureIntensity, color, dataRepository);\r
-                               break;\r
                        case MTEX_BLEND_SAT:\r
-                               textureIntensity *= textureFactor;\r
-                               System.arraycopy(materialColor, 0, result, 0, 3);\r
-                               this.rampBlend(MA_RAMP_SAT, result, textureIntensity, color, dataRepository);\r
-                               break;\r
                        case MTEX_BLEND_VAL:\r
-                               textureIntensity *= textureFactor;\r
-                               System.arraycopy(materialColor, 0, result, 0, 3);\r
-                               this.rampBlend(MA_RAMP_VAL, result, textureIntensity, color, dataRepository);\r
-                               break;\r
                        case MTEX_BLEND_COLOR:\r
-                               textureIntensity *= textureFactor;\r
                                System.arraycopy(materialColor, 0, result, 0, 3);\r
-                               this.rampBlend(MA_RAMP_COLOR, result, textureIntensity, color, dataRepository);\r
+                               this.rampBlend(blendtype, result, textureIntensity, color, dataRepository);\r
                                break;\r
                        default:\r
                                throw new IllegalStateException("Unknown blend type: " + blendtype);\r
@@ -544,10 +500,10 @@ public class TextureHelper extends AbstractBlenderHelper {
        }\r
 \r
        /**\r
-        * The method that performs the ramp blending (whatever it is :P - copied from blender sources).\r
+        * The method that performs the ramp blending.\r
         * \r
         * @param type\r
-        *        the ramp type\r
+        *        the blend type\r
         * @param rgb\r
         *        the rgb value where the result is stored\r
         * @param fac\r
@@ -558,239 +514,60 @@ public class TextureHelper extends AbstractBlenderHelper {
         *        the data repository\r
         */\r
        protected void rampBlend(int type, float[] rgb, float fac, float[] col, DataRepository dataRepository) {\r
-               float tmp, facm = 1.0f - fac;\r
+               float oneMinusFactor = 1.0f - fac;\r
                MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class);\r
 \r
-               switch (type) {\r
-                       case MA_RAMP_HUE:\r
-                               if (rgb.length == 3) {\r
+               if (rgb.length >= 3) {\r
+                       switch (type) {\r
+                               case MTEX_BLEND_HUE: {\r
                                        float[] colorTransformResult = new float[3];\r
                                        materialHelper.rgbToHsv(col[0], col[1], col[2], colorTransformResult);\r
                                        if (colorTransformResult[1] != 0.0f) {\r
                                                float colH = colorTransformResult[0];\r
                                                materialHelper.rgbToHsv(rgb[0], rgb[1], rgb[2], colorTransformResult);\r
                                                materialHelper.hsvToRgb(colH, colorTransformResult[1], colorTransformResult[2], colorTransformResult);\r
-                                               rgb[0] = facm * rgb[0] + fac * colorTransformResult[0];\r
-                                               rgb[1] = facm * rgb[1] + fac * colorTransformResult[1];\r
-                                               rgb[2] = facm * rgb[2] + fac * colorTransformResult[2];\r
+                                               rgb[0] = oneMinusFactor * rgb[0] + fac * colorTransformResult[0];\r
+                                               rgb[1] = oneMinusFactor * rgb[1] + fac * colorTransformResult[1];\r
+                                               rgb[2] = oneMinusFactor * rgb[2] + fac * colorTransformResult[2];\r
                                        }\r
+                                       break;\r
                                }\r
-                               break;\r
-                       case MA_RAMP_SAT:\r
-                               if (rgb.length == 3) {\r
+                               case MTEX_BLEND_SAT: {\r
                                        float[] colorTransformResult = new float[3];\r
                                        materialHelper.rgbToHsv(rgb[0], rgb[1], rgb[2], colorTransformResult);\r
-                                       float rH = colorTransformResult[0];\r
-                                       float rS = colorTransformResult[1];\r
-                                       float rV = colorTransformResult[2];\r
-                                       if (rS != 0) {\r
+                                       float h = colorTransformResult[0];\r
+                                       float s = colorTransformResult[1];\r
+                                       float v = colorTransformResult[2];\r
+                                       if (s != 0.0f) {\r
                                                materialHelper.rgbToHsv(col[0], col[1], col[2], colorTransformResult);\r
-                                               materialHelper.hsvToRgb(rH, (facm * rS + fac * colorTransformResult[1]), rV, rgb);\r
+                                               materialHelper.hsvToRgb(h, (oneMinusFactor * s + fac * colorTransformResult[1]), v, rgb);\r
                                        }\r
+                                       break;\r
                                }\r
-                               break;\r
-                       case MA_RAMP_VAL:\r
-                               if (rgb.length == 3) {\r
+                               case MTEX_BLEND_VAL: {\r
                                        float[] rgbToHsv = new float[3];\r
                                        float[] colToHsv = new float[3];\r
                                        materialHelper.rgbToHsv(rgb[0], rgb[1], rgb[2], rgbToHsv);\r
                                        materialHelper.rgbToHsv(col[0], col[1], col[2], colToHsv);\r
-                                       materialHelper.hsvToRgb(rgbToHsv[0], rgbToHsv[1], (facm * rgbToHsv[2] + fac * colToHsv[2]), rgb);\r
+                                       materialHelper.hsvToRgb(rgbToHsv[0], rgbToHsv[1], (oneMinusFactor * rgbToHsv[2] + fac * colToHsv[2]), rgb);\r
+                                       break;\r
                                }\r
-                               break;\r
-                       case MA_RAMP_COLOR:\r
-                               if (rgb.length == 3) {\r
+                               case MTEX_BLEND_COLOR: {\r
                                        float[] rgbToHsv = new float[3];\r
                                        float[] colToHsv = new float[3];\r
                                        materialHelper.rgbToHsv(col[0], col[1], col[2], colToHsv);\r
                                        if (colToHsv[2] != 0) {\r
                                                materialHelper.rgbToHsv(rgb[0], rgb[1], rgb[2], rgbToHsv);\r
                                                materialHelper.hsvToRgb(colToHsv[0], colToHsv[1], rgbToHsv[2], rgbToHsv);\r
-                                               rgb[0] = facm * rgb[0] + fac * rgbToHsv[0];\r
-                                               rgb[1] = facm * rgb[1] + fac * rgbToHsv[1];\r
-                                               rgb[2] = facm * rgb[2] + fac * rgbToHsv[2];\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_BLEND:\r
-                               rgb[0] = facm * rgb[0] + fac * col[0];\r
-                               if (rgb.length == 3) {\r
-                                       rgb[1] = facm * rgb[1] + fac * col[1];\r
-                                       rgb[2] = facm * rgb[2] + fac * col[2];\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_ADD:\r
-                               rgb[0] += fac * col[0];\r
-                               if (rgb.length == 3) {\r
-                                       rgb[1] += fac * col[1];\r
-                                       rgb[2] += fac * col[2];\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_MULT:\r
-                               rgb[0] *= facm + fac * col[0];\r
-                               if (rgb.length == 3) {\r
-                                       rgb[1] *= facm + fac * col[1];\r
-                                       rgb[2] *= facm + fac * col[2];\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_SCREEN:\r
-                               rgb[0] = 1.0f - (facm + fac * (1.0f - col[0])) * (1.0f - rgb[0]);\r
-                               if (rgb.length == 3) {\r
-                                       rgb[1] = 1.0f - (facm + fac * (1.0f - col[1])) * (1.0f - rgb[1]);\r
-                                       rgb[2] = 1.0f - (facm + fac * (1.0f - col[2])) * (1.0f - rgb[2]);\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_OVERLAY:\r
-                               if (rgb[0] < 0.5f) {\r
-                                       rgb[0] *= facm + 2.0f * fac * col[0];\r
-                               } else {\r
-                                       rgb[0] = 1.0f - (facm + 2.0f * fac * (1.0f - col[0])) * (1.0f - rgb[0]);\r
-                               }\r
-                               if (rgb.length == 3) {\r
-                                       if (rgb[1] < 0.5f) {\r
-                                               rgb[1] *= facm + 2.0f * fac * col[1];\r
-                                       } else {\r
-                                               rgb[1] = 1.0f - (facm + 2.0f * fac * (1.0f - col[1])) * (1.0f - rgb[1]);\r
-                                       }\r
-                                       if (rgb[2] < 0.5f) {\r
-                                               rgb[2] *= facm + 2.0f * fac * col[2];\r
-                                       } else {\r
-                                               rgb[2] = 1.0f - (facm + 2.0f * fac * (1.0f - col[2])) * (1.0f - rgb[2]);\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_SUB:\r
-                               rgb[0] -= fac * col[0];\r
-                               if (rgb.length == 3) {\r
-                                       rgb[1] -= fac * col[1];\r
-                                       rgb[2] -= fac * col[2];\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_DIV:\r
-                               if (col[0] != 0.0) {\r
-                                       rgb[0] = facm * rgb[0] + fac * rgb[0] / col[0];\r
-                               }\r
-                               if (rgb.length == 3) {\r
-                                       if (col[1] != 0.0) {\r
-                                               rgb[1] = facm * rgb[1] + fac * rgb[1] / col[1];\r
-                                       }\r
-                                       if (col[2] != 0.0) {\r
-                                               rgb[2] = facm * rgb[2] + fac * rgb[2] / col[2];\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_DIFF:\r
-                               rgb[0] = facm * rgb[0] + fac * Math.abs(rgb[0] - col[0]);\r
-                               if (rgb.length == 3) {\r
-                                       rgb[1] = facm * rgb[1] + fac * Math.abs(rgb[1] - col[1]);\r
-                                       rgb[2] = facm * rgb[2] + fac * Math.abs(rgb[2] - col[2]);\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_DARK:\r
-                               tmp = fac * col[0];\r
-                               if (tmp < rgb[0]) {\r
-                                       rgb[0] = tmp;\r
-                               }\r
-                               if (rgb.length == 3) {\r
-                                       tmp = fac * col[1];\r
-                                       if (tmp < rgb[1]) {\r
-                                               rgb[1] = tmp;\r
-                                       }\r
-                                       tmp = fac * col[2];\r
-                                       if (tmp < rgb[2]) {\r
-                                               rgb[2] = tmp;\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_LIGHT:\r
-                               tmp = fac * col[0];\r
-                               if (tmp > rgb[0]) {\r
-                                       rgb[0] = tmp;\r
-                               }\r
-                               if (rgb.length == 3) {\r
-                                       tmp = fac * col[1];\r
-                                       if (tmp > rgb[1]) {\r
-                                               rgb[1] = tmp;\r
-                                       }\r
-                                       tmp = fac * col[2];\r
-                                       if (tmp > rgb[2]) {\r
-                                               rgb[2] = tmp;\r
-                                       }\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_DODGE:\r
-                               if (rgb[0] != 0.0) {\r
-                                       tmp = 1.0f - fac * col[0];\r
-                                       if (tmp <= 0.0) {\r
-                                               rgb[0] = 1.0f;\r
-                                       } else if ((tmp = rgb[0] / tmp) > 1.0) {\r
-                                               rgb[0] = 1.0f;\r
-                                       } else {\r
-                                               rgb[0] = tmp;\r
-                                       }\r
-                               }\r
-                               if (rgb.length == 3) {\r
-                                       if (rgb[1] != 0.0) {\r
-                                               tmp = 1.0f - fac * col[1];\r
-                                               if (tmp <= 0.0) {\r
-                                                       rgb[1] = 1.0f;\r
-                                               } else if ((tmp = rgb[1] / tmp) > 1.0) {\r
-                                                       rgb[1] = 1.0f;\r
-                                               } else {\r
-                                                       rgb[1] = tmp;\r
-                                               }\r
-                                       }\r
-                                       if (rgb[2] != 0.0) {\r
-                                               tmp = 1.0f - fac * col[2];\r
-                                               if (tmp <= 0.0) {\r
-                                                       rgb[2] = 1.0f;\r
-                                               } else if ((tmp = rgb[2] / tmp) > 1.0) {\r
-                                                       rgb[2] = 1.0f;\r
-                                               } else {\r
-                                                       rgb[2] = tmp;\r
-                                               }\r
-                                       }\r
-\r
-                               }\r
-                               break;\r
-                       case MA_RAMP_BURN:\r
-                               tmp = facm + fac * col[0];\r
-                               if (tmp <= 0.0) {\r
-                                       rgb[0] = 0.0f;\r
-                               } else if ((tmp = 1.0f - (1.0f - rgb[0]) / tmp) < 0.0) {\r
-                                       rgb[0] = 0.0f;\r
-                               } else if (tmp > 1.0) {\r
-                                       rgb[0] = 1.0f;\r
-                               } else {\r
-                                       rgb[0] = tmp;\r
-                               }\r
-\r
-                               if (rgb.length == 3) {\r
-                                       tmp = facm + fac * col[1];\r
-                                       if (tmp <= 0.0) {\r
-                                               rgb[1] = 0.0f;\r
-                                       } else if ((tmp = 1.0f - (1.0f - rgb[1]) / tmp) < 0.0) {\r
-                                               rgb[1] = 0.0f;\r
-                                       } else if (tmp > 1.0) {\r
-                                               rgb[1] = 1.0f;\r
-                                       } else {\r
-                                               rgb[1] = tmp;\r
-                                       }\r
-\r
-                                       tmp = facm + fac * col[2];\r
-                                       if (tmp <= 0.0) {\r
-                                               rgb[2] = 0.0f;\r
-                                       } else if ((tmp = 1.0f - (1.0f - rgb[2]) / tmp) < 0.0) {\r
-                                               rgb[2] = 0.0f;\r
-                                       } else if (tmp > 1.0) {\r
-                                               rgb[2] = 1.0f;\r
-                                       } else {\r
-                                               rgb[2] = tmp;\r
+                                               rgb[0] = oneMinusFactor * rgb[0] + fac * rgbToHsv[0];\r
+                                               rgb[1] = oneMinusFactor * rgb[1] + fac * rgbToHsv[1];\r
+                                               rgb[2] = oneMinusFactor * rgb[2] + fac * rgbToHsv[2];\r
                                        }\r
+                                       break;\r
                                }\r
-                               break;\r
-                       default:\r
-                               throw new IllegalStateException("Unknown ramp type: " + type);\r
+                               default:\r
+                                       throw new IllegalStateException("Unknown ramp type: " + type);\r
+                       }\r
                }\r
        }\r
 \r
@@ -863,7 +640,7 @@ public class TextureHelper extends AbstractBlenderHelper {
                }\r
                return image.getRGB(x, y) & 0xff;\r
        }\r
-    \r
+\r
        /**\r
         * This method transforms given vector's coordinates into ARGB color (A is always = 255).\r
         * @param x X factor of the vector\r
@@ -871,13 +648,13 @@ public class TextureHelper extends AbstractBlenderHelper {
         * @param z Z factor of the vector\r
         * @return color representation of the given vector\r
         */\r
-    protected int vectorToColor(float x, float y, float z) {\r
-        int r = Math.round(255 * (x + 1f) / 2f);\r
-        int g = Math.round(255 * (y + 1f) / 2f);\r
-        int b = Math.round(255 * (z + 1f) / 2f);\r
-        return (255 << 24) + (r << 16) + (g << 8) + b;\r
-    }\r
-       \r
+       protected int vectorToColor(float x, float y, float z) {\r
+               int r = Math.round(255 * (x + 1f) / 2f);\r
+               int g = Math.round(255 * (y + 1f) / 2f);\r
+               int b = Math.round(255 * (z + 1f) / 2f);\r
+               return (255 << 24) + (r << 16) + (g << 8) + b;\r
+       }\r
+\r
        /**\r
         * This class returns a texture read from the file or from packed blender data.\r
         * \r
@@ -933,7 +710,7 @@ public class TextureHelper extends AbstractBlenderHelper {
                AssetManager assetManager = dataRepository.getAssetManager();\r
                name = name.replaceAll("\\\\", "\\/");\r
                Texture result = null;\r
-               \r
+\r
                List<String> assetNames = new ArrayList<String>();\r
                if (name.startsWith("//")) {\r
                        String relativePath = name.substring(1);\r
@@ -946,14 +723,14 @@ public class TextureHelper extends AbstractBlenderHelper {
                        String[] paths = name.split("\\/");\r
                        StringBuilder sb = new StringBuilder(paths[paths.length-1]);//the asset name\r
                        assetNames.add(paths[paths.length-1]);\r
-                       \r
+\r
                        for(int i=paths.length-2;i>=0;--i) {\r
                                sb.insert(0, '/');\r
                                sb.insert(0, paths[i]);\r
                                assetNames.add(sb.toString());\r
                        }\r
                }\r
-               \r
+\r
                //now try to locate the asset\r
                for(String assetName : assetNames) {\r
                        try {\r
@@ -966,107 +743,8 @@ public class TextureHelper extends AbstractBlenderHelper {
                return result;\r
        }\r
 \r
-       /**\r
-        * This method closes the given stream.\r
-        * \r
-        * @param is\r
-        *        the input stream that is to be closed\r
-        */\r
-       protected void closeStream(InputStream is) {\r
-               if (is != null) {\r
-                       try {\r
-                               is.close();\r
-                       } catch (IOException e) {\r
-                               LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);\r
-                       }\r
-               }\r
-       }\r
-       \r
        @Override\r
        public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) {\r
                return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0;\r
        }\r
-\r
-       /**\r
-        * Image types that can be loaded. AWT: png, jpg, jped or bmp TGA: tga DDS: DirectX image files\r
-        * \r
-        * @author Marcin Roguski (Kaelthas)\r
-        */\r
-       public static enum ImageType {\r
-               AWT, TGA, DDS;\r
-       }\r
-\r
-       /**\r
-        * The result pixel of generated texture computations;\r
-        * \r
-        * @author Marcin Roguski (Kaelthas)\r
-        */\r
-       protected static class TexResult implements Cloneable {\r
-               public float    tin, tr, tg, tb, ta;\r
-               public int              talpha;\r
-               public float[]  nor;\r
-\r
-               @Override\r
-               public Object clone() throws CloneNotSupportedException {\r
-                       return super.clone();\r
-               }\r
-       }\r
-\r
-       /**\r
-        * A class constaining the colorband data.\r
-        * \r
-        * @author Marcin Roguski (Kaelthas)\r
-        */\r
-       protected static class ColorBand {\r
-               public int              flag, tot, cur, ipotype;\r
-               public CBData[] data    = new CBData[32];\r
-\r
-               /**\r
-                * Constructor. Loads the data from the given structure.\r
-                * \r
-                * @param cbdataStructure\r
-                *        the colorband structure\r
-                */\r
-               @SuppressWarnings("unchecked")\r
-               public ColorBand(Structure colorbandStructure) {\r
-                       this.flag = ((Number) colorbandStructure.getFieldValue("flag")).intValue();\r
-                       this.tot = ((Number) colorbandStructure.getFieldValue("tot")).intValue();\r
-                       this.cur = ((Number) colorbandStructure.getFieldValue("cur")).intValue();\r
-                       this.ipotype = ((Number) colorbandStructure.getFieldValue("ipotype")).intValue();\r
-                       DynamicArray<Structure> data = (DynamicArray<Structure>) colorbandStructure.getFieldValue("data");\r
-                       for (int i = 0; i < data.getTotalSize(); ++i) {\r
-                               this.data[i] = new CBData(data.get(i));\r
-                       }\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Class to store the single colorband unit data.\r
-        * \r
-        * @author Marcin Roguski (Kaelthas)\r
-        */\r
-       protected static class CBData implements Cloneable {\r
-               public float    r, g, b, a, pos;\r
-               public int              cur;\r
-\r
-               /**\r
-                * Constructor. Loads the data from the given structure.\r
-                * \r
-                * @param cbdataStructure\r
-                *        the structure containing the CBData object\r
-                */\r
-               public CBData(Structure cbdataStructure) {\r
-                       this.r = ((Number) cbdataStructure.getFieldValue("r")).floatValue();\r
-                       this.g = ((Number) cbdataStructure.getFieldValue("g")).floatValue();\r
-                       this.b = ((Number) cbdataStructure.getFieldValue("b")).floatValue();\r
-                       this.a = ((Number) cbdataStructure.getFieldValue("a")).floatValue();\r
-                       this.pos = ((Number) cbdataStructure.getFieldValue("pos")).floatValue();\r
-                       this.cur = ((Number) cbdataStructure.getFieldValue("cur")).intValue();\r
-               }\r
-\r
-               @Override\r
-               public Object clone() throws CloneNotSupportedException {\r
-                       return super.clone();\r
-               }\r
-       }\r
 }
\ No newline at end of file
index a5f0010..a286a8d 100644 (file)
@@ -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() {