Refactoring: reducing the amount of operations performed in generated textures by fetching all required functions during setup rather than generation time for each pixel.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10894 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
experimental
Kae..pl 11 years ago
parent 20fade37c5
commit fe32d59515
  1. 166
      engine/src/blender/com/jme3/scene/plugins/blender/textures/generating/NoiseGenerator.java
  2. 22
      engine/src/blender/com/jme3/scene/plugins/blender/textures/generating/TextureGeneratorClouds.java
  3. 16
      engine/src/blender/com/jme3/scene/plugins/blender/textures/generating/TextureGeneratorMarble.java
  4. 28
      engine/src/blender/com/jme3/scene/plugins/blender/textures/generating/TextureGeneratorMusgrave.java
  5. 18
      engine/src/blender/com/jme3/scene/plugins/blender/textures/generating/TextureGeneratorStucci.java
  6. 26
      engine/src/blender/com/jme3/scene/plugins/blender/textures/generating/TextureGeneratorVoronoi.java
  7. 25
      engine/src/blender/com/jme3/scene/plugins/blender/textures/generating/TextureGeneratorWood.java

@ -138,84 +138,91 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
}
});
noiseFunctions.put(Integer.valueOf(3), new NoiseFunction() {
private float[] da = new float[4];
private float[] pa = new float[12];
private final float[] da = new float[4];
private final float[] pa = new float[12];
// voronoi_F1
public float execute(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return da[0];
}
public float executeSigned(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return 2.0f * da[0] - 1.0f;
}
});
noiseFunctions.put(Integer.valueOf(4), new NoiseFunction() {
private float[] da = new float[4];
private float[] pa = new float[12];
private final float[] da = new float[4];
private final float[] pa = new float[12];
// voronoi_F2
public float execute(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return da[1];
}
public float executeSigned(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return 2.0f * da[1] - 1.0f;
}
});
noiseFunctions.put(Integer.valueOf(5), new NoiseFunction() {
private float[] da = new float[4];
private float[] pa = new float[12];
private final float[] da = new float[4];
private final float[] pa = new float[12];
// voronoi_F3
public float execute(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return da[2];
}
public float executeSigned(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return 2.0f * da[2] - 1.0f;
}
});
noiseFunctions.put(Integer.valueOf(6), new NoiseFunction() {
private float[] da = new float[4];
private float[] pa = new float[12];
private final float[] da = new float[4];
private final float[] pa = new float[12];
// voronoi_F4
public float execute(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return da[3];
}
public float executeSigned(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return 2.0f * da[3] - 1.0f;
}
});
noiseFunctions.put(Integer.valueOf(7), new NoiseFunction() {
private float[] da = new float[4];
private float[] pa = new float[12];
private final float[] da = new float[4];
private final float[] pa = new float[12];
// voronoi_F1F2
public float execute(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return da[1] - da[0];
}
public float executeSigned(float x, float y, float z) {
NoiseFunctions.voronoi(x, y, z, da, pa, 1, 0);
NoiseFunctions.voronoi(x, y, z, da, pa, 1, NATURAL_DISTANCE_FUNCTION);
return 2.0f * (da[1] - da[0]) - 1.0f;
}
});
noiseFunctions.put(Integer.valueOf(8), new NoiseFunction() {
private final NoiseFunction voronoiF1F2NoiseFunction = noiseFunctions.get(Integer.valueOf(7));
// voronoi_Cr
public float execute(float x, float y, float z) {
float t = 10 * noiseFunctions.get(Integer.valueOf(7)).execute(x, y, z);// voronoi_F1F2
float t = 10 * voronoiF1F2NoiseFunction.execute(x, y, z);
return t > 1.0f ? 1.0f : t;
}
public float executeSigned(float x, float y, float z) {
float t = 10.0f * noiseFunctions.get(Integer.valueOf(7)).execute(x, y, z);// voronoi_F1F2
float t = 10.0f * voronoiF1F2NoiseFunction.execute(x, y, z);
return t > 1.0f ? 1.0f : 2.0f * t - 1.0f;
}
});
@ -237,7 +244,7 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
}
/** Distance metrics for voronoi. e parameter only used in Minkovsky. */
protected static Map<Integer, DistanceFunction> distanceFunctions = new HashMap<Integer, NoiseGenerator.DistanceFunction>();
private static DistanceFunction NATURAL_DISTANCE_FUNCTION; // often used in noise functions, se I store it here to avoid fetching it every time
static {
distanceFunctions.put(Integer.valueOf(0), new DistanceFunction() {
// real distance
@ -289,6 +296,7 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
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);
}
});
NATURAL_DISTANCE_FUNCTION = distanceFunctions.get(Integer.valueOf(0));
}
protected static Map<Integer, MusgraveFunction> musgraveFunctions = new HashMap<Integer, NoiseGenerator.MusgraveFunction>();
@ -297,21 +305,17 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
public float execute(MusgraveData musgraveData, float x, float y, float z) {
float rmd, value = 1.0f, pwr = 1.0f, pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
if (abstractNoiseFunc == null) {
abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
}
for (int i = 0; i < (int) musgraveData.octaves; ++i) {
value *= pwr * abstractNoiseFunc.executeSigned(x, y, z) + 1.0f;
value *= pwr * musgraveData.noiseFunction.executeSigned(x, y, z) + 1.0f;
pwr *= pwHL;
x *= musgraveData.lacunarity;
y *= musgraveData.lacunarity;
z *= musgraveData.lacunarity;
}
rmd = (float) (musgraveData.octaves - FastMath.floor(musgraveData.octaves));
rmd = musgraveData.octaves - FastMath.floor(musgraveData.octaves);
if (rmd != 0.0f) {
value *= rmd * abstractNoiseFunc.executeSigned(x, y, z) * pwr + 1.0f;
value *= rmd * musgraveData.noiseFunction.executeSigned(x, y, z) * pwr + 1.0f;
}
return value;
}
@ -323,12 +327,7 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
float pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
float pwr = pwHL;
NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
if (abstractNoiseFunc == null) {
abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
}
signal = musgraveData.offset - FastMath.abs(abstractNoiseFunc.executeSigned(x, y, z));
signal = musgraveData.offset - FastMath.abs(musgraveData.noiseFunction.executeSigned(x, y, z));
signal *= signal;
result = signal;
weight = 1.0f;
@ -343,7 +342,7 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
} else if (weight < 0.0) {
weight = 0.0f;
}
signal = musgraveData.offset - FastMath.abs(abstractNoiseFunc.executeSigned(x, y, z));
signal = musgraveData.offset - FastMath.abs(musgraveData.noiseFunction.executeSigned(x, y, z));
signal *= signal;
signal *= weight;
result += signal * pwr;
@ -358,12 +357,8 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
float result, signal, weight, rmd;
float pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
float pwr = pwHL;
NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
if (abstractNoiseFunc == null) {
abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
}
result = abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset;
result = musgraveData.noiseFunction.executeSigned(x, y, z) + musgraveData.offset;
weight = musgraveData.gain * result;
x *= musgraveData.lacunarity;
y *= musgraveData.lacunarity;
@ -373,7 +368,7 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
if (weight > 1.0f) {
weight = 1.0f;
}
signal = (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr;
signal = (musgraveData.noiseFunction.executeSigned(x, y, z) + musgraveData.offset) * pwr;
pwr *= pwHL;
result += weight * signal;
weight *= musgraveData.gain * signal;
@ -382,9 +377,9 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
z *= musgraveData.lacunarity;
}
rmd = musgraveData.octaves - (float) FastMath.floor(musgraveData.octaves);
rmd = musgraveData.octaves - FastMath.floor(musgraveData.octaves);
if (rmd != 0.0f) {
result += rmd * (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr;
result += rmd * (musgraveData.noiseFunction.executeSigned(x, y, z) + musgraveData.offset) * pwr;
}
return result;
}
@ -394,22 +389,17 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
public float execute(MusgraveData musgraveData, float x, float y, float z) {
float rmd, value = 0.0f, pwr = 1.0f, pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
if (abstractNoiseFunc == null) {
abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
}
for (int i = 0; i < (int) musgraveData.octaves; ++i) {
value += abstractNoiseFunc.executeSigned(x, y, z) * pwr;
value += musgraveData.noiseFunction.executeSigned(x, y, z) * pwr;
pwr *= pwHL;
x *= musgraveData.lacunarity;
y *= musgraveData.lacunarity;
z *= musgraveData.lacunarity;
}
rmd = (float) (musgraveData.octaves - FastMath.floor(musgraveData.octaves));
rmd = musgraveData.octaves - FastMath.floor(musgraveData.octaves);
if (rmd != 0.f) {
value += rmd * abstractNoiseFunc.executeSigned(x, y, z) * pwr;
value += rmd * musgraveData.noiseFunction.executeSigned(x, y, z) * pwr;
}
return value;
}
@ -420,18 +410,14 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
float value, increment, rmd;
float pwHL = (float) Math.pow(musgraveData.lacunarity, -musgraveData.h);
float pwr = pwHL;
NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(musgraveData.noisebasis));
if (abstractNoiseFunc == null) {
abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(0));
}
value = musgraveData.offset + abstractNoiseFunc.executeSigned(x, y, z);
value = musgraveData.offset + musgraveData.noiseFunction.executeSigned(x, y, z);
x *= musgraveData.lacunarity;
y *= musgraveData.lacunarity;
z *= musgraveData.lacunarity;
for (int i = 1; i < (int) musgraveData.octaves; ++i) {
increment = (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr * value;
increment = (musgraveData.noiseFunction.executeSigned(x, y, z) + musgraveData.offset) * pwr * value;
value += increment;
pwr *= pwHL;
x *= musgraveData.lacunarity;
@ -439,9 +425,9 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
z *= musgraveData.lacunarity;
}
rmd = musgraveData.octaves - (float) FastMath.floor(musgraveData.octaves);
rmd = musgraveData.octaves - FastMath.floor(musgraveData.octaves);
if (rmd != 0.0) {
increment = (abstractNoiseFunc.executeSigned(x, y, z) + musgraveData.offset) * pwr * value;
increment = (musgraveData.noiseFunction.executeSigned(x, y, z) + musgraveData.offset) * pwr * value;
value += rmd * increment;
}
return value;
@ -450,41 +436,18 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
}
public static class NoiseFunctions {
public static float noise(float x, float y, float z, float noiseSize, int noiseDepth, int noiseBasis, boolean isHard) {
NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noiseBasis));
if (abstractNoiseFunc == null) {
abstractNoiseFunc = noiseFunctions.get(0);
noiseBasis = 0;
}
if (noiseBasis == 0) {
++x;
++y;
++z;
}
public static float noise(float x, float y, float z, float noiseSize, int noiseDepth, NoiseFunction noiseFunction, boolean isHard) {
if (noiseSize != 0.0) {
noiseSize = 1.0f / noiseSize;
x *= noiseSize;
y *= noiseSize;
z *= noiseSize;
}
float result = abstractNoiseFunc.execute(x, y, z);
float result = noiseFunction.execute(x, y, z);
return isHard ? FastMath.abs(2.0f * result - 1.0f) : result;
}
public static float turbulence(float x, float y, float z, float noiseSize, int noiseDepth, int noiseBasis, boolean isHard) {
NoiseFunction abstractNoiseFunc = noiseFunctions.get(Integer.valueOf(noiseBasis));
if (abstractNoiseFunc == null) {
abstractNoiseFunc = noiseFunctions.get(0);
noiseBasis = 0;
}
if (noiseBasis == 0) {
++x;
++y;
++z;
}
public static float turbulence(float x, float y, float z, float noiseSize, int noiseDepth, NoiseFunction noiseFunction, boolean isHard) {
if (noiseSize != 0.0) {
noiseSize = 1.0f / noiseSize;
x *= noiseSize;
@ -494,7 +457,7 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
float sum = 0, t, amp = 1, fscale = 1;
for (int i = 0; i <= noiseDepth; ++i, amp *= 0.5f, fscale *= 2f) {
t = abstractNoiseFunc.execute(fscale * x, fscale * y, fscale * z);
t = noiseFunction.execute(fscale * x, fscale * y, fscale * z);
if (isHard) {
t = FastMath.abs(2.0f * t - 1.0f);
}
@ -505,14 +468,10 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
return sum;
}
private static float[] voronoiP = new float[3];
public static void voronoi(float x, float y, float z, float[] da, float[] pa, float distanceExponent, int distanceType) {
float xd, yd, zd, d;
private static final float[] voronoiP = new float[3];
DistanceFunction distanceFunc = distanceFunctions.get(Integer.valueOf(distanceType));
if (distanceFunc == null) {
distanceFunc = distanceFunctions.get(Integer.valueOf(0));
}
public static void voronoi(float x, float y, float z, float[] da, float[] pa, float distanceExponent, DistanceFunction distanceFunction) {
float xd, yd, zd, d;
int xi = (int) FastMath.floor(x);
int yi = (int) FastMath.floor(y);
@ -525,7 +484,7 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
xd = x - (voronoiP[0] + i);
yd = y - (voronoiP[1] + j);
zd = z - (voronoiP[2] + k);
d = distanceFunc.execute(xd, yd, zd, distanceExponent);
d = distanceFunction.execute(xd, yd, zd, distanceExponent);
if (d < da[0]) {
da[3] = da[2];
da[2] = da[1];
@ -579,7 +538,7 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
// instead of adding another permutation array, just use hash table defined above
public static float newPerlin(float x, float y, float z) {
int A, AA, AB, B, BA, BB;
float floorX = (float) FastMath.floor(x), floorY = (float) FastMath.floor(y), floorZ = (float) FastMath.floor(z);
float floorX = FastMath.floor(x), floorY = FastMath.floor(y), floorZ = FastMath.floor(z);
int intX = (int) floorX & 0xFF, intY = (int) floorY & 0xFF, intZ = (int) floorZ & 0xFF;
x -= floorX;
y -= floorY;
@ -659,12 +618,13 @@ import com.jme3.scene.plugins.blender.textures.generating.TextureGeneratorMusgra
return 1.5f * NoiseMath.lerp(sz, c, d);
}
private static float[] cn = new float[8];
private static int[] b1 = new int[8];
private static int[] b2 = new int[2];
private static float[] xFactor = new float[8];
private static float[] yFactor = new float[8];
private static float[] zFactor = new float[8];
private static final float[] cn = new float[8];
private static final int[] b1 = new int[8];
private static final int[] b2 = new int[2];
private static final float[] xFactor = new float[8];
private static final float[] yFactor = new float[8];
private static final float[] zFactor = new float[8];
public static float originalBlenderNoise(float x, float y, float z) {
float n = 0.5f;

@ -35,6 +35,7 @@ import com.jme3.math.FastMath;
import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.textures.TexturePixel;
import com.jme3.scene.plugins.blender.textures.generating.NoiseGenerator.NoiseFunction;
import com.jme3.texture.Image.Format;
/**
@ -53,6 +54,7 @@ public class TextureGeneratorClouds extends TextureGenerator {
protected float noisesize;
protected int noiseDepth;
protected int noiseBasis;
protected NoiseFunction noiseFunction;
protected int noiseType;
protected boolean isHard;
protected int sType;
@ -76,14 +78,24 @@ public class TextureGeneratorClouds extends TextureGenerator {
isHard = noiseType != TEX_NOISESOFT;
sType = ((Number) tex.getFieldValue("stype")).intValue();
if (sType == TEX_COLOR) {
this.imageFormat = Format.RGBA8;
imageFormat = Format.RGBA8;
}
noiseFunction = NoiseGenerator.noiseFunctions.get(noiseBasis);
if (noiseFunction == null) {
noiseFunction = NoiseGenerator.noiseFunctions.get(0);
noiseBasis = 0;
}
}
@Override
public void getPixel(TexturePixel pixel, float x, float y, float z) {
pixel.intensity = NoiseGenerator.NoiseFunctions.turbulence(x, y, z, noisesize, noiseDepth, noiseBasis, isHard);
pixel.intensity = FastMath.clamp(pixel.intensity, 0.0f, 1.0f);
if (noiseBasis == 0) {
++x;
++y;
++z;
}
pixel.intensity = NoiseGenerator.NoiseFunctions.turbulence(x, y, z, noisesize, noiseDepth, noiseFunction, isHard);
if (colorBand != null) {
int colorbandIndex = (int) (pixel.intensity * 1000.0f);
pixel.red = colorBand[colorbandIndex][0];
@ -94,8 +106,8 @@ public class TextureGeneratorClouds extends TextureGenerator {
this.applyBrightnessAndContrast(bacd, pixel);
} else if (sType == TEX_COLOR) {
pixel.red = pixel.intensity;
pixel.green = NoiseGenerator.NoiseFunctions.turbulence(y, x, z, noisesize, noiseDepth, noiseBasis, isHard);
pixel.blue = NoiseGenerator.NoiseFunctions.turbulence(y, z, x, noisesize, noiseDepth, noiseBasis, isHard);
pixel.green = NoiseGenerator.NoiseFunctions.turbulence(y, x, z, noisesize, noiseDepth, noiseFunction, isHard);
pixel.blue = NoiseGenerator.NoiseFunctions.turbulence(y, z, x, noisesize, noiseDepth, noiseFunction, isHard);
pixel.green = FastMath.clamp(pixel.green, 0.0f, 1.0f);
pixel.blue = FastMath.clamp(pixel.blue, 0.0f, 1.0f);

@ -34,6 +34,7 @@ package com.jme3.scene.plugins.blender.textures.generating;
import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.textures.TexturePixel;
import com.jme3.scene.plugins.blender.textures.generating.NoiseGenerator.NoiseFunction;
/**
* This class generates the 'marble' texture.
@ -46,6 +47,8 @@ public class TextureGeneratorMarble extends TextureGeneratorWood {
protected static final int TEX_SHARPER = 2;
protected MarbleData marbleData;
protected int noisebasis;
protected NoiseFunction noiseFunction;
/**
* Constructor stores the given noise generator.
@ -60,6 +63,12 @@ public class TextureGeneratorMarble extends TextureGeneratorWood {
public void readData(Structure tex, BlenderContext blenderContext) {
super.readData(tex, blenderContext);
marbleData = new MarbleData(tex);
noisebasis = marbleData.noisebasis;
noiseFunction = NoiseGenerator.noiseFunctions.get(noisebasis);
if (noiseFunction == null) {
noiseFunction = NoiseGenerator.noiseFunctions.get(0);
noisebasis = 0;
}
}
@Override
@ -87,7 +96,12 @@ public class TextureGeneratorMarble extends TextureGeneratorWood {
}
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 (noisebasis == 0) {
++x;
++y;
++z;
}
float mi = n + marbleData.turbul * NoiseGenerator.NoiseFunctions.turbulence(x, y, z, marbleData.noisesize, marbleData.noisedepth, noiseFunction, marbleData.isHard);
if (marbleData.stype >= TEX_SOFT) {
mi = waveformFunctions[waveform].execute(mi);

@ -35,6 +35,7 @@ import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.textures.TexturePixel;
import com.jme3.scene.plugins.blender.textures.generating.NoiseGenerator.MusgraveFunction;
import com.jme3.scene.plugins.blender.textures.generating.NoiseGenerator.NoiseFunction;
import com.jme3.texture.Image.Format;
/**
@ -91,14 +92,15 @@ public class TextureGeneratorMusgrave extends TextureGenerator {
}
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 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 NoiseFunction noiseFunction;
public final float offset;
public final float gain;
public MusgraveData(Structure tex) {
stype = ((Number) tex.getFieldValue("stype")).intValue();
@ -106,9 +108,17 @@ public class TextureGeneratorMusgrave extends TextureGenerator {
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();
int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
NoiseFunction noiseFunction = NoiseGenerator.noiseFunctions.get(noisebasis);
if (noiseFunction == null) {
noiseFunction = NoiseGenerator.noiseFunctions.get(0);
noisebasis = 0;
}
this.noisebasis = noisebasis;
this.noiseFunction = noiseFunction;
}
}
}

@ -34,6 +34,7 @@ package com.jme3.scene.plugins.blender.textures.generating;
import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.textures.TexturePixel;
import com.jme3.scene.plugins.blender.textures.generating.NoiseGenerator.NoiseFunction;
import com.jme3.texture.Image.Format;
/**
@ -45,6 +46,7 @@ public class TextureGeneratorStucci extends TextureGenerator {
protected float noisesize;
protected int noisebasis;
protected NoiseFunction noiseFunction;
protected int noisetype;
protected float turbul;
protected boolean isHard;
@ -63,7 +65,14 @@ public class TextureGeneratorStucci extends TextureGenerator {
public void readData(Structure tex, BlenderContext blenderContext) {
super.readData(tex, blenderContext);
noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
noiseFunction = NoiseGenerator.noiseFunctions.get(noisebasis);
if (noiseFunction == null) {
noiseFunction = NoiseGenerator.noiseFunctions.get(0);
noisebasis = 0;
}
noisetype = ((Number) tex.getFieldValue("noisetype")).intValue();
turbul = ((Number) tex.getFieldValue("turbul")).floatValue();
isHard = noisetype != TEX_NOISESOFT;
@ -75,13 +84,18 @@ public class TextureGeneratorStucci extends TextureGenerator {
@Override
public void getPixel(TexturePixel pixel, float x, float y, float z) {
float noiseValue = NoiseGenerator.NoiseFunctions.noise(x, y, z, noisesize, 0, noisebasis, isHard);
if (noisebasis == 0) {
++x;
++y;
++z;
}
float noiseValue = NoiseGenerator.NoiseFunctions.noise(x, y, z, noisesize, 0, noiseFunction, isHard);
float ofs = turbul / 200.0f;
if (stype != 0) {
ofs *= noiseValue * noiseValue;
}
pixel.intensity = NoiseGenerator.NoiseFunctions.noise(x, y, z + ofs, noisesize, 0, noisebasis, isHard);
pixel.intensity = NoiseGenerator.NoiseFunctions.noise(x, y, z + ofs, noisesize, 0, noiseFunction, isHard);
if (colorBand != null) {
int colorbandIndex = (int) (pixel.intensity * 1000.0f);
pixel.red = colorBand[colorbandIndex][0];

@ -35,6 +35,7 @@ import com.jme3.math.FastMath;
import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.textures.TexturePixel;
import com.jme3.scene.plugins.blender.textures.generating.NoiseGenerator.DistanceFunction;
import com.jme3.scene.plugins.blender.textures.generating.NoiseGenerator.NoiseMath;
import com.jme3.texture.Image.Format;
@ -43,15 +44,15 @@ import com.jme3.texture.Image.Format;
* @author Marcin Roguski (Kaelthas)
*/
public class TextureGeneratorVoronoi extends TextureGenerator {
protected float noisesize;
protected float outscale;
protected float mexp;
protected int distanceType;
protected int voronoiColorType;
protected float[] da = new float[4], pa = new float[12];
protected float[] hashPoint;
protected float[] voronoiWeights;
protected float weightSum;
protected float noisesize;
protected float outscale;
protected float mexp;
protected DistanceFunction distanceFunction;
protected int voronoiColorType;
protected float[] da = new float[4], pa = new float[12];
protected float[] hashPoint;
protected float[] voronoiWeights;
protected float weightSum;
/**
* Constructor stores the given noise generator.
@ -73,7 +74,8 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
outscale = ((Number) tex.getFieldValue("ns_outscale")).floatValue();
mexp = ((Number) tex.getFieldValue("vn_mexp")).floatValue();
distanceType = ((Number) tex.getFieldValue("vn_distm")).intValue();
int distanceType = ((Number) tex.getFieldValue("vn_distm")).intValue();
distanceFunction = NoiseGenerator.distanceFunctions.get(distanceType);
voronoiColorType = ((Number) tex.getFieldValue("vn_coltype")).intValue();
hashPoint = voronoiColorType != 0 ? new float[3] : null;
weightSum = voronoiWeights[0] + voronoiWeights[1] + voronoiWeights[2] + voronoiWeights[3];
@ -81,14 +83,14 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
weightSum = outscale / weightSum;
}
if (voronoiColorType != 0 || colorBand != null) {
this.imageFormat = Format.RGBA8;
imageFormat = Format.RGBA8;
}
}
@Override
public void getPixel(TexturePixel pixel, float x, float y, float z) {
// for voronoi we need to widen the range a little
NoiseGenerator.NoiseFunctions.voronoi(x * 4, y * 4, z * 4, da, pa, mexp, distanceType);
NoiseGenerator.NoiseFunctions.voronoi(x * 4, y * 4, z * 4, da, pa, mexp, distanceFunction);
pixel.intensity = weightSum * FastMath.abs(voronoiWeights[0] * da[0] + voronoiWeights[1] * da[1] + voronoiWeights[2] * da[2] + voronoiWeights[3] * da[3]);
if (pixel.intensity > 1.0f) {
pixel.intensity = 1.0f;

@ -34,6 +34,7 @@ import com.jme3.math.FastMath;
import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.textures.TexturePixel;
import com.jme3.scene.plugins.blender.textures.generating.NoiseGenerator.NoiseFunction;
import com.jme3.texture.Image.Format;
/**
@ -139,11 +140,21 @@ public class TextureGeneratorWood extends TextureGenerator {
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);
if (woodIntData.noisebasis == 0) {
++x;
++y;
++z;
}
result = woodIntData.turbul * NoiseGenerator.NoiseFunctions.noise(x, y, z, woodIntData.noisesize, 0, woodIntData.noiseFunction, 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);
if (woodIntData.noisebasis == 0) {
++x;
++y;
++z;
}
result = woodIntData.turbul * NoiseGenerator.NoiseFunctions.noise(x, y, z, woodIntData.noisesize, 0, woodIntData.noiseFunction, woodIntData.isHard);
result = woodIntData.waveformFunction.execute((float) Math.sqrt(x * x + y * y + z * z) * 20.0f + result);
break;
default:
@ -159,6 +170,8 @@ public class TextureGeneratorWood extends TextureGenerator {
private static class WoodIntensityData {
public final WaveForm waveformFunction;
public final int noisebasis;
public NoiseFunction noiseFunction;
public final float noisesize;
public final float turbul;
public final int noiseType;
@ -171,7 +184,13 @@ public class TextureGeneratorWood extends TextureGenerator {
waveform = 0; // check to be sure noisebasis2 is initialized ahead of time
}
waveformFunction = waveformFunctions[waveform];
noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
if (noiseFunction == null) {
noiseFunction = NoiseGenerator.noiseFunctions.get(0);
noisebasis = 0;
}
this.noisebasis = noisebasis;
woodType = ((Number) tex.getFieldValue("stype")).intValue();
noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
turbul = ((Number) tex.getFieldValue("turbul")).floatValue();

Loading…
Cancel
Save