Textures importing refactoring in blender loader.
Each generated texture has now its own generator class. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7975 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
152153e94f
commit
1f90dcb8ff
@ -0,0 +1,97 @@
|
|||||||
|
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;
|
||||||
|
import com.jme3.texture.plugins.TGALoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An image loader class. It uses three loaders (AWTLoader, TGALoader and DDSLoader) in an attempt to load the image from the given
|
||||||
|
* input stream.
|
||||||
|
*
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
/*package*/ class ImageLoader extends AWTLoader {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(ImageLoader.class.getName());
|
||||||
|
|
||||||
|
protected DDSLoader ddsLoader = new DDSLoader(); // DirectX image loader
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method loads the image from the blender file itself. It tries each loader to load the image.
|
||||||
|
*
|
||||||
|
* @param inputStream
|
||||||
|
* blender input stream
|
||||||
|
* @param startPosition
|
||||||
|
* position in the stream where the image data starts
|
||||||
|
* @param flipY
|
||||||
|
* if the image should be flipped (does not work with DirectX image)
|
||||||
|
* @return loaded image or null if it could not be loaded
|
||||||
|
*/
|
||||||
|
public Image loadImage(BlenderInputStream inputStream, int startPosition, boolean flipY) {
|
||||||
|
// loading using AWT loader
|
||||||
|
inputStream.setPosition(startPosition);
|
||||||
|
Image result = this.loadImage(inputStream, ImageType.AWT, flipY);
|
||||||
|
// loading using TGA loader
|
||||||
|
if (result == null) {
|
||||||
|
inputStream.setPosition(startPosition);
|
||||||
|
result = this.loadImage(inputStream, ImageType.TGA, flipY);
|
||||||
|
}
|
||||||
|
// loading using DDS loader
|
||||||
|
if (result == null) {
|
||||||
|
inputStream.setPosition(startPosition);
|
||||||
|
result = this.loadImage(inputStream, ImageType.DDS, flipY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
LOGGER.warning("Image could not be loaded by none of available loaders!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method loads an image of a specified type from the given input stream.
|
||||||
|
*
|
||||||
|
* @param inputStream
|
||||||
|
* the input stream we read the image from
|
||||||
|
* @param imageType
|
||||||
|
* the type of the image {@link ImageType}
|
||||||
|
* @param flipY
|
||||||
|
* if the image should be flipped (does not work with DirectX image)
|
||||||
|
* @return loaded image or null if it could not be loaded
|
||||||
|
*/
|
||||||
|
public Image loadImage(InputStream inputStream, ImageType imageType, boolean flipY) {
|
||||||
|
Image result = null;
|
||||||
|
switch (imageType) {
|
||||||
|
case AWT:
|
||||||
|
try {
|
||||||
|
result = this.load(inputStream, flipY);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.info("Unable to load image using AWT loader!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DDS:
|
||||||
|
try {
|
||||||
|
result = ddsLoader.load(inputStream);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.info("Unable to load image using DDS loader!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TGA:
|
||||||
|
try {
|
||||||
|
result = TGALoader.load(inputStream, flipY);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOGGER.info("Unable to load image using TGA loader!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unknown image type: " + imageType);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -57,20 +57,20 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(NoiseGenerator.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(NoiseGenerator.class.getName());
|
||||||
|
|
||||||
/* return value */
|
// return value
|
||||||
protected static final int TEX_INT = 0;
|
protected static final int TEX_INT = 0;
|
||||||
protected static final int TEX_RGB = 1;
|
protected static final int TEX_RGB = 1;
|
||||||
protected static final int TEX_NOR = 2;
|
protected static final int TEX_NOR = 2;
|
||||||
|
|
||||||
/* noisetype */
|
// noisetype
|
||||||
protected static final int TEX_NOISESOFT = 0;
|
protected static final int TEX_NOISESOFT = 0;
|
||||||
protected static final int TEX_NOISEPERL = 1;
|
protected static final int TEX_NOISEPERL = 1;
|
||||||
|
|
||||||
/* tex->stype in texture.c - cloud types */
|
// tex->stype
|
||||||
protected static final int TEX_DEFAULT = 0;
|
protected static final int TEX_DEFAULT = 0;
|
||||||
protected static final int TEX_COLOR = 1;
|
protected static final int TEX_COLOR = 1;
|
||||||
|
|
||||||
/* flag */
|
// flag
|
||||||
protected static final int TEX_COLORBAND = 1;
|
protected static final int TEX_COLORBAND = 1;
|
||||||
protected static final int TEX_FLIPBLEND = 2;
|
protected static final int TEX_FLIPBLEND = 2;
|
||||||
protected static final int TEX_NEGALPHA = 4;
|
protected static final int TEX_NEGALPHA = 4;
|
||||||
@ -82,23 +82,23 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
protected static final int TEX_REPEAT_YMIR = 256;
|
protected static final int TEX_REPEAT_YMIR = 256;
|
||||||
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;
|
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;
|
||||||
|
|
||||||
/* tex->noisebasis2 in texture.c - wood waveforms */
|
// tex->noisebasis2
|
||||||
protected static final int TEX_SIN = 0;
|
protected static final int TEX_SIN = 0;
|
||||||
protected static final int TEX_SAW = 1;
|
protected static final int TEX_SAW = 1;
|
||||||
protected static final int TEX_TRI = 2;
|
protected static final int TEX_TRI = 2;
|
||||||
|
|
||||||
/* tex->stype in texture.c - marble types */
|
// tex->stype
|
||||||
protected static final int TEX_SOFT = 0;
|
protected static final int TEX_SOFT = 0;
|
||||||
protected static final int TEX_SHARP = 1;
|
protected static final int TEX_SHARP = 1;
|
||||||
protected static final int TEX_SHARPER = 2;
|
protected static final int TEX_SHARPER = 2;
|
||||||
|
|
||||||
/* tex->stype in texture.c - wood types */
|
// tex->stype
|
||||||
protected static final int TEX_BAND = 0;
|
protected static final int TEX_BAND = 0;
|
||||||
protected static final int TEX_RING = 1;
|
protected static final int TEX_RING = 1;
|
||||||
protected static final int TEX_BANDNOISE = 2;
|
protected static final int TEX_BANDNOISE = 2;
|
||||||
protected static final int TEX_RINGNOISE = 3;
|
protected static final int TEX_RINGNOISE = 3;
|
||||||
|
|
||||||
/* tex->stype in texture.c - blend types */
|
// tex->stype
|
||||||
protected static final int TEX_LIN = 0;
|
protected static final int TEX_LIN = 0;
|
||||||
protected static final int TEX_QUAD = 1;
|
protected static final int TEX_QUAD = 1;
|
||||||
protected static final int TEX_EASE = 2;
|
protected static final int TEX_EASE = 2;
|
||||||
@ -107,24 +107,24 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
protected static final int TEX_HALO = 5;
|
protected static final int TEX_HALO = 5;
|
||||||
protected static final int TEX_RAD = 6;
|
protected static final int TEX_RAD = 6;
|
||||||
|
|
||||||
/* tex->stype in texture.c - stucci types */
|
// tex->stype
|
||||||
protected static final int TEX_PLASTIC = 0;
|
protected static final int TEX_PLASTIC = 0;
|
||||||
protected static final int TEX_WALLIN = 1;
|
protected static final int TEX_WALLIN = 1;
|
||||||
protected static final int TEX_WALLOUT = 2;
|
protected static final int TEX_WALLOUT = 2;
|
||||||
|
|
||||||
/* musgrave stype */
|
// musgrave stype
|
||||||
protected static final int TEX_MFRACTAL = 0;
|
protected static final int TEX_MFRACTAL = 0;
|
||||||
protected static final int TEX_RIDGEDMF = 1;
|
protected static final int TEX_RIDGEDMF = 1;
|
||||||
protected static final int TEX_HYBRIDMF = 2;
|
protected static final int TEX_HYBRIDMF = 2;
|
||||||
protected static final int TEX_FBM = 3;
|
protected static final int TEX_FBM = 3;
|
||||||
protected static final int TEX_HTERRAIN = 4;
|
protected static final int TEX_HTERRAIN = 4;
|
||||||
|
|
||||||
/* keyblock->type */
|
// keyblock->type
|
||||||
protected static final int KEY_LINEAR = 0;
|
protected static final int KEY_LINEAR = 0;
|
||||||
protected static final int KEY_CARDINAL = 1;
|
protected static final int KEY_CARDINAL = 1;
|
||||||
protected static final int KEY_BSPLINE = 2;
|
protected static final int KEY_BSPLINE = 2;
|
||||||
|
|
||||||
/* CONSTANTS (read from file) */
|
// CONSTANTS (read from file)
|
||||||
protected static float[] hashpntf;
|
protected static float[] hashpntf;
|
||||||
protected static short[] hash;
|
protected static short[] hash;
|
||||||
protected static float[] hashvectf;
|
protected static float[] hashvectf;
|
||||||
@ -1288,10 +1288,7 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #define HASHVEC(x,y,z) hashvectf+3*hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255]
|
// needed for voronoi
|
||||||
|
|
||||||
/* needed for voronoi */
|
|
||||||
// #define HASHPNT(x,y,z) hashpntf+3*hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255]
|
|
||||||
protected static float[] hashPoint(int x, int y, int z) {
|
protected static float[] hashPoint(int x, int y, int z) {
|
||||||
float[] result = new float[3];
|
float[] result = new float[3];
|
||||||
result[0] = hashpntf[3 * hash[hash[hash[z & 255] + y & 255] + x & 255]];
|
result[0] = hashpntf[3 * hash[hash[hash[z & 255] + y & 255] + x & 255]];
|
||||||
@ -1300,31 +1297,23 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// #define setup(i,b0,b1,r0,r1) \
|
|
||||||
// t = vec[i] + 10000.; \
|
|
||||||
// b0 = ((int)t) & 255; \
|
|
||||||
// b1 = (b0+1) & 255; \
|
|
||||||
// r0 = t - (int)t; \
|
|
||||||
// r1 = r0 - 1.;
|
|
||||||
// vec[3]
|
|
||||||
public float noise3Perlin(float[] vec) {
|
public float noise3Perlin(float[] vec) {
|
||||||
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
|
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
|
||||||
float rx0, rx1, ry0, ry1, rz0, rz1, sx, sy, sz, a, b, c, d, t, u, v;
|
float rx0, rx1, ry0, ry1, rz0, rz1, sx, sy, sz, a, b, c, d, t, u, v;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
// setup(0, bx0,bx1, rx0,rx1);
|
|
||||||
t = vec[0] + 10000.0f;
|
t = vec[0] + 10000.0f;
|
||||||
bx0 = (int) t & 255;
|
bx0 = (int) t & 255;
|
||||||
bx1 = bx0 + 1 & 255;
|
bx1 = bx0 + 1 & 255;
|
||||||
rx0 = t - (int) t;
|
rx0 = t - (int) t;
|
||||||
rx1 = rx0 - 1.0f;
|
rx1 = rx0 - 1.0f;
|
||||||
// setup(1, by0,by1, ry0,ry1);
|
|
||||||
t = vec[0] + 10000.0f;
|
t = vec[0] + 10000.0f;
|
||||||
by0 = (int) t & 255;
|
by0 = (int) t & 255;
|
||||||
by1 = by0 + 1 & 255;
|
by1 = by0 + 1 & 255;
|
||||||
ry0 = t - (int) t;
|
ry0 = t - (int) t;
|
||||||
ry1 = ry0 - 1.0f;
|
ry1 = ry0 - 1.0f;
|
||||||
// setup(2, bz0,bz1, rz0,rz1);
|
|
||||||
t = vec[0] + 10000.0f;
|
t = vec[0] + 10000.0f;
|
||||||
bz0 = (int) t & 255;
|
bz0 = (int) t & 255;
|
||||||
bz1 = bz0 + 1 & 255;
|
bz1 = bz0 + 1 & 255;
|
||||||
@ -1339,7 +1328,7 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
b01 = p[i + by1];
|
b01 = p[i + by1];
|
||||||
b11 = p[j + by1];
|
b11 = p[j + by1];
|
||||||
|
|
||||||
/* lerp moved to improved perlin above */
|
// lerp moved to improved perlin above
|
||||||
|
|
||||||
sx = this.surve(rx0);
|
sx = this.surve(rx0);
|
||||||
sy = this.surve(ry0);
|
sy = this.surve(ry0);
|
||||||
@ -1358,7 +1347,7 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
v = this.at(rx1, ry1, rz0, q);
|
v = this.at(rx1, ry1, rz0, q);
|
||||||
b = this.lerp(sx, u, v);
|
b = this.lerp(sx, u, v);
|
||||||
|
|
||||||
c = this.lerp(sy, a, b); /* interpolate in y at lo x */
|
c = this.lerp(sy, a, b); // interpolate in y at lo x
|
||||||
|
|
||||||
q = g[b00 + bz1];
|
q = g[b00 + bz1];
|
||||||
u = this.at(rx0, ry0, rz1, q);
|
u = this.at(rx0, ry0, rz1, q);
|
||||||
@ -1372,31 +1361,32 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
v = this.at(rx1, ry1, rz1, q);
|
v = this.at(rx1, ry1, rz1, q);
|
||||||
b = this.lerp(sx, u, v);
|
b = this.lerp(sx, u, v);
|
||||||
|
|
||||||
d = this.lerp(sy, a, b); /* interpolate in y at hi x */
|
d = this.lerp(sy, a, b); // interpolate in y at hi x
|
||||||
|
|
||||||
return 1.5f * this.lerp(sz, c, d); /* interpolate in z */
|
return 1.5f * this.lerp(sz, c, d); // interpolate in z
|
||||||
}
|
}
|
||||||
|
|
||||||
public float orgBlenderNoise(float x, float y, float z) {
|
public float orgBlenderNoise(float x, float y, float z) {
|
||||||
float cn1, cn2, cn3, cn4, cn5, cn6, i;
|
|
||||||
float ox, oy, oz, jx, jy, jz;
|
|
||||||
float n = 0.5f;
|
float n = 0.5f;
|
||||||
int ix, iy, iz, b00, b01, b10, b11, b20, b21;
|
|
||||||
|
|
||||||
ox = x - (ix = (int) Math.floor(x));
|
int ix = (int) Math.floor(x);
|
||||||
oy = y - (iy = (int) Math.floor(y));
|
int iy = (int) Math.floor(y);
|
||||||
oz = z - (iz = (int) Math.floor(z));
|
int iz = (int) Math.floor(z);
|
||||||
|
|
||||||
jx = ox - 1;
|
float ox = x - ix;
|
||||||
jy = oy - 1;
|
float oy = y - iy;
|
||||||
jz = oz - 1;
|
float oz = z - iz;
|
||||||
|
|
||||||
cn1 = ox * ox;
|
float jx = ox - 1;
|
||||||
cn2 = oy * oy;
|
float jy = oy - 1;
|
||||||
cn3 = oz * oz;
|
float jz = oz - 1;
|
||||||
cn4 = jx * jx;
|
|
||||||
cn5 = jy * jy;
|
float cn1 = ox * ox;
|
||||||
cn6 = jz * jz;
|
float cn2 = oy * oy;
|
||||||
|
float cn3 = oz * oz;
|
||||||
|
float cn4 = jx * jx;
|
||||||
|
float cn5 = jy * jy;
|
||||||
|
float cn6 = jz * jz;
|
||||||
|
|
||||||
cn1 = 1.0f - 3.0f * cn1 + 2.0f * cn1 * ox;
|
cn1 = 1.0f - 3.0f * cn1 + 2.0f * cn1 * ox;
|
||||||
cn2 = 1.0f - 3.0f * cn2 + 2.0f * cn2 * oy;
|
cn2 = 1.0f - 3.0f * cn2 + 2.0f * cn2 * oy;
|
||||||
@ -1405,43 +1395,43 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
cn5 = 1.0f - 3.0f * cn5 - 2.0f * cn5 * jy;
|
cn5 = 1.0f - 3.0f * cn5 - 2.0f * cn5 * jy;
|
||||||
cn6 = 1.0f - 3.0f * cn6 - 2.0f * cn6 * jz;
|
cn6 = 1.0f - 3.0f * cn6 - 2.0f * cn6 * jz;
|
||||||
|
|
||||||
b00 = hash[hash[ix & 255] + (iy & 255)];
|
int b00 = hash[hash[ix & 255] + (iy & 255)];
|
||||||
b10 = hash[hash[ix + 1 & 255] + (iy & 255)];
|
int b10 = hash[hash[ix + 1 & 255] + (iy & 255)];
|
||||||
b01 = hash[hash[ix & 255] + (iy + 1 & 255)];
|
int b01 = hash[hash[ix & 255] + (iy + 1 & 255)];
|
||||||
b11 = hash[hash[ix + 1 & 255] + (iy + 1 & 255)];
|
int b11 = hash[hash[ix + 1 & 255] + (iy + 1 & 255)];
|
||||||
|
|
||||||
b20 = iz & 255;
|
int b20 = iz & 255;
|
||||||
b21 = iz + 1 & 255;
|
int b21 = iz + 1 & 255;
|
||||||
|
|
||||||
/* 0 */
|
// 0
|
||||||
i = cn1 * cn2 * cn3;
|
float i = cn1 * cn2 * cn3;
|
||||||
int hIndex = 3 * hash[b20 + b00];
|
int hIndex = 3 * hash[b20 + b00];
|
||||||
n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * oz);
|
n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * oz);
|
||||||
/* 1 */
|
// 1
|
||||||
i = cn1 * cn2 * cn6;
|
i = cn1 * cn2 * cn6;
|
||||||
hIndex = 3 * hash[b21 + b00];
|
hIndex = 3 * hash[b21 + b00];
|
||||||
n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * jz);
|
n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * jz);
|
||||||
/* 2 */
|
// 2
|
||||||
i = cn1 * cn5 * cn3;
|
i = cn1 * cn5 * cn3;
|
||||||
hIndex = 3 * hash[b20 + b01];
|
hIndex = 3 * hash[b20 + b01];
|
||||||
n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * oz);
|
n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * oz);
|
||||||
/* 3 */
|
// 3
|
||||||
i = cn1 * cn5 * cn6;
|
i = cn1 * cn5 * cn6;
|
||||||
hIndex = 3 * hash[b21 + b01];
|
hIndex = 3 * hash[b21 + b01];
|
||||||
n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * jz);
|
n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * jz);
|
||||||
/* 4 */
|
// 4
|
||||||
i = cn4 * cn2 * cn3;
|
i = cn4 * cn2 * cn3;
|
||||||
hIndex = 3 * hash[b20 + b10];
|
hIndex = 3 * hash[b20 + b10];
|
||||||
n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * oz);
|
n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * oz);
|
||||||
/* 5 */
|
// 5
|
||||||
i = cn4 * cn2 * cn6;
|
i = cn4 * cn2 * cn6;
|
||||||
hIndex = 3 * hash[b21 + b10];
|
hIndex = 3 * hash[b21 + b10];
|
||||||
n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * jz);
|
n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * jz);
|
||||||
/* 6 */
|
// 6
|
||||||
i = cn4 * cn5 * cn3;
|
i = cn4 * cn5 * cn3;
|
||||||
hIndex = 3 * hash[b20 + b11];
|
hIndex = 3 * hash[b20 + b11];
|
||||||
n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * oz);
|
n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * oz);
|
||||||
/* 7 */
|
// 7
|
||||||
i = cn4 * cn5 * cn6;
|
i = cn4 * cn5 * cn6;
|
||||||
hIndex = 3 * hash[b21 + b11];
|
hIndex = 3 * hash[b21 + b11];
|
||||||
n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * jz);
|
n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * jz);
|
||||||
@ -1454,7 +1444,7 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult;
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* instead of adding another permutation array, just use hash table defined above */
|
// instead of adding another permutation array, just use hash table defined above
|
||||||
public float newPerlin(float x, float y, float z) {
|
public float newPerlin(float x, float y, float z) {
|
||||||
int A, AA, AB, B, BA, BB;
|
int A, AA, AB, B, BA, BB;
|
||||||
float u = (float) Math.floor(x), v = (float) Math.floor(y), w = (float) Math.floor(z);
|
float u = (float) Math.floor(x), v = (float) Math.floor(y), w = (float) Math.floor(z);
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.jme3.scene.plugins.blender.DataRepository;
|
||||||
|
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
|
||||||
|
import com.jme3.scene.plugins.blender.file.Pointer;
|
||||||
|
import com.jme3.scene.plugins.blender.file.Structure;
|
||||||
|
import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand;
|
||||||
|
import com.jme3.texture.Texture;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a base class for texture generators.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
/* package */abstract class TextureGenerator {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(TextureGenerator.class.getName());
|
||||||
|
|
||||||
|
protected NoiseGenerator noiseGenerator;
|
||||||
|
|
||||||
|
public TextureGenerator(NoiseGenerator noiseGenerator) {
|
||||||
|
this.noiseGenerator = noiseGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method generates the texture.
|
||||||
|
* @param tex
|
||||||
|
* texture's structure
|
||||||
|
* @param width
|
||||||
|
* the width of the result texture
|
||||||
|
* @param height
|
||||||
|
* the height of the result texture
|
||||||
|
* @param dataRepository
|
||||||
|
* the data repository
|
||||||
|
* @return newly generated texture
|
||||||
|
*/
|
||||||
|
protected abstract Texture generate(Structure tex, int width, int height, DataRepository dataRepository);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method reads the colorband data from the given texture structure.
|
||||||
|
*
|
||||||
|
* @param tex
|
||||||
|
* the texture structure
|
||||||
|
* @param dataRepository
|
||||||
|
* the data repository
|
||||||
|
* @return read colorband or null if not present
|
||||||
|
*/
|
||||||
|
protected ColorBand readColorband(Structure tex, DataRepository dataRepository) {
|
||||||
|
ColorBand result = null;
|
||||||
|
int flag = ((Number) tex.getFieldValue("flag")).intValue();
|
||||||
|
if ((flag & NoiseGenerator.TEX_COLORBAND) != 0) {
|
||||||
|
Pointer pColorband = (Pointer) tex.getFieldValue("coba");
|
||||||
|
Structure colorbandStructure;
|
||||||
|
try {
|
||||||
|
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 ???
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,105 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'blend' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public final class TextureGeneratorBlend extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorBlend(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, 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, x, y, t;
|
||||||
|
float[] texvec = new float[] { 0, 0, 0 };
|
||||||
|
TexResult texres = new TexResult();
|
||||||
|
int halfW = width, halfH = height;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 1;
|
||||||
|
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
||||||
|
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||||
|
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||||
|
|
||||||
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
||||||
|
for (int i = -halfW; i < halfW; ++i) {
|
||||||
|
texvec[0] = wDelta * i;
|
||||||
|
for (int j = -halfH; j < halfH; ++j) {
|
||||||
|
texvec[1] = hDelta * j;
|
||||||
|
if ((flag & NoiseGenerator.TEX_FLIPBLEND) != 0) {
|
||||||
|
x = texvec[1];
|
||||||
|
y = texvec[0];
|
||||||
|
} else {
|
||||||
|
x = texvec[0];
|
||||||
|
y = texvec[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stype == NoiseGenerator.TEX_LIN) { /* lin */
|
||||||
|
texres.tin = (1.0f + x) / 2.0f;
|
||||||
|
} else if (stype == NoiseGenerator.TEX_QUAD) { /* quad */
|
||||||
|
texres.tin = (1.0f + x) / 2.0f;
|
||||||
|
if (texres.tin < 0.0f) {
|
||||||
|
texres.tin = 0.0f;
|
||||||
|
} 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 */
|
||||||
|
}
|
||||||
|
if (colorBand != null) {
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
noiseGenerator.brightnesAndContrastRGB(tex, texres);
|
||||||
|
data.put((byte) (texres.tr * 255.0f));
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else {
|
||||||
|
noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
|
||||||
|
data.put((byte) (texres.tin * 255.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(format, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'clouds' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class TextureGeneratorClouds extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorClouds(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
|
||||||
|
// preparing the proper data
|
||||||
|
float wDelta = 1.0f / width, hDelta = 1.0f / height;
|
||||||
|
float[] texvec = new float[] { 0, 0, 0 };
|
||||||
|
TexResult texres = new TexResult();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
int sType = ((Number) tex.getFieldValue("stype")).intValue();
|
||||||
|
int halfW = width, halfH = height;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 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 * bytesPerPixel);
|
||||||
|
for (int i = -halfW; i < halfW; ++i) {
|
||||||
|
texvec[0] = wDelta * i;// x
|
||||||
|
for (int j = -halfH; j < halfH; ++j) {
|
||||||
|
texvec[1] = hDelta * j;// y (z is always = 0)
|
||||||
|
|
||||||
|
texres.tin = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2], noiseDepth, isHard, noiseBasis);
|
||||||
|
if (colorBand != null) {
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
if (texres.nor != null) {
|
||||||
|
float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
|
||||||
|
// calculate bumpnormal
|
||||||
|
texres.nor[0] = noiseGenerator.bliGTurbulence(noisesize, texvec[0] + nabla, texvec[1], texvec[2], noiseDepth, isHard, noiseBasis);
|
||||||
|
texres.nor[1] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1] + nabla, texvec[2], noiseDepth, isHard, noiseBasis);
|
||||||
|
texres.nor[2] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2] + nabla, noiseDepth, isHard, noiseBasis);
|
||||||
|
noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
|
||||||
|
}
|
||||||
|
noiseGenerator.brightnesAndContrastRGB(tex, texres);
|
||||||
|
data.put((byte) (texres.tr * 255.0f));
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else if (sType == NoiseGenerator.TEX_COLOR) {
|
||||||
|
// in this case, int. value should really be computed from color,
|
||||||
|
// and bumpnormal from that, would be too slow, looks ok as is
|
||||||
|
texres.tr = texres.tin;
|
||||||
|
texres.tg = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[0], texvec[2], noiseDepth, isHard, noiseBasis);
|
||||||
|
texres.tb = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[2], texvec[0], noiseDepth, isHard, noiseBasis);
|
||||||
|
noiseGenerator.brightnesAndContrastRGB(tex, texres);
|
||||||
|
data.put((byte) (texres.tr * 255.0f));
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else {
|
||||||
|
noiseGenerator.brightnesAndContrast(texres, contrast, bright);
|
||||||
|
data.put((byte) (texres.tin * 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(format, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'distorted noise' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class TextureGeneratorDistnoise extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorDistnoise(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, 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();
|
||||||
|
float[] texvec = new float[] { 0, 0, 0 };
|
||||||
|
float wDelta = 1.0f / width, hDelta = 1.0f / height;
|
||||||
|
int halfW = width, halfH = height;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 1;
|
||||||
|
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
||||||
|
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||||
|
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||||
|
|
||||||
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * 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;
|
||||||
|
|
||||||
|
texres.tin = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2], distAmount, noisebasis, noisebasis2);
|
||||||
|
if (colorBand != null) {
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
if (texres.nor != null) {
|
||||||
|
float offs = nabla / noisesize; // also scaling of texvec
|
||||||
|
/* calculate bumpnormal */
|
||||||
|
texres.nor[0] = noiseGenerator.mgVLNoise(texvec[0] + offs, texvec[1], texvec[2], distAmount, noisebasis, noisebasis2);
|
||||||
|
texres.nor[1] = noiseGenerator.mgVLNoise(texvec[0], texvec[1] + offs, texvec[2], distAmount, noisebasis, noisebasis2);
|
||||||
|
texres.nor[2] = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2] + offs, distAmount, noisebasis, noisebasis2);
|
||||||
|
noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
noiseGenerator.brightnesAndContrastRGB(tex, texres);
|
||||||
|
data.put((byte) (texres.tr * 255.0f));
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else {
|
||||||
|
noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
|
||||||
|
data.put((byte) (texres.tin * 255.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(format, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'magic' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class TextureGeneratorMagic extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorMagic(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
|
||||||
|
float x, y, z, 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;
|
||||||
|
int halfW = width, halfH = height;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 1;
|
||||||
|
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
||||||
|
|
||||||
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * 4);
|
||||||
|
for (int i = -halfW; i < halfW; ++i) {
|
||||||
|
texvec[0] = wDelta * i;
|
||||||
|
for (int j = -halfH; j < halfH; ++j) {
|
||||||
|
turb = turbul;
|
||||||
|
texvec[1] = hDelta * j;
|
||||||
|
x = (float) Math.sin((texvec[0] + texvec[1]) * 5.0f);// in blender: Math.sin((texvec[0] + texvec[1] + texvec[2]) * 5.0f);
|
||||||
|
y = (float) Math.cos((-texvec[0] + texvec[1]) * 5.0f);// in blender: Math.cos((-texvec[0] + texvec[1] - texvec[2]) * 5.0f);
|
||||||
|
z = -(float) Math.cos((-texvec[0] - texvec[1]) * 5.0f);// in blender: Math.cos((-texvec[0] - texvec[1] + texvec[2]) * 5.0f);
|
||||||
|
|
||||||
|
if (colorBand != null) {
|
||||||
|
texres.tin = 0.3333f * (x + y + z);
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
} else {
|
||||||
|
if (noisedepth > 0) {
|
||||||
|
x *= turb;
|
||||||
|
y *= turb;
|
||||||
|
z *= turb;
|
||||||
|
y = -(float) Math.cos(x - y + z) * turb;
|
||||||
|
if (noisedepth > 1) {
|
||||||
|
x = (float) Math.cos(x - y - z) * turb;
|
||||||
|
if (noisedepth > 2) {
|
||||||
|
z = (float) Math.sin(-x - y - z) * turb;
|
||||||
|
if (noisedepth > 3) {
|
||||||
|
x = -(float) Math.cos(-x + y - z) * turb;
|
||||||
|
if (noisedepth > 4) {
|
||||||
|
y = -(float) Math.sin(-x + y + z) * turb;
|
||||||
|
if (noisedepth > 5) {
|
||||||
|
y = -(float) Math.cos(-x + y + z) * turb;
|
||||||
|
if (noisedepth > 6) {
|
||||||
|
x = (float) Math.cos(x + y + z) * turb;
|
||||||
|
if (noisedepth > 7) {
|
||||||
|
z = (float) Math.sin(x + y - z) * turb;
|
||||||
|
if (noisedepth > 8) {
|
||||||
|
x = -(float) Math.cos(-x - y + z) * turb;
|
||||||
|
if (noisedepth > 9) {
|
||||||
|
y = -(float) Math.sin(x - y + z) * turb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (turb != 0.0f) {
|
||||||
|
turb *= 2.0f;
|
||||||
|
x /= turb;
|
||||||
|
y /= turb;
|
||||||
|
z /= turb;
|
||||||
|
}
|
||||||
|
texres.tr = 0.5f - x;
|
||||||
|
texres.tg = 0.5f - y;
|
||||||
|
texres.tb = 0.5f - z;
|
||||||
|
}
|
||||||
|
noiseGenerator.brightnesAndContrastRGB(tex, texres);
|
||||||
|
data.put((byte) (texres.tin * 255));
|
||||||
|
data.put((byte) (texres.tb * 255));
|
||||||
|
data.put((byte) (texres.tg * 255));
|
||||||
|
data.put((byte) (texres.tr * 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(Format.ABGR8, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'marble' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class TextureGeneratorMarble extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorMarble(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, 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;
|
||||||
|
float[] texvec = new float[] { 0, 0, 0 };
|
||||||
|
TexResult texres = new TexResult();
|
||||||
|
int halfW = width, halfH = height;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 1;
|
||||||
|
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
||||||
|
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||||
|
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||||
|
|
||||||
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
||||||
|
for (int i = -halfW; i < halfW; ++i) {
|
||||||
|
texvec[0] = wDelta * i;
|
||||||
|
for (int j = -halfH; j < halfH; ++j) {
|
||||||
|
texvec[1] = hDelta * j;
|
||||||
|
texres.tin = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
|
||||||
|
if (colorBand != null) {
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
if (texres.nor != null) {// calculate bumpnormal
|
||||||
|
texres.nor[0] = noiseGenerator.marbleInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository);
|
||||||
|
texres.nor[1] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository);
|
||||||
|
texres.nor[2] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository);
|
||||||
|
noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
|
||||||
|
}
|
||||||
|
|
||||||
|
noiseGenerator.brightnesAndContrastRGB(tex, texres);
|
||||||
|
data.put((byte) (texres.tr * 255.0f));
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else {
|
||||||
|
noiseGenerator.brightnesAndContrast(texres, contrast, bright);
|
||||||
|
data.put((byte) (texres.tin * 255.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(format, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'musgrave' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class TextureGeneratorMusgrave extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorMusgrave(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
|
||||||
|
int stype = ((Number) tex.getFieldValue("stype")).intValue();
|
||||||
|
float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
|
||||||
|
TexResult texres = new TexResult();
|
||||||
|
float[] texvec = new float[] { 0, 0, 0 };
|
||||||
|
float wDelta = 1.0f / width, hDelta = 1.0f / height;
|
||||||
|
int halfW = width, halfH = height;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 1;
|
||||||
|
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
||||||
|
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||||
|
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||||
|
|
||||||
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * 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;
|
||||||
|
switch (stype) {
|
||||||
|
case NoiseGenerator.TEX_MFRACTAL:
|
||||||
|
case NoiseGenerator.TEX_FBM:
|
||||||
|
noiseGenerator.mgMFractalOrfBmTex(tex, texvec, colorBand, texres, dataRepository);
|
||||||
|
break;
|
||||||
|
case NoiseGenerator.TEX_RIDGEDMF:
|
||||||
|
case NoiseGenerator.TEX_HYBRIDMF:
|
||||||
|
noiseGenerator.mgRidgedOrHybridMFTex(tex, texvec, colorBand, texres, dataRepository);
|
||||||
|
break;
|
||||||
|
case NoiseGenerator.TEX_HTERRAIN:
|
||||||
|
noiseGenerator.mgHTerrainTex(tex, texvec, colorBand, texres, dataRepository);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unknown type of musgrave texture: " + stype);
|
||||||
|
}
|
||||||
|
if (colorBand != null) {
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
data.put((byte) (texres.tr * 255.0f));
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else {
|
||||||
|
data.put((byte) (texres.tin * 255.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(format, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'noise' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class TextureGeneratorNoise extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorNoise(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
|
||||||
|
float div = 3.0f;
|
||||||
|
int val, ran, 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;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 1;
|
||||||
|
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
||||||
|
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||||
|
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||||
|
|
||||||
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
||||||
|
for (int i = -halfW; i < halfW; ++i) {
|
||||||
|
for (int j = -halfH; j < halfH; ++j) {
|
||||||
|
ran = FastMath.rand.nextInt();// BLI_rand();
|
||||||
|
val = ran & 3;
|
||||||
|
|
||||||
|
loop = noisedepth;
|
||||||
|
while (loop-- != 0) {
|
||||||
|
ran = ran >> 2;
|
||||||
|
val *= ran & 3;
|
||||||
|
div *= 3.0f;
|
||||||
|
}
|
||||||
|
texres.tin = val;// / div;
|
||||||
|
if (colorBand != null) {
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
noiseGenerator.brightnesAndContrastRGB(tex, texres);
|
||||||
|
data.put((byte) (texres.tr * 255.0f));
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else {
|
||||||
|
noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
|
||||||
|
data.put((byte) (texres.tin * 255.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(format, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,95 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'stucci' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class TextureGeneratorStucci extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorStucci(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) {
|
||||||
|
float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
|
||||||
|
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;
|
||||||
|
int stype = ((Number) tex.getFieldValue("stype")).intValue();
|
||||||
|
|
||||||
|
float[] texvec = new float[] { 0, 0, 0 };
|
||||||
|
TexResult texres = new TexResult();
|
||||||
|
float wDelta = 1.0f / width, hDelta = 1.0f / height, b2, ofs;
|
||||||
|
int halfW = width, halfH = height;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 1;
|
||||||
|
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
||||||
|
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||||
|
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||||
|
|
||||||
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
||||||
|
for (int i = -halfW; i < halfW; ++i) {
|
||||||
|
texvec[0] = wDelta * i;// x
|
||||||
|
for (int j = -halfH; j < halfH; ++j) {
|
||||||
|
texvec[1] = hDelta * j;// y (z is always = 0)
|
||||||
|
b2 = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2], isHard, noisebasis);
|
||||||
|
|
||||||
|
ofs = turbul / 200.0f;
|
||||||
|
|
||||||
|
if (stype != 0) {
|
||||||
|
ofs *= b2 * b2;
|
||||||
|
}
|
||||||
|
|
||||||
|
texres.tin = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2] + ofs, isHard, noisebasis);// ==nor[2]
|
||||||
|
if (colorBand != null) {
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
if (texres.nor != null) {
|
||||||
|
texres.nor[0] = noiseGenerator.bliGNoise(noisesize, texvec[0] + ofs, texvec[1], texvec[2], isHard, noisebasis);
|
||||||
|
texres.nor[1] = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1] + ofs, texvec[2], isHard, noisebasis);
|
||||||
|
texres.nor[2] = texres.tin;
|
||||||
|
noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
|
||||||
|
|
||||||
|
if (stype == NoiseGenerator.TEX_WALLOUT) {
|
||||||
|
texres.nor[0] = -texres.nor[0];
|
||||||
|
texres.nor[1] = -texres.nor[1];
|
||||||
|
texres.nor[2] = -texres.nor[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stype == NoiseGenerator.TEX_WALLOUT) {
|
||||||
|
texres.tin = 1.0f - texres.tin;
|
||||||
|
}
|
||||||
|
if (texres.tin < 0.0f) {
|
||||||
|
texres.tin = 0.0f;
|
||||||
|
}
|
||||||
|
if (colorBand != null) {
|
||||||
|
data.put((byte) (texres.tr * 255.0f));
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else {
|
||||||
|
data.put((byte) (texres.tin * 255.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(format, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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.Texture;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.texture.Image.Format;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'voronoi' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class TextureGeneratorVoronoi extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorVoronoi(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, 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 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();
|
||||||
|
|
||||||
|
TexResult texres = new TexResult();
|
||||||
|
float[] texvec = new float[] { 0, 0, 0 };
|
||||||
|
float wDelta = 1.0f / width, hDelta = 1.0f / height;
|
||||||
|
int halfW = width, halfH = height;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * 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;
|
||||||
|
|
||||||
|
noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2], da, pa, vn_mexp, vn_distm);
|
||||||
|
texres.tin = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
|
||||||
|
if (vn_coltype != 0) {
|
||||||
|
noiseGenerator.cellNoiseV(pa[0], pa[1], pa[2], ca);
|
||||||
|
texres.tr = aw1 * ca[0];
|
||||||
|
texres.tg = aw1 * ca[1];
|
||||||
|
texres.tb = aw1 * ca[2];
|
||||||
|
noiseGenerator.cellNoiseV(pa[3], pa[4], pa[5], ca);
|
||||||
|
texres.tr += aw2 * ca[0];
|
||||||
|
texres.tg += aw2 * ca[1];
|
||||||
|
texres.tb += aw2 * ca[2];
|
||||||
|
noiseGenerator.cellNoiseV(pa[6], pa[7], pa[8], ca);
|
||||||
|
texres.tr += aw3 * ca[0];
|
||||||
|
texres.tg += aw3 * ca[1];
|
||||||
|
texres.tb += aw3 * ca[2];
|
||||||
|
noiseGenerator.cellNoiseV(pa[9], pa[10], pa[11], ca);
|
||||||
|
texres.tr += aw4 * ca[0];
|
||||||
|
texres.tg += aw4 * ca[1];
|
||||||
|
texres.tb += aw4 * ca[2];
|
||||||
|
if (vn_coltype >= 2) {
|
||||||
|
float t1 = (da[1] - da[0]) * 10.0f;
|
||||||
|
if (t1 > 1) {
|
||||||
|
t1 = 1.0f;
|
||||||
|
}
|
||||||
|
if (vn_coltype == 3) {
|
||||||
|
t1 *= texres.tin;
|
||||||
|
} else {
|
||||||
|
t1 *= sc;
|
||||||
|
}
|
||||||
|
texres.tr *= t1;
|
||||||
|
texres.tg *= t1;
|
||||||
|
texres.tb *= t1;
|
||||||
|
} else {
|
||||||
|
texres.tr *= sc;
|
||||||
|
texres.tg *= sc;
|
||||||
|
texres.tb *= sc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (colorBand != null) {
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
if (texres.nor != null) {
|
||||||
|
float offs = nabla / noisesize; // also scaling of texvec
|
||||||
|
// calculate bumpnormal
|
||||||
|
noiseGenerator.voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, vn_mexp, vn_distm);
|
||||||
|
texres.nor[0] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
|
||||||
|
noiseGenerator.voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, vn_mexp, vn_distm);
|
||||||
|
texres.nor[1] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
|
||||||
|
noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, vn_mexp, vn_distm);
|
||||||
|
texres.nor[2] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]);
|
||||||
|
noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vn_coltype != 0 || colorBand != null) {
|
||||||
|
noiseGenerator.brightnesAndContrastRGB(tex, texres);
|
||||||
|
data.put((byte) (texres.tr * 255.0f));// tin or tr??
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else {
|
||||||
|
noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
|
||||||
|
data.put((byte) (texres.tin * 255.0f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(format, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.textures;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import com.jme3.texture.Texture2D;
|
||||||
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class generates the 'wood' texture.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class TextureGeneratorWood extends TextureGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor stores the given noise generator.
|
||||||
|
* @param noiseGenerator the noise generator
|
||||||
|
*/
|
||||||
|
public TextureGeneratorWood(NoiseGenerator noiseGenerator) {
|
||||||
|
super(noiseGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Texture generate(Structure tex, int width, int height, 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;
|
||||||
|
float[] texvec = new float[] { 0, 0, 0 };
|
||||||
|
TexResult texres = new TexResult();
|
||||||
|
int halfW = width;
|
||||||
|
int halfH = height;
|
||||||
|
width <<= 1;
|
||||||
|
height <<= 1;
|
||||||
|
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
||||||
|
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||||
|
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||||
|
|
||||||
|
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
||||||
|
for (int i = -halfW; i < halfW; ++i) {
|
||||||
|
texvec[0] = wDelta * i;
|
||||||
|
for (int j = -halfH; j < halfH; ++j) {
|
||||||
|
texvec[1] = hDelta * j;
|
||||||
|
texres.tin = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
|
||||||
|
if (colorBand != null) {
|
||||||
|
noiseGenerator.doColorband(colorBand, texres, dataRepository);
|
||||||
|
if (texres.nor != null) {// calculate bumpnormal
|
||||||
|
texres.nor[0] = noiseGenerator.woodInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository);
|
||||||
|
texres.nor[1] = noiseGenerator.woodInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository);
|
||||||
|
texres.nor[2] = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository);
|
||||||
|
noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository);
|
||||||
|
}
|
||||||
|
noiseGenerator.brightnesAndContrastRGB(tex, texres);
|
||||||
|
data.put((byte) (texres.tr * 255.0f));
|
||||||
|
data.put((byte) (texres.tg * 255.0f));
|
||||||
|
data.put((byte) (texres.tb * 255.0f));
|
||||||
|
} else {
|
||||||
|
noiseGenerator.brightnesAndContrast(texres, contrast, bright);
|
||||||
|
data.put((byte) (texres.tin * 255));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Texture2D(new Image(format, width, height, data));
|
||||||
|
}
|
||||||
|
}
|
@ -41,6 +41,8 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@ -56,7 +58,6 @@ import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
|
|||||||
import com.jme3.scene.plugins.blender.DataRepository;
|
import com.jme3.scene.plugins.blender.DataRepository;
|
||||||
import com.jme3.scene.plugins.blender.DataRepository.LoadedFeatureDataType;
|
import com.jme3.scene.plugins.blender.DataRepository.LoadedFeatureDataType;
|
||||||
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
|
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
|
||||||
import com.jme3.scene.plugins.blender.file.BlenderInputStream;
|
|
||||||
import com.jme3.scene.plugins.blender.file.DynamicArray;
|
import com.jme3.scene.plugins.blender.file.DynamicArray;
|
||||||
import com.jme3.scene.plugins.blender.file.FileBlockHeader;
|
import com.jme3.scene.plugins.blender.file.FileBlockHeader;
|
||||||
import com.jme3.scene.plugins.blender.file.Pointer;
|
import com.jme3.scene.plugins.blender.file.Pointer;
|
||||||
@ -67,9 +68,6 @@ import com.jme3.texture.Image.Format;
|
|||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.Texture.WrapMode;
|
import com.jme3.texture.Texture.WrapMode;
|
||||||
import com.jme3.texture.Texture2D;
|
import com.jme3.texture.Texture2D;
|
||||||
import com.jme3.texture.plugins.AWTLoader;
|
|
||||||
import com.jme3.texture.plugins.DDSLoader;
|
|
||||||
import com.jme3.texture.plugins.TGALoader;
|
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -151,18 +149,29 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
public static final int MA_RAMP_VAL = 14;
|
public static final int MA_RAMP_VAL = 14;
|
||||||
public static final int MA_RAMP_COLOR = 15;
|
public static final int MA_RAMP_COLOR = 15;
|
||||||
|
|
||||||
protected NoiseGenerator noiseHelper;
|
protected NoiseGenerator noiseGenerator;
|
||||||
|
private Map<Integer, TextureGenerator> textureGenerators = new HashMap<Integer, TextureGenerator>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor parses the given blender version and stores the result. Some functionalities may differ in different blender
|
* This constructor parses the given blender version and stores the result.
|
||||||
* versions.
|
* It creates noise generator and texture generators.
|
||||||
*
|
*
|
||||||
* @param blenderVersion
|
* @param blenderVersion
|
||||||
* the version read from the blend file
|
* the version read from the blend file
|
||||||
*/
|
*/
|
||||||
public TextureHelper(String blenderVersion) {
|
public TextureHelper(String blenderVersion) {
|
||||||
super(blenderVersion);
|
super(blenderVersion);
|
||||||
noiseHelper = new NoiseGenerator(blenderVersion);
|
noiseGenerator = new NoiseGenerator(blenderVersion);
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_BLEND), new TextureGeneratorBlend(noiseGenerator));
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_CLOUDS), new TextureGeneratorClouds(noiseGenerator));
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_DISTNOISE), new TextureGeneratorDistnoise(noiseGenerator));
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_MAGIC), new TextureGeneratorMagic(noiseGenerator));
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_MARBLE), new TextureGeneratorMarble(noiseGenerator));
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_MUSGRAVE), new TextureGeneratorMusgrave(noiseGenerator));
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_NOISE), new TextureGeneratorNoise(noiseGenerator));
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_STUCCI), new TextureGeneratorStucci(noiseGenerator));
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_VORONOI), new TextureGeneratorVoronoi(noiseGenerator));
|
||||||
|
textureGenerators.put(Integer.valueOf(TEX_WOOD), new TextureGeneratorWood(noiseGenerator));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -195,34 +204,17 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TEX_CLOUDS:
|
case TEX_CLOUDS:
|
||||||
result = this.clouds(tex, width, height, dataRepository);
|
|
||||||
break;
|
|
||||||
case TEX_WOOD:
|
case TEX_WOOD:
|
||||||
result = this.wood(tex, width, height, dataRepository);
|
|
||||||
break;
|
|
||||||
case TEX_MARBLE:
|
case TEX_MARBLE:
|
||||||
result = this.marble(tex, width, height, dataRepository);
|
|
||||||
break;
|
|
||||||
case TEX_MAGIC:
|
case TEX_MAGIC:
|
||||||
result = this.magic(tex, width, height, dataRepository);
|
|
||||||
break;
|
|
||||||
case TEX_BLEND:
|
case TEX_BLEND:
|
||||||
result = this.blend(tex, width, height, dataRepository);
|
|
||||||
break;
|
|
||||||
case TEX_STUCCI:
|
case TEX_STUCCI:
|
||||||
result = this.stucci(tex, width, height, dataRepository);
|
|
||||||
break;
|
|
||||||
case TEX_NOISE:
|
case TEX_NOISE:
|
||||||
result = this.texnoise(tex, width, height, dataRepository);
|
|
||||||
break;
|
|
||||||
case TEX_MUSGRAVE:
|
case TEX_MUSGRAVE:
|
||||||
result = this.musgrave(tex, width, height, dataRepository);
|
|
||||||
break;
|
|
||||||
case TEX_VORONOI:
|
case TEX_VORONOI:
|
||||||
result = this.voronoi(tex, width, height, dataRepository);
|
|
||||||
break;
|
|
||||||
case TEX_DISTNOISE:
|
case TEX_DISTNOISE:
|
||||||
result = this.distnoise(tex, width, height, dataRepository);
|
TextureGenerator textureGenerator = textureGenerators.get(Integer.valueOf(type));
|
||||||
|
result = textureGenerator.generate(tex, width, height, dataRepository);
|
||||||
break;
|
break;
|
||||||
case TEX_NONE:// No texture, do nothing
|
case TEX_NONE:// No texture, do nothing
|
||||||
break;
|
break;
|
||||||
@ -249,778 +241,6 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the clouds texture. The result is one pixel.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of texture (in pixels)
|
|
||||||
* @param height
|
|
||||||
* the height of texture (in pixels)
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return generated texture
|
|
||||||
*/
|
|
||||||
protected Texture clouds(Structure tex, int width, int height, DataRepository dataRepository) {
|
|
||||||
// preparing the proper data
|
|
||||||
float wDelta = 1.0f / width, hDelta = 1.0f / height;
|
|
||||||
float[] texvec = new float[] { 0, 0, 0 };
|
|
||||||
TexResult texres = new TexResult();
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
int sType = ((Number) tex.getFieldValue("stype")).intValue();
|
|
||||||
int halfW = width, halfH = height;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 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 * bytesPerPixel);
|
|
||||||
for (int i = -halfW; i < halfW; ++i) {
|
|
||||||
texvec[0] = wDelta * i;// x
|
|
||||||
for (int j = -halfH; j < halfH; ++j) {
|
|
||||||
texvec[1] = hDelta * j;// y (z is always = 0)
|
|
||||||
|
|
||||||
texres.tin = noiseHelper.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2], noiseDepth, isHard, noiseBasis);
|
|
||||||
if (colorBand != null) {
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
if (texres.nor != null) {
|
|
||||||
float nabla = ((Number) tex.getFieldValue("nabla")).floatValue();
|
|
||||||
// calculate bumpnormal
|
|
||||||
texres.nor[0] = noiseHelper.bliGTurbulence(noisesize, texvec[0] + nabla, texvec[1], texvec[2], noiseDepth, isHard, noiseBasis);
|
|
||||||
texres.nor[1] = noiseHelper.bliGTurbulence(noisesize, texvec[0], texvec[1] + nabla, texvec[2], noiseDepth, isHard, noiseBasis);
|
|
||||||
texres.nor[2] = noiseHelper.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2] + nabla, noiseDepth, isHard, noiseBasis);
|
|
||||||
noiseHelper.texNormalDerivate(colorBand, texres, dataRepository);
|
|
||||||
}
|
|
||||||
noiseHelper.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 = noiseHelper.bliGTurbulence(noisesize, texvec[1], texvec[0], texvec[2], noiseDepth, isHard, noiseBasis);
|
|
||||||
texres.tb = noiseHelper.bliGTurbulence(noisesize, texvec[1], texvec[2], texvec[0], noiseDepth, isHard, noiseBasis);
|
|
||||||
noiseHelper.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 {
|
|
||||||
noiseHelper.brightnesAndContrast(texres, contrast, bright);
|
|
||||||
data.put((byte) (texres.tin * 255));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(format, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the wood texture.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of the texture
|
|
||||||
* @param height
|
|
||||||
* the height of the texture
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return the generated texture
|
|
||||||
*/
|
|
||||||
protected Texture wood(Structure tex, int width, int height, 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;
|
|
||||||
float[] texvec = new float[] { 0, 0, 0 };
|
|
||||||
TexResult texres = new TexResult();
|
|
||||||
int halfW = width;
|
|
||||||
int halfH = height;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 1;
|
|
||||||
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
|
||||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
|
||||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
|
||||||
|
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
|
||||||
for (int i = -halfW; i < halfW; ++i) {
|
|
||||||
texvec[0] = wDelta * i;
|
|
||||||
for (int j = -halfH; j < halfH; ++j) {
|
|
||||||
texvec[1] = hDelta * j;
|
|
||||||
texres.tin = noiseHelper.woodInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
|
|
||||||
if (colorBand != null) {
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
if (texres.nor != null) {// calculate bumpnormal
|
|
||||||
texres.nor[0] = noiseHelper.woodInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository);
|
|
||||||
texres.nor[1] = noiseHelper.woodInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository);
|
|
||||||
texres.nor[2] = noiseHelper.woodInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository);
|
|
||||||
noiseHelper.texNormalDerivate(colorBand, texres, dataRepository);
|
|
||||||
}
|
|
||||||
noiseHelper.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 {
|
|
||||||
noiseHelper.brightnesAndContrast(texres, contrast, bright);
|
|
||||||
data.put((byte) (texres.tin * 255));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(format, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the marble texture.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of the texture
|
|
||||||
* @param height
|
|
||||||
* the height of the texture
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return the generated texture
|
|
||||||
*/
|
|
||||||
protected Texture marble(Structure tex, int width, int height, 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;
|
|
||||||
float[] texvec = new float[] { 0, 0, 0 };
|
|
||||||
TexResult texres = new TexResult();
|
|
||||||
int halfW = width, halfH = height;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 1;
|
|
||||||
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
|
||||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
|
||||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
|
||||||
|
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
|
||||||
for (int i = -halfW; i < halfW; ++i) {
|
|
||||||
texvec[0] = wDelta * i;
|
|
||||||
for (int j = -halfH; j < halfH; ++j) {
|
|
||||||
texvec[1] = hDelta * j;
|
|
||||||
texres.tin = noiseHelper.marbleInt(tex, texvec[0], texvec[1], texvec[2], dataRepository);
|
|
||||||
if (colorBand != null) {
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
if (texres.nor != null) {// calculate bumpnormal
|
|
||||||
texres.nor[0] = noiseHelper.marbleInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository);
|
|
||||||
texres.nor[1] = noiseHelper.marbleInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository);
|
|
||||||
texres.nor[2] = noiseHelper.marbleInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository);
|
|
||||||
noiseHelper.texNormalDerivate(colorBand, texres, dataRepository);
|
|
||||||
}
|
|
||||||
|
|
||||||
noiseHelper.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 {
|
|
||||||
noiseHelper.brightnesAndContrast(texres, contrast, bright);
|
|
||||||
data.put((byte) (texres.tin * 255.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(format, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the magic texture.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of the texture
|
|
||||||
* @param height
|
|
||||||
* the height of the texture
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return the generated texture
|
|
||||||
*/
|
|
||||||
protected Texture magic(Structure tex, int width, int height, DataRepository dataRepository) {
|
|
||||||
float x, y, z, 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;
|
|
||||||
int halfW = width, halfH = height;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 1;
|
|
||||||
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
|
||||||
|
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(width * height * 4);
|
|
||||||
for (int i = -halfW; i < halfW; ++i) {
|
|
||||||
texvec[0] = wDelta * i;
|
|
||||||
for (int j = -halfH; j < halfH; ++j) {
|
|
||||||
turb = turbul;
|
|
||||||
texvec[1] = hDelta * j;
|
|
||||||
x = (float) Math.sin((texvec[0] + texvec[1]) * 5.0f);// in blender: Math.sin((texvec[0] + texvec[1] + texvec[2]) * 5.0f);
|
|
||||||
y = (float) Math.cos((-texvec[0] + texvec[1]) * 5.0f);// in blender: Math.cos((-texvec[0] + texvec[1] - texvec[2]) * 5.0f);
|
|
||||||
z = -(float) Math.cos((-texvec[0] - texvec[1]) * 5.0f);// in blender: Math.cos((-texvec[0] - texvec[1] + texvec[2]) * 5.0f);
|
|
||||||
|
|
||||||
if (colorBand != null) {
|
|
||||||
texres.tin = 0.3333f * (x + y + z);
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
} else {
|
|
||||||
if (noisedepth > 0) {
|
|
||||||
x *= turb;
|
|
||||||
y *= turb;
|
|
||||||
z *= turb;
|
|
||||||
y = -(float) Math.cos(x - y + z) * turb;
|
|
||||||
if (noisedepth > 1) {
|
|
||||||
x = (float) Math.cos(x - y - z) * turb;
|
|
||||||
if (noisedepth > 2) {
|
|
||||||
z = (float) Math.sin(-x - y - z) * turb;
|
|
||||||
if (noisedepth > 3) {
|
|
||||||
x = -(float) Math.cos(-x + y - z) * turb;
|
|
||||||
if (noisedepth > 4) {
|
|
||||||
y = -(float) Math.sin(-x + y + z) * turb;
|
|
||||||
if (noisedepth > 5) {
|
|
||||||
y = -(float) Math.cos(-x + y + z) * turb;
|
|
||||||
if (noisedepth > 6) {
|
|
||||||
x = (float) Math.cos(x + y + z) * turb;
|
|
||||||
if (noisedepth > 7) {
|
|
||||||
z = (float) Math.sin(x + y - z) * turb;
|
|
||||||
if (noisedepth > 8) {
|
|
||||||
x = -(float) Math.cos(-x - y + z) * turb;
|
|
||||||
if (noisedepth > 9) {
|
|
||||||
y = -(float) Math.sin(x - y + z) * turb;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (turb != 0.0f) {
|
|
||||||
turb *= 2.0f;
|
|
||||||
x /= turb;
|
|
||||||
y /= turb;
|
|
||||||
z /= turb;
|
|
||||||
}
|
|
||||||
texres.tr = 0.5f - x;
|
|
||||||
texres.tg = 0.5f - y;
|
|
||||||
texres.tb = 0.5f - z;
|
|
||||||
}
|
|
||||||
noiseHelper.brightnesAndContrastRGB(tex, texres);
|
|
||||||
data.put((byte) (texres.tin * 255));
|
|
||||||
data.put((byte) (texres.tb * 255));
|
|
||||||
data.put((byte) (texres.tg * 255));
|
|
||||||
data.put((byte) (texres.tr * 255));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(Format.ABGR8, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the blend texture.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of the texture
|
|
||||||
* @param height
|
|
||||||
* the height of the texture
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return the generated texture
|
|
||||||
*/
|
|
||||||
protected Texture blend(Structure tex, int width, int height, 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, x, y, t;
|
|
||||||
float[] texvec = new float[] { 0, 0, 0 };
|
|
||||||
TexResult texres = new TexResult();
|
|
||||||
int halfW = width, halfH = height;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 1;
|
|
||||||
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
|
||||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
|
||||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
|
||||||
|
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
|
||||||
for (int i = -halfW; i < halfW; ++i) {
|
|
||||||
texvec[0] = wDelta * i;
|
|
||||||
for (int j = -halfH; j < halfH; ++j) {
|
|
||||||
texvec[1] = hDelta * j;
|
|
||||||
if ((flag & NoiseGenerator.TEX_FLIPBLEND) != 0) {
|
|
||||||
x = texvec[1];
|
|
||||||
y = texvec[0];
|
|
||||||
} else {
|
|
||||||
x = texvec[0];
|
|
||||||
y = texvec[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stype == NoiseGenerator.TEX_LIN) { /* lin */
|
|
||||||
texres.tin = (1.0f + x) / 2.0f;
|
|
||||||
} else if (stype == NoiseGenerator.TEX_QUAD) { /* quad */
|
|
||||||
texres.tin = (1.0f + x) / 2.0f;
|
|
||||||
if (texres.tin < 0.0f) {
|
|
||||||
texres.tin = 0.0f;
|
|
||||||
} 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 */
|
|
||||||
}
|
|
||||||
if (colorBand != null) {
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
noiseHelper.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 {
|
|
||||||
noiseHelper.brightnesAndContrast(texres, contrast, brightness);
|
|
||||||
data.put((byte) (texres.tin * 255.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(format, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the stucci texture.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of the texture
|
|
||||||
* @param height
|
|
||||||
* the height of the texture
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return the generated texture
|
|
||||||
*/
|
|
||||||
protected Texture stucci(Structure tex, int width, int height, DataRepository dataRepository) {
|
|
||||||
float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
|
|
||||||
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;
|
|
||||||
int stype = ((Number) tex.getFieldValue("stype")).intValue();
|
|
||||||
|
|
||||||
float[] texvec = new float[] { 0, 0, 0 };
|
|
||||||
TexResult texres = new TexResult();
|
|
||||||
float wDelta = 1.0f / width, hDelta = 1.0f / height, b2, ofs;
|
|
||||||
int halfW = width, halfH = height;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 1;
|
|
||||||
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
|
||||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
|
||||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
|
||||||
|
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
|
||||||
for (int i = -halfW; i < halfW; ++i) {
|
|
||||||
texvec[0] = wDelta * i;// x
|
|
||||||
for (int j = -halfH; j < halfH; ++j) {
|
|
||||||
texvec[1] = hDelta * j;// y (z is always = 0)
|
|
||||||
b2 = noiseHelper.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2], isHard, noisebasis);
|
|
||||||
|
|
||||||
ofs = turbul / 200.0f;
|
|
||||||
|
|
||||||
if (stype != 0) {
|
|
||||||
ofs *= b2 * b2;
|
|
||||||
}
|
|
||||||
|
|
||||||
texres.tin = noiseHelper.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2] + ofs, isHard, noisebasis);// ==nor[2]
|
|
||||||
if (colorBand != null) {
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
if (texres.nor != null) {
|
|
||||||
texres.nor[0] = noiseHelper.bliGNoise(noisesize, texvec[0] + ofs, texvec[1], texvec[2], isHard, noisebasis);
|
|
||||||
texres.nor[1] = noiseHelper.bliGNoise(noisesize, texvec[0], texvec[1] + ofs, texvec[2], isHard, noisebasis);
|
|
||||||
texres.nor[2] = texres.tin;
|
|
||||||
noiseHelper.texNormalDerivate(colorBand, texres, dataRepository);
|
|
||||||
|
|
||||||
if (stype == NoiseGenerator.TEX_WALLOUT) {
|
|
||||||
texres.nor[0] = -texres.nor[0];
|
|
||||||
texres.nor[1] = -texres.nor[1];
|
|
||||||
texres.nor[2] = -texres.nor[2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stype == NoiseGenerator.TEX_WALLOUT) {
|
|
||||||
texres.tin = 1.0f - texres.tin;
|
|
||||||
}
|
|
||||||
if (texres.tin < 0.0f) {
|
|
||||||
texres.tin = 0.0f;
|
|
||||||
}
|
|
||||||
if (colorBand != null) {
|
|
||||||
data.put((byte) (texres.tr * 255.0f));
|
|
||||||
data.put((byte) (texres.tg * 255.0f));
|
|
||||||
data.put((byte) (texres.tb * 255.0f));
|
|
||||||
} else {
|
|
||||||
data.put((byte) (texres.tin * 255.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(format, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the noise texture.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of the texture
|
|
||||||
* @param height
|
|
||||||
* the height of the texture
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return the generated texture
|
|
||||||
*/
|
|
||||||
// TODO: correct this one, so it looks more like the texture generated by blender
|
|
||||||
protected Texture texnoise(Structure tex, int width, int height, DataRepository dataRepository) {
|
|
||||||
float div = 3.0f;
|
|
||||||
int val, ran, 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;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 1;
|
|
||||||
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
|
||||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
|
||||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
|
||||||
|
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel);
|
|
||||||
for (int i = -halfW; i < halfW; ++i) {
|
|
||||||
for (int j = -halfH; j < halfH; ++j) {
|
|
||||||
ran = FastMath.rand.nextInt();// BLI_rand();
|
|
||||||
val = ran & 3;
|
|
||||||
|
|
||||||
loop = noisedepth;
|
|
||||||
while (loop-- != 0) {
|
|
||||||
ran = ran >> 2;
|
|
||||||
val *= ran & 3;
|
|
||||||
div *= 3.0f;
|
|
||||||
}
|
|
||||||
texres.tin = val;// / div;
|
|
||||||
if (colorBand != null) {
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
noiseHelper.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 {
|
|
||||||
noiseHelper.brightnesAndContrast(texres, contrast, brightness);
|
|
||||||
data.put((byte) (texres.tin * 255.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(format, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the musgrave texture.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of the texture
|
|
||||||
* @param height
|
|
||||||
* the height of the texture
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return the generated texture
|
|
||||||
*/
|
|
||||||
protected Texture musgrave(Structure tex, int width, int height, DataRepository dataRepository) {
|
|
||||||
int stype = ((Number) tex.getFieldValue("stype")).intValue();
|
|
||||||
float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
|
|
||||||
TexResult texres = new TexResult();
|
|
||||||
float[] texvec = new float[] { 0, 0, 0 };
|
|
||||||
float wDelta = 1.0f / width, hDelta = 1.0f / height;
|
|
||||||
int halfW = width, halfH = height;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 1;
|
|
||||||
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
|
||||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
|
||||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
|
||||||
|
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(width * height * 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;
|
|
||||||
switch (stype) {
|
|
||||||
case NoiseGenerator.TEX_MFRACTAL:
|
|
||||||
case NoiseGenerator.TEX_FBM:
|
|
||||||
noiseHelper.mgMFractalOrfBmTex(tex, texvec, colorBand, texres, dataRepository);
|
|
||||||
break;
|
|
||||||
case NoiseGenerator.TEX_RIDGEDMF:
|
|
||||||
case NoiseGenerator.TEX_HYBRIDMF:
|
|
||||||
noiseHelper.mgRidgedOrHybridMFTex(tex, texvec, colorBand, texres, dataRepository);
|
|
||||||
break;
|
|
||||||
case NoiseGenerator.TEX_HTERRAIN:
|
|
||||||
noiseHelper.mgHTerrainTex(tex, texvec, colorBand, texres, dataRepository);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("Unknown type of musgrave texture: " + stype);
|
|
||||||
}
|
|
||||||
if (colorBand != null) {
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
data.put((byte) (texres.tr * 255.0f));
|
|
||||||
data.put((byte) (texres.tg * 255.0f));
|
|
||||||
data.put((byte) (texres.tb * 255.0f));
|
|
||||||
} else {
|
|
||||||
data.put((byte) (texres.tin * 255.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(format, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the voronoi texture.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of the texture
|
|
||||||
* @param height
|
|
||||||
* the height of the texture
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return the generated texture
|
|
||||||
*/
|
|
||||||
protected Texture voronoi(Structure tex, int width, int height, 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 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();
|
|
||||||
|
|
||||||
TexResult texres = new TexResult();
|
|
||||||
float[] texvec = new float[] { 0, 0, 0 };
|
|
||||||
float wDelta = 1.0f / width, hDelta = 1.0f / height;
|
|
||||||
int halfW = width, halfH = height;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(width * height * 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;
|
|
||||||
|
|
||||||
noiseHelper.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) {
|
|
||||||
noiseHelper.cellNoiseV(pa[0], pa[1], pa[2], ca);
|
|
||||||
texres.tr = aw1 * ca[0];
|
|
||||||
texres.tg = aw1 * ca[1];
|
|
||||||
texres.tb = aw1 * ca[2];
|
|
||||||
noiseHelper.cellNoiseV(pa[3], pa[4], pa[5], ca);
|
|
||||||
texres.tr += aw2 * ca[0];
|
|
||||||
texres.tg += aw2 * ca[1];
|
|
||||||
texres.tb += aw2 * ca[2];
|
|
||||||
noiseHelper.cellNoiseV(pa[6], pa[7], pa[8], ca);
|
|
||||||
texres.tr += aw3 * ca[0];
|
|
||||||
texres.tg += aw3 * ca[1];
|
|
||||||
texres.tb += aw3 * ca[2];
|
|
||||||
noiseHelper.cellNoiseV(pa[9], pa[10], pa[11], ca);
|
|
||||||
texres.tr += aw4 * ca[0];
|
|
||||||
texres.tg += aw4 * ca[1];
|
|
||||||
texres.tb += aw4 * ca[2];
|
|
||||||
if (vn_coltype >= 2) {
|
|
||||||
float t1 = (da[1] - da[0]) * 10.0f;
|
|
||||||
if (t1 > 1) {
|
|
||||||
t1 = 1.0f;
|
|
||||||
}
|
|
||||||
if (vn_coltype == 3) {
|
|
||||||
t1 *= texres.tin;
|
|
||||||
} else {
|
|
||||||
t1 *= sc;
|
|
||||||
}
|
|
||||||
texres.tr *= t1;
|
|
||||||
texres.tg *= t1;
|
|
||||||
texres.tb *= t1;
|
|
||||||
} else {
|
|
||||||
texres.tr *= sc;
|
|
||||||
texres.tg *= sc;
|
|
||||||
texres.tb *= sc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (colorBand != null) {
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
if (texres.nor != null) {
|
|
||||||
float offs = nabla / noisesize; // also scaling of texvec
|
|
||||||
// calculate bumpnormal
|
|
||||||
noiseHelper.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]);
|
|
||||||
noiseHelper.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]);
|
|
||||||
noiseHelper.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]);
|
|
||||||
noiseHelper.texNormalDerivate(colorBand, texres, dataRepository);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vn_coltype != 0 || colorBand != null) {
|
|
||||||
noiseHelper.brightnesAndContrastRGB(tex, texres);
|
|
||||||
data.put((byte) (texres.tr * 255.0f));// tin or tr??
|
|
||||||
data.put((byte) (texres.tg * 255.0f));
|
|
||||||
data.put((byte) (texres.tb * 255.0f));
|
|
||||||
} else {
|
|
||||||
noiseHelper.brightnesAndContrast(texres, contrast, brightness);
|
|
||||||
data.put((byte) (texres.tin * 255.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(format, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method generates the distorted noise texture.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param width
|
|
||||||
* the width of the texture
|
|
||||||
* @param height
|
|
||||||
* the height of the texture
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return the generated texture
|
|
||||||
*/
|
|
||||||
protected Texture distnoise(Structure tex, int width, int height, 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();
|
|
||||||
float[] texvec = new float[] { 0, 0, 0 };
|
|
||||||
float wDelta = 1.0f / width, hDelta = 1.0f / height;
|
|
||||||
int halfW = width, halfH = height;
|
|
||||||
width <<= 1;
|
|
||||||
height <<= 1;
|
|
||||||
ColorBand colorBand = this.readColorband(tex, dataRepository);
|
|
||||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
|
||||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
|
||||||
|
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(width * height * 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;
|
|
||||||
|
|
||||||
texres.tin = noiseHelper.mgVLNoise(texvec[0], texvec[1], texvec[2], distAmount, noisebasis, noisebasis2);
|
|
||||||
if (colorBand != null) {
|
|
||||||
noiseHelper.doColorband(colorBand, texres, dataRepository);
|
|
||||||
if (texres.nor != null) {
|
|
||||||
float offs = nabla / noisesize; // also scaling of texvec
|
|
||||||
/* calculate bumpnormal */
|
|
||||||
texres.nor[0] = noiseHelper.mgVLNoise(texvec[0] + offs, texvec[1], texvec[2], distAmount, noisebasis, noisebasis2);
|
|
||||||
texres.nor[1] = noiseHelper.mgVLNoise(texvec[0], texvec[1] + offs, texvec[2], distAmount, noisebasis, noisebasis2);
|
|
||||||
texres.nor[2] = noiseHelper.mgVLNoise(texvec[0], texvec[1], texvec[2] + offs, distAmount, noisebasis, noisebasis2);
|
|
||||||
noiseHelper.texNormalDerivate(colorBand, texres, dataRepository);
|
|
||||||
}
|
|
||||||
|
|
||||||
noiseHelper.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 {
|
|
||||||
noiseHelper.brightnesAndContrast(texres, contrast, brightness);
|
|
||||||
data.put((byte) (texres.tin * 255.0f));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Texture2D(new Image(format, width, height, data));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method reads the colorband data from the given texture structure.
|
|
||||||
*
|
|
||||||
* @param tex
|
|
||||||
* the texture structure
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return read colorband or null if not present
|
|
||||||
*/
|
|
||||||
protected ColorBand readColorband(Structure tex, DataRepository dataRepository) {
|
|
||||||
ColorBand result = null;
|
|
||||||
int flag = ((Number) tex.getFieldValue("flag")).intValue();
|
|
||||||
if ((flag & NoiseGenerator.TEX_COLORBAND) != 0) {
|
|
||||||
Pointer pColorband = (Pointer) tex.getFieldValue("coba");
|
|
||||||
Structure colorbandStructure;
|
|
||||||
try {
|
|
||||||
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 ???
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method blends the given texture with material color and the defined color in 'map to' panel. As a result of this method a new
|
* This method blends the given texture with material color and the defined color in 'map to' panel. As a result of this method a new
|
||||||
* texture is created. The input texture is NOT.
|
* texture is created. The input texture is NOT.
|
||||||
@ -1189,7 +409,7 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
* @param dataRepository
|
* @param dataRepository
|
||||||
* the data repository
|
* the data repository
|
||||||
*/
|
*/
|
||||||
public void blendPixel(float[] result, float[] materialColor, float[] color, float textureIntensity, float textureFactor, int blendtype, DataRepository dataRepository) {
|
protected void blendPixel(float[] result, float[] materialColor, float[] color, float textureIntensity, float textureFactor, int blendtype, DataRepository dataRepository) {
|
||||||
float facm, col;
|
float facm, col;
|
||||||
|
|
||||||
switch (blendtype) {
|
switch (blendtype) {
|
||||||
@ -1325,7 +545,7 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
* @param dataRepository
|
* @param dataRepository
|
||||||
* the data repository
|
* the data repository
|
||||||
*/
|
*/
|
||||||
public void rampBlend(int type, float[] rgb, float fac, float[] col, DataRepository dataRepository) {
|
protected void rampBlend(int type, float[] rgb, float fac, float[] col, DataRepository dataRepository) {
|
||||||
float tmp, facm = 1.0f - fac;
|
float tmp, facm = 1.0f - fac;
|
||||||
MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class);
|
MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class);
|
||||||
|
|
||||||
@ -1793,92 +1013,6 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* An image loader class. It uses three loaders (AWTLoader, TGALoader and DDSLoader) in an attempt to load the image from the given
|
|
||||||
* input stream.
|
|
||||||
*
|
|
||||||
* @author Marcin Roguski (Kaelthas)
|
|
||||||
*/
|
|
||||||
protected static class ImageLoader extends AWTLoader {
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(ImageLoader.class.getName());
|
|
||||||
|
|
||||||
protected DDSLoader ddsLoader = new DDSLoader(); // DirectX image loader
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method loads the image from the blender file itself. It tries each loader to load the image.
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* blender input stream
|
|
||||||
* @param startPosition
|
|
||||||
* position in the stream where the image data starts
|
|
||||||
* @param flipY
|
|
||||||
* if the image should be flipped (does not work with DirectX image)
|
|
||||||
* @return loaded image or null if it could not be loaded
|
|
||||||
*/
|
|
||||||
public Image loadImage(BlenderInputStream inputStream, int startPosition, boolean flipY) {
|
|
||||||
// loading using AWT loader
|
|
||||||
inputStream.setPosition(startPosition);
|
|
||||||
Image result = this.loadImage(inputStream, ImageType.AWT, flipY);
|
|
||||||
// loading using TGA loader
|
|
||||||
if (result == null) {
|
|
||||||
inputStream.setPosition(startPosition);
|
|
||||||
result = this.loadImage(inputStream, ImageType.TGA, flipY);
|
|
||||||
}
|
|
||||||
// loading using DDS loader
|
|
||||||
if (result == null) {
|
|
||||||
inputStream.setPosition(startPosition);
|
|
||||||
result = this.loadImage(inputStream, ImageType.DDS, flipY);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result == null) {
|
|
||||||
LOGGER.warning("Image could not be loaded by none of available loaders!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method loads an image of a specified type from the given input stream.
|
|
||||||
*
|
|
||||||
* @param inputStream
|
|
||||||
* the input stream we read the image from
|
|
||||||
* @param imageType
|
|
||||||
* the type of the image {@link ImageType}
|
|
||||||
* @param flipY
|
|
||||||
* if the image should be flipped (does not work with DirectX image)
|
|
||||||
* @return loaded image or null if it could not be loaded
|
|
||||||
*/
|
|
||||||
public Image loadImage(InputStream inputStream, ImageType imageType, boolean flipY) {
|
|
||||||
Image result = null;
|
|
||||||
switch (imageType) {
|
|
||||||
case AWT:
|
|
||||||
try {
|
|
||||||
result = this.load(inputStream, flipY);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.info("Unable to load image using AWT loader!");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DDS:
|
|
||||||
try {
|
|
||||||
result = ddsLoader.load(inputStream);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.info("Unable to load image using DDS loader!");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TGA:
|
|
||||||
try {
|
|
||||||
result = TGALoader.load(inputStream, flipY);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.info("Unable to load image using TGA loader!");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("Unknown image type: " + imageType);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) {
|
public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) {
|
||||||
return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0;
|
return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user