Fix to loading normal maps.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7918 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
		
							parent
							
								
									f15107da95
								
							
						
					
					
						commit
						0de5fe39a3
					
				| @ -252,11 +252,9 @@ public class MaterialHelper extends AbstractBlenderHelper { | ||||
| 							Structure tex = pTex.fetchData(dataRepository.getInputStream()).get(0); | ||||
| 							Texture texture = textureHelper.getTexture(tex, dataRepository); | ||||
|                                                          | ||||
|                                                          | ||||
|                                                          | ||||
| 							if (texture != null) { | ||||
|                                                             // NOTE: Enable mipmaps FOR ALL TEXTURES EVER | ||||
|                                                             texture.setMinFilter(MinFilter.Trilinear); | ||||
|                                 // NOTE: Enable mipmaps FOR ALL TEXTURES EVER | ||||
|                                 texture.setMinFilter(MinFilter.Trilinear); | ||||
|                                                              | ||||
| 								if ((mapto & 0x01) != 0) {// Col | ||||
|                                     // Map to COLOR channel or DIFFUSE | ||||
| @ -276,7 +274,8 @@ public class MaterialHelper extends AbstractBlenderHelper { | ||||
| 									} | ||||
| 								} | ||||
| 								if ((mapto & 0x02) != 0) {// Nor | ||||
| 									result.setTexture(TEXTURE_TYPE_NORMAL, texture); | ||||
| 									Texture normalMapTexture = textureHelper.convertToNormalMapTexture(texture, ((Number)tex.getFieldValue("norfac")).floatValue()); | ||||
| 									result.setTexture(TEXTURE_TYPE_NORMAL, normalMapTexture); | ||||
| 									if (vertexColor) { | ||||
| 										result.setBoolean(shadeless ? "VertexColor" : "UseVertexColor", false); | ||||
| 									} | ||||
|  | ||||
| @ -31,6 +31,9 @@ | ||||
|  */ | ||||
| package com.jme3.scene.plugins.blender.helpers.v249; | ||||
| 
 | ||||
| import java.awt.color.ColorSpace; | ||||
| import java.awt.image.BufferedImage; | ||||
| import java.awt.image.ColorConvertOp; | ||||
| import java.io.File; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.FileNotFoundException; | ||||
| @ -40,10 +43,13 @@ import java.nio.ByteBuffer; | ||||
| import java.util.logging.Level; | ||||
| import java.util.logging.Logger; | ||||
| 
 | ||||
| import jme3tools.converters.ImageToAwt; | ||||
| 
 | ||||
| import com.jme3.asset.AssetNotFoundException; | ||||
| import com.jme3.asset.TextureKey; | ||||
| import com.jme3.asset.BlenderKey.FeaturesToLoad; | ||||
| import com.jme3.math.FastMath; | ||||
| import com.jme3.math.Vector3f; | ||||
| import com.jme3.scene.plugins.blender.data.FileBlockHeader; | ||||
| import com.jme3.scene.plugins.blender.data.Structure; | ||||
| import com.jme3.scene.plugins.blender.exception.BlenderFileException; | ||||
| @ -174,14 +180,12 @@ public class TextureHelper extends AbstractBlenderHelper { | ||||
| 		int height = dataRepository.getBlenderKey().getGeneratedTextureHeight(); | ||||
| 
 | ||||
| 		switch (type) { | ||||
| 			case TEX_NONE:// No texture, do nothing | ||||
| 				break; | ||||
| 			case TEX_IMAGE:// (it is first because probably this will be most commonly used) | ||||
| 				Pointer pImage = (Pointer) tex.getFieldValue("ima"); | ||||
|                                 if (pImage.isNotNull()){ | ||||
|                                     Structure image = pImage.fetchData(dataRepository.getInputStream()).get(0); | ||||
|                                     result = this.getTextureFromImage(image, dataRepository); | ||||
|                                 } | ||||
|                 if (pImage.isNotNull()){ | ||||
|                     Structure image = pImage.fetchData(dataRepository.getInputStream()).get(0); | ||||
|                     result = this.getTextureFromImage(image, dataRepository); | ||||
|                 } | ||||
| 				break; | ||||
| 			case TEX_CLOUDS: | ||||
| 				result = this.clouds(tex, width, height, dataRepository); | ||||
| @ -213,6 +217,8 @@ public class TextureHelper extends AbstractBlenderHelper { | ||||
| 			case TEX_DISTNOISE: | ||||
| 				result = this.distnoise(tex, width, height, dataRepository); | ||||
| 				break; | ||||
| 			case TEX_NONE:// No texture, do nothing | ||||
| 				break; | ||||
| 			case TEX_PLUGIN: | ||||
| 			case TEX_ENVMAP:// TODO: implement envmap texture | ||||
| 				LOGGER.log(Level.WARNING, "Unsupported texture type: {0} for texture: {1}", new Object[]{type, tex.getName()}); | ||||
| @ -1550,6 +1556,90 @@ public class TextureHelper extends AbstractBlenderHelper { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This method converts the given texture into normal-map texture. | ||||
| 	 * @param source | ||||
| 	 *        the source texture | ||||
| 	 * @param strengthFactor | ||||
| 	 *        the normal strength factor | ||||
| 	 * @return normal-map texture | ||||
| 	 */ | ||||
| 	public Texture convertToNormalMapTexture(Texture source, float strengthFactor) { | ||||
| 		Image image = source.getImage(); | ||||
| 		BufferedImage sourceImage = ImageToAwt.convert(image, false, false, 0); | ||||
| 		BufferedImage heightMap = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB); | ||||
| 		BufferedImage bumpMap = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB); | ||||
| 		ColorConvertOp gscale = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null); | ||||
| 		gscale.filter(sourceImage, heightMap); | ||||
| 
 | ||||
| 		Vector3f S = new Vector3f(); | ||||
| 		Vector3f T = new Vector3f(); | ||||
| 		Vector3f N = new Vector3f(); | ||||
| 
 | ||||
| 		for (int x = 0; x < bumpMap.getWidth(); ++x) { | ||||
| 			for (int y = 0; y < bumpMap.getHeight(); ++y) { | ||||
| 				// generating bump pixel | ||||
| 				S.x = 1; | ||||
| 				S.y = 0; | ||||
| 				S.z = strengthFactor * this.getHeight(heightMap, x + 1, y) - strengthFactor * this.getHeight(heightMap, x - 1, y); | ||||
| 				T.x = 0; | ||||
| 				T.y = 1; | ||||
| 				T.z = strengthFactor * this.getHeight(heightMap, x, y + 1) - strengthFactor * this.getHeight(heightMap, x, y - 1); | ||||
| 
 | ||||
| 				float den = (float) Math.sqrt(S.z * S.z + T.z * T.z + 1); | ||||
| 				N.x = -S.z; | ||||
| 				N.y = -T.z; | ||||
| 				N.z = 1; | ||||
| 				N.divideLocal(den); | ||||
| 
 | ||||
| 				// setting thge pixel in the result image | ||||
| 				bumpMap.setRGB(x, y, this.vectorToColor(N.x, N.y, N.z)); | ||||
| 			} | ||||
| 		} | ||||
| 		ByteBuffer byteBuffer = BufferUtils.createByteBuffer(image.getWidth() * image.getHeight() * 3); | ||||
| 		ImageToAwt.convert(bumpMap, Format.RGB8, byteBuffer); | ||||
| 		return new Texture2D(new Image(Format.RGB8, image.getWidth(), image.getHeight(), byteBuffer)); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This method returns the height represented by the specified pixel in the given texture. | ||||
| 	 * The given texture should be a height-map. | ||||
| 	 * @param image | ||||
| 	 *        the height-map texture | ||||
| 	 * @param x | ||||
| 	 *        pixel's X coordinate | ||||
| 	 * @param y | ||||
| 	 *        pixel's Y coordinate | ||||
| 	 * @return height reprezented by the given texture in the specified location | ||||
| 	 */ | ||||
| 	protected int getHeight(BufferedImage image, int x, int y) { | ||||
| 		if (x < 0) { | ||||
| 			x = 0; | ||||
| 		} else if (x >= image.getWidth()) { | ||||
| 			x = image.getWidth() - 1; | ||||
| 		} | ||||
| 		if (y < 0) { | ||||
| 			y = 0; | ||||
| 		} else if (y >= image.getHeight()) { | ||||
| 			y = image.getHeight() - 1; | ||||
| 		} | ||||
| 		return image.getRGB(x, y) & 0xff; | ||||
| 	} | ||||
|      | ||||
| 	/** | ||||
| 	 * This method transforms given vector's coordinates into ARGB color (A is always = 255). | ||||
| 	 * @param x X factor of the vector | ||||
| 	 * @param y Y factor of the vector | ||||
| 	 * @param z Z factor of the vector | ||||
| 	 * @return color representation of the given vector | ||||
| 	 */ | ||||
|     protected int vectorToColor(float x, float y, float z) { | ||||
|         int r = Math.round(255 * (x + 1f) / 2f); | ||||
|         int g = Math.round(255 * (y + 1f) / 2f); | ||||
|         int b = Math.round(255 * (z + 1f) / 2f); | ||||
|         return (255 << 24) + (r << 16) + (g << 8) + b; | ||||
|     } | ||||
| 	 | ||||
| 	/** | ||||
| 	 * This class returns a texture read from the file or from packed blender data. | ||||
| 	 *  | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user