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
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
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
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
+/*
+ * 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;
}
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;
+ }
}
/*\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
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
* @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
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
}\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
}\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
}\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
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
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
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
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
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
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
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
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
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
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
}\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
* 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
\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
+/*
+ * 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;
/**
private static final Logger LOGGER = Logger.getLogger(TextureGenerator.class.getName());
protected NoiseGenerator noiseGenerator;
-
+
public TextureGenerator(NoiseGenerator noiseGenerator) {
this.noiseGenerator = noiseGenerator;
}
* 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) {
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();
+ }
+ }
}
/*
- *
- * $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;
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;
* @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
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);
+ }
}
/*
- *
- * $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;
* @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
@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));
}
}
/*
- *
- * $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 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;
@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
+ }
}
/*
- *
- * $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;
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;
* @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
@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);
}
}
/*
- *
- * $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 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;
* 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
@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;
+ }
+ }
}
/*
- *
- * $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 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;
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();
+ }
+ }
}
/*
- *
- * $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;
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;
@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));
}
}
/*
- *
- * $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;
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;
* @author Marcin Roguski (Kaelthas)
*/
public class TextureGeneratorStucci extends TextureGenerator {
-
+ protected static final int TEX_NOISESOFT = 0;
+
/**
* Constructor stores the given noise generator.
* @param noiseGenerator
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));
}
}
/*
- *
- * $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 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;
@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);
+ }
}
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;
* @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
@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);
+ }
}
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
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
*/\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
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
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
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
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
* @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
* 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
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
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
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
}\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
* 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
}\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
* @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
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
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
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
}
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() {