|
|
|
@ -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. |
|
|
|
|
* |
|
|
|
|