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()); | ||||
| 
 | ||||
|     /* return value */ | ||||
|     // return value | ||||
|     protected static final int TEX_INT = 0; | ||||
|     protected static final int TEX_RGB = 1; | ||||
|     protected static final int TEX_NOR = 2; | ||||
| 
 | ||||
|     /* noisetype */ | ||||
|     // noisetype | ||||
|     protected static final int TEX_NOISESOFT = 0; | ||||
|     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_COLOR = 1; | ||||
| 
 | ||||
|     /* flag */ | ||||
|     // flag | ||||
|     protected static final int TEX_COLORBAND = 1; | ||||
|     protected static final int TEX_FLIPBLEND = 2; | ||||
|     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_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_SAW = 1; | ||||
|     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_SHARP = 1; | ||||
|     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_RING = 1; | ||||
|     protected static final int TEX_BANDNOISE = 2; | ||||
|     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_QUAD = 1; | ||||
|     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_RAD = 6; | ||||
| 
 | ||||
|     /* tex->stype in texture.c - stucci types */ | ||||
|     // tex->stype | ||||
|     protected static final int TEX_PLASTIC = 0; | ||||
|     protected static final int TEX_WALLIN = 1; | ||||
|     protected static final int TEX_WALLOUT = 2; | ||||
| 
 | ||||
|     /* musgrave stype */ | ||||
|     // musgrave stype | ||||
|     protected static final int TEX_MFRACTAL = 0; | ||||
|     protected static final int TEX_RIDGEDMF = 1; | ||||
|     protected static final int TEX_HYBRIDMF = 2; | ||||
|     protected static final int TEX_FBM = 3; | ||||
|     protected static final int TEX_HTERRAIN = 4; | ||||
| 
 | ||||
|     /* keyblock->type */ | ||||
|     // keyblock->type | ||||
|     protected static final int KEY_LINEAR = 0; | ||||
|     protected static final int KEY_CARDINAL = 1; | ||||
|     protected static final int KEY_BSPLINE = 2; | ||||
| 
 | ||||
|     /* CONSTANTS (read from file) */ | ||||
|     // CONSTANTS (read from file) | ||||
|     protected static float[] hashpntf; | ||||
|     protected static short[] hash; | ||||
|     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 */ | ||||
|         // #define HASHPNT(x,y,z) hashpntf+3*hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255] | ||||
|         // needed for voronoi | ||||
|         protected static float[] hashPoint(int x, int y, int z) { | ||||
|             float[] result = new float[3]; | ||||
|             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; | ||||
|         } | ||||
| 
 | ||||
|         // #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) { | ||||
|             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; | ||||
|             int i, j; | ||||
| 
 | ||||
|             // setup(0, bx0,bx1, rx0,rx1); | ||||
|             t = vec[0] + 10000.0f; | ||||
|             bx0 = (int) t & 255; | ||||
|             bx1 = bx0 + 1 & 255; | ||||
|             rx0 = t - (int) t; | ||||
|             rx1 = rx0 - 1.0f; | ||||
|             // setup(1, by0,by1, ry0,ry1); | ||||
|              | ||||
|             t = vec[0] + 10000.0f; | ||||
|             by0 = (int) t & 255; | ||||
|             by1 = by0 + 1 & 255; | ||||
|             ry0 = t - (int) t; | ||||
|             ry1 = ry0 - 1.0f; | ||||
|             // setup(2, bz0,bz1, rz0,rz1); | ||||
|              | ||||
|             t = vec[0] + 10000.0f; | ||||
|             bz0 = (int) t & 255; | ||||
|             bz1 = bz0 + 1 & 255; | ||||
| @ -1339,7 +1328,7 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; | ||||
|             b01 = p[i + by1]; | ||||
|             b11 = p[j + by1]; | ||||
| 
 | ||||
|             /* lerp moved to improved perlin above */ | ||||
|             // lerp moved to improved perlin above | ||||
| 
 | ||||
|             sx = this.surve(rx0); | ||||
|             sy = this.surve(ry0); | ||||
| @ -1358,7 +1347,7 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; | ||||
|             v = this.at(rx1, ry1, rz0, q); | ||||
|             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]; | ||||
|             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); | ||||
|             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) { | ||||
|             float cn1, cn2, cn3, cn4, cn5, cn6, i; | ||||
|             float ox, oy, oz, jx, jy, jz; | ||||
|             float n = 0.5f; | ||||
|             int ix, iy, iz, b00, b01, b10, b11, b20, b21; | ||||
| 
 | ||||
|             ox = x - (ix = (int) Math.floor(x)); | ||||
|             oy = y - (iy = (int) Math.floor(y)); | ||||
|             oz = z - (iz = (int) Math.floor(z)); | ||||
|             int ix = (int) Math.floor(x); | ||||
|             int iy = (int) Math.floor(y); | ||||
|             int iz = (int) Math.floor(z); | ||||
|              | ||||
|             float ox = x - ix; | ||||
|             float oy = y - iy; | ||||
|             float oz = z - iz; | ||||
| 
 | ||||
|             jx = ox - 1; | ||||
|             jy = oy - 1; | ||||
|             jz = oz - 1; | ||||
|             float jx = ox - 1; | ||||
|             float jy = oy - 1; | ||||
|             float jz = oz - 1; | ||||
| 
 | ||||
|             cn1 = ox * ox; | ||||
|             cn2 = oy * oy; | ||||
|             cn3 = oz * oz; | ||||
|             cn4 = jx * jx; | ||||
|             cn5 = jy * jy; | ||||
|             cn6 = jz * jz; | ||||
|             float cn1 = ox * ox; | ||||
|             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; | ||||
|             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; | ||||
|             cn6 = 1.0f - 3.0f * cn6 - 2.0f * cn6 * jz; | ||||
| 
 | ||||
|             b00 = hash[hash[ix & 255] + (iy & 255)]; | ||||
|             b10 = hash[hash[ix + 1 & 255] + (iy & 255)]; | ||||
|             b01 = hash[hash[ix & 255] + (iy + 1 & 255)]; | ||||
|             b11 = hash[hash[ix + 1 & 255] + (iy + 1 & 255)]; | ||||
|             int b00 = hash[hash[ix & 255] + (iy & 255)]; | ||||
|             int b10 = hash[hash[ix + 1 & 255] + (iy & 255)]; | ||||
|             int b01 = hash[hash[ix & 255] + (iy + 1 & 255)]; | ||||
|             int b11 = hash[hash[ix + 1 & 255] + (iy + 1 & 255)]; | ||||
| 
 | ||||
|             b20 = iz & 255; | ||||
|             b21 = iz + 1 & 255; | ||||
|             int b20 = iz & 255; | ||||
|             int b21 = iz + 1 & 255; | ||||
| 
 | ||||
|             /* 0 */ | ||||
|             i = cn1 * cn2 * cn3; | ||||
|             // 0 | ||||
|             float i = cn1 * cn2 * cn3; | ||||
|             int hIndex = 3 * hash[b20 + b00]; | ||||
|             n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * oz); | ||||
|             /* 1 */ | ||||
|             // 1 | ||||
|             i = cn1 * cn2 * cn6; | ||||
|             hIndex = 3 * hash[b21 + b00]; | ||||
|             n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * jz); | ||||
|             /* 2 */ | ||||
|             // 2 | ||||
|             i = cn1 * cn5 * cn3; | ||||
|             hIndex = 3 * hash[b20 + b01]; | ||||
|             n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * oz); | ||||
|             /* 3 */ | ||||
|             // 3 | ||||
|             i = cn1 * cn5 * cn6; | ||||
|             hIndex = 3 * hash[b21 + b01]; | ||||
|             n += i * (hashvectf[hIndex] * ox + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * jz); | ||||
|             /* 4 */ | ||||
|             // 4 | ||||
|             i = cn4 * cn2 * cn3; | ||||
|             hIndex = 3 * hash[b20 + b10]; | ||||
|             n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * oz); | ||||
|             /* 5 */ | ||||
|             // 5 | ||||
|             i = cn4 * cn2 * cn6; | ||||
|             hIndex = 3 * hash[b21 + b10]; | ||||
|             n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * oy + hashvectf[hIndex + 2] * jz); | ||||
|             /* 6 */ | ||||
|             // 6 | ||||
|             i = cn4 * cn5 * cn3; | ||||
|             hIndex = 3 * hash[b20 + b11]; | ||||
|             n += i * (hashvectf[hIndex] * jx + hashvectf[hIndex + 1] * jy + hashvectf[hIndex + 2] * oz); | ||||
|             /* 7 */ | ||||
|             // 7 | ||||
|             i = cn4 * cn5 * cn6; | ||||
|             hIndex = 3 * hash[b21 + b11]; | ||||
|             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; | ||||
|         } | ||||
| 
 | ||||
|         /* 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) { | ||||
|             int A, AA, AB, B, BA, BB; | ||||
|             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.InputStream; | ||||
| import java.nio.ByteBuffer; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
| import java.util.logging.Level; | ||||
| 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.LoadedFeatureDataType; | ||||
| 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.FileBlockHeader; | ||||
| 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.WrapMode; | ||||
| 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; | ||||
| 
 | ||||
| /** | ||||
| @ -79,7 +77,7 @@ import com.jme3.util.BufferUtils; | ||||
|  */ | ||||
| public class TextureHelper extends AbstractBlenderHelper { | ||||
| 	private static final Logger	LOGGER				= Logger.getLogger(TextureHelper.class.getName()); | ||||
| 
 | ||||
| 	 | ||||
| 	// texture types | ||||
| 	public static final int		TEX_NONE			= 0; | ||||
| 	public static final int		TEX_CLOUDS			= 1; | ||||
| @ -151,18 +149,29 @@ public class TextureHelper extends AbstractBlenderHelper { | ||||
| 	public static final int		MA_RAMP_VAL			= 14; | ||||
| 	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 | ||||
| 	 * versions. | ||||
| 	 * This constructor parses the given blender version and stores the result. | ||||
| 	 * It creates noise generator and texture generators. | ||||
| 	 *  | ||||
| 	 * @param blenderVersion | ||||
| 	 *        the version read from the blend file | ||||
| 	 */ | ||||
| 	public TextureHelper(String 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; | ||||
| 			case TEX_CLOUDS: | ||||
| 				result = this.clouds(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			case TEX_WOOD: | ||||
| 				result = this.wood(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			case TEX_MARBLE: | ||||
| 				result = this.marble(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			case TEX_MAGIC: | ||||
| 				result = this.magic(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			case TEX_BLEND: | ||||
| 				result = this.blend(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			case TEX_STUCCI: | ||||
| 				result = this.stucci(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			case TEX_NOISE: | ||||
| 				result = this.texnoise(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			case TEX_MUSGRAVE: | ||||
| 				result = this.musgrave(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			case TEX_VORONOI: | ||||
| 				result = this.voronoi(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			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; | ||||
| 			case TEX_NONE:// No texture, do nothing | ||||
| 				break; | ||||
| @ -249,778 +241,6 @@ public class TextureHelper extends AbstractBlenderHelper { | ||||
| 		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 | ||||
| 	 * texture is created. The input texture is NOT. | ||||
| @ -1189,7 +409,7 @@ public class TextureHelper extends AbstractBlenderHelper { | ||||
| 	 * @param dataRepository | ||||
| 	 *        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; | ||||
| 
 | ||||
| 		switch (blendtype) { | ||||
| @ -1325,7 +545,7 @@ public class TextureHelper extends AbstractBlenderHelper { | ||||
| 	 * @param dataRepository | ||||
| 	 *        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; | ||||
| 		MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class); | ||||
| 
 | ||||
| @ -1792,92 +1012,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 | ||||
| 	public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user