Support for generated textures merging.
Optimizations in textures loading when multiple textures are applied. Fixes in pixel blending. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8324 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
a28d0d8baf
commit
846b569552
engine/src/blender/com/jme3/scene/plugins/blender
cameras
materials
textures
TextureGenerator.javaTextureGeneratorBlend.javaTextureGeneratorClouds.javaTextureGeneratorDistnoise.javaTextureGeneratorMagic.javaTextureGeneratorMarble.javaTextureGeneratorMusgrave.javaTextureGeneratorNoise.javaTextureGeneratorStucci.javaTextureGeneratorVoronoi.javaTextureGeneratorWood.javaTextureHelper.javaTexturePixel.java
@ -17,8 +17,8 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
||||
public class CameraHelper extends AbstractBlenderHelper {
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(CameraHelper.class.getName());
|
||||
protected static final int DEFAULT_CAM_WIDTH = 100;
|
||||
protected static final int DEFAULT_CAM_HEIGHT = 100;
|
||||
protected static final int DEFAULT_CAM_WIDTH = 640;
|
||||
protected static final int DEFAULT_CAM_HEIGHT = 480;
|
||||
|
||||
/**
|
||||
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
|
||||
@ -98,7 +98,6 @@ public class CameraHelper extends AbstractBlenderHelper {
|
||||
}
|
||||
//type==0 - perspective; type==1 - orthographic; perspective is used as default
|
||||
result.setParallelProjection(type == 1);
|
||||
float angle = ((Number) structure.getFieldValue("angle")).floatValue();
|
||||
float aspect = 0;
|
||||
float clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
|
||||
float clipend = ((Number) structure.getFieldValue("clipend")).floatValue();
|
||||
@ -107,7 +106,7 @@ public class CameraHelper extends AbstractBlenderHelper {
|
||||
} else {
|
||||
aspect = ((Number) structure.getFieldValue("ortho_scale")).floatValue();
|
||||
}
|
||||
result.setFrustumPerspective(angle, aspect, clipsta, clipend);
|
||||
result.setFrustumPerspective(aspect, result.getWidth() / result.getHeight(), clipsta, clipend);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1,31 +1,58 @@
|
||||
package com.jme3.scene.plugins.blender.materials;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.scene.plugins.blender.BlenderContext;
|
||||
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
|
||||
import com.jme3.scene.plugins.blender.file.DynamicArray;
|
||||
import com.jme3.scene.plugins.blender.file.Pointer;
|
||||
import com.jme3.scene.plugins.blender.file.Structure;
|
||||
import com.jme3.scene.plugins.blender.materials.MaterialHelper.DiffuseShader;
|
||||
import com.jme3.scene.plugins.blender.materials.MaterialHelper.SpecularShader;
|
||||
import com.jme3.scene.plugins.blender.textures.TextureHelper;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.Texture.Type;
|
||||
import com.jme3.texture.Texture.WrapMode;
|
||||
|
||||
/**
|
||||
* This class holds the data about the material.
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
*/
|
||||
public final class MaterialContext {
|
||||
private static final Logger LOGGER = Logger.getLogger(MaterialContext.class.getName());
|
||||
|
||||
//texture mapping types
|
||||
public static final int MTEX_COL = 0x01;
|
||||
public static final int MTEX_NOR = 0x02;
|
||||
public static final int MTEX_SPEC = 0x04;
|
||||
public static final int MTEX_EMIT = 0x40;
|
||||
public static final int MTEX_ALPHA = 0x80;
|
||||
|
||||
/* package */final String name;
|
||||
/* package */final List<Structure> mTexs;
|
||||
/* package */final List<Structure> textures;
|
||||
/* package */final Map<Number, Texture> loadedTextures;
|
||||
/* package */final Map<Texture, Structure> textureToMTexMap;
|
||||
/* package */final int texturesCount;
|
||||
/* package */final Type textureType;
|
||||
|
||||
/* package */final ColorRGBA diffuseColor;
|
||||
/* package */final DiffuseShader diffuseShader;
|
||||
/* package */final SpecularShader specularShader;
|
||||
/* package */final ColorRGBA specularColor;
|
||||
/* package */final ColorRGBA ambientColor;
|
||||
/* package */final float shininess;
|
||||
/* package */final boolean shadeless;
|
||||
/* package */final boolean vertexColor;
|
||||
/* package */final boolean transparent;
|
||||
/* package */final boolean vtangent;
|
||||
/* package */final boolean vTangent;
|
||||
|
||||
/* package */int uvCoordinatesType = -1;
|
||||
/* package */int projectionType;
|
||||
@ -38,10 +65,37 @@ public final class MaterialContext {
|
||||
shadeless = (mode & 0x4) != 0;
|
||||
vertexColor = (mode & 0x80) != 0;
|
||||
transparent = (mode & 0x10000) != 0;
|
||||
vtangent = (mode & 0x4000000) != 0; // NOTE: Requires tangents
|
||||
vTangent = (mode & 0x4000000) != 0; // NOTE: Requires tangents
|
||||
|
||||
int diff_shader = ((Number) structure.getFieldValue("diff_shader")).intValue();
|
||||
diffuseShader = DiffuseShader.values()[diff_shader];
|
||||
|
||||
if(this.shadeless) {
|
||||
diffuseColor = ColorRGBA.White.clone();
|
||||
specularShader = null;
|
||||
specularColor = ambientColor = null;
|
||||
shininess = 0.0f;
|
||||
} else {
|
||||
diffuseColor = this.readDiffuseColor(structure, diffuseShader);
|
||||
|
||||
int spec_shader = ((Number) structure.getFieldValue("spec_shader")).intValue();
|
||||
specularShader = SpecularShader.values()[spec_shader];
|
||||
specularColor = this.readSpecularColor(structure, specularShader);
|
||||
|
||||
float r = ((Number) structure.getFieldValue("ambr")).floatValue();
|
||||
float g = ((Number) structure.getFieldValue("ambg")).floatValue();
|
||||
float b = ((Number) structure.getFieldValue("ambb")).floatValue();
|
||||
float alpha = ((Number) structure.getFieldValue("alpha")).floatValue();
|
||||
ambientColor = new ColorRGBA(r, g, b, alpha);
|
||||
|
||||
float shininess = ((Number) structure.getFieldValue("emit")).floatValue();
|
||||
this.shininess = shininess > 0.0f ? shininess : MaterialHelper.DEFAULT_SHININESS;
|
||||
}
|
||||
float[] diffuseColorArray = new float[] {diffuseColor.r, diffuseColor.g, diffuseColor.b, diffuseColor.a};//TODO: czy trzeba wstawiac te dane?
|
||||
|
||||
mTexs = new ArrayList<Structure>();
|
||||
textures = new ArrayList<Structure>();
|
||||
|
||||
DynamicArray<Pointer> mtexsArray = (DynamicArray<Pointer>) structure.getFieldValue("mtex");
|
||||
int separatedTextures = ((Number) structure.getFieldValue("septex")).intValue();
|
||||
Type firstTextureType = null;
|
||||
@ -79,10 +133,89 @@ public final class MaterialContext {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//loading the textures and merging them
|
||||
Map<Number, List<Structure[]>> sortedTextures = this.sortAndFilterTextures();
|
||||
loadedTextures = new HashMap<Number, Texture>(sortedTextures.size());
|
||||
textureToMTexMap = new HashMap<Texture, Structure>();
|
||||
TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
|
||||
for(Entry<Number, List<Structure[]>> entry : sortedTextures.entrySet()) {
|
||||
if(entry.getValue().size()>0) {
|
||||
List<Texture> textures = new ArrayList<Texture>(entry.getValue().size());
|
||||
for(Structure[] mtexAndTex : entry.getValue()) {
|
||||
int texflag = ((Number) mtexAndTex[0].getFieldValue("texflag")).intValue();
|
||||
boolean negateTexture = (texflag & 0x04) != 0;
|
||||
Texture texture = textureHelper.getTexture(mtexAndTex[1], blenderContext);
|
||||
int blendType = ((Number) mtexAndTex[0].getFieldValue("blendtype")).intValue();
|
||||
float[] color = new float[] { ((Number) mtexAndTex[0].getFieldValue("r")).floatValue(),
|
||||
((Number) mtexAndTex[0].getFieldValue("g")).floatValue(),
|
||||
((Number) mtexAndTex[0].getFieldValue("b")).floatValue() };
|
||||
float colfac = ((Number) mtexAndTex[0].getFieldValue("colfac")).floatValue();
|
||||
texture = textureHelper.blendTexture(diffuseColorArray, texture, color, colfac, blendType, negateTexture, blenderContext);
|
||||
texture.setWrap(WrapMode.Repeat);
|
||||
textures.add(texture);
|
||||
textureToMTexMap.put(texture, mtexAndTex[0]);
|
||||
}
|
||||
loadedTextures.put(entry.getKey(), textureHelper.mergeTextures(textures, this));
|
||||
}
|
||||
}
|
||||
|
||||
this.texturesCount = mTexs.size();
|
||||
this.textureType = firstTextureType;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sorts the textures by their mapping type.
|
||||
* In each group only textures of one type are put (either two- or three-dimensional).
|
||||
* If the mapping type is MTEX_COL then if the texture has no alpha channel then all textures before it are
|
||||
* discarded and will not be loaded and merged because texture with no alpha will cover them anyway.
|
||||
* @return a map with sorted and filtered textures
|
||||
*/
|
||||
private Map<Number, List<Structure[]>> sortAndFilterTextures() {
|
||||
Map<Number, List<Structure[]>> result = new HashMap<Number, List<Structure[]>>();
|
||||
for (int i = 0; i < mTexs.size(); ++i) {
|
||||
Structure mTex = mTexs.get(i);
|
||||
Structure texture = textures.get(i);
|
||||
Number mapto = (Number) mTex.getFieldValue("mapto");
|
||||
List<Structure[]> mtexs = result.get(mapto);
|
||||
if(mtexs==null) {
|
||||
mtexs = new ArrayList<Structure[]>();
|
||||
result.put(mapto, mtexs);
|
||||
}
|
||||
if(mapto.intValue() == MTEX_COL && this.isWithoutAlpha(textures.get(i))) {
|
||||
mtexs.clear();//remove previous textures, they will be covered anyway
|
||||
}
|
||||
mtexs.add(new Structure[] {mTex, texture});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method determines if the given texture has no alpha channel.
|
||||
*
|
||||
* @param texture
|
||||
* the texture to check for alpha channel
|
||||
* @return <b>true</b> if the texture has no alpha channel and <b>false</b>
|
||||
* otherwise
|
||||
*/
|
||||
private boolean isWithoutAlpha(Structure texture) {
|
||||
int flag = ((Number) texture.getFieldValue("flag")).intValue();
|
||||
if((flag & 0x01) == 0) {//the texture has no colorband
|
||||
int type = ((Number) texture.getFieldValue("type")).intValue();
|
||||
if(type==TextureHelper.TEX_MAGIC) {
|
||||
return true;
|
||||
}
|
||||
if(type==TextureHelper.TEX_VORONOI) {
|
||||
int voronoiColorType = ((Number) texture.getFieldValue("vn_coltype")).intValue();
|
||||
return voronoiColorType != 0;//voronoiColorType == 0: intensity, voronoiColorType != 0: col1, col2 or col3
|
||||
}
|
||||
if(type==TextureHelper.TEX_CLOUDS) {
|
||||
int sType = ((Number) texture.getFieldValue("stype")).intValue();
|
||||
return sType == 1;//sType==0: without colors, sType==1: with colors
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the current material's texture UV coordinates type.
|
||||
@ -133,6 +266,74 @@ public final class MaterialContext {
|
||||
Structure mtex = mTexs.get(textureIndex);
|
||||
return new int[] { ((Number) mtex.getFieldValue("projx")).intValue(), ((Number) mtex.getFieldValue("projy")).intValue(), ((Number) mtex.getFieldValue("projz")).intValue() };
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the diffuse color.
|
||||
*
|
||||
* @param materialStructure the material structure
|
||||
* @param diffuseShader the diffuse shader
|
||||
* @return the diffuse color
|
||||
*/
|
||||
private ColorRGBA readDiffuseColor(Structure materialStructure, DiffuseShader diffuseShader) {
|
||||
// bitwise 'or' of all textures mappings
|
||||
int commonMapto = ((Number) materialStructure.getFieldValue("mapto")).intValue();
|
||||
|
||||
// diffuse color
|
||||
float r = ((Number) materialStructure.getFieldValue("r")).floatValue();
|
||||
float g = ((Number) materialStructure.getFieldValue("g")).floatValue();
|
||||
float b = ((Number) materialStructure.getFieldValue("b")).floatValue();
|
||||
float alpha = ((Number) materialStructure.getFieldValue("alpha")).floatValue();
|
||||
if ((commonMapto & 0x01) == 0x01) {// Col
|
||||
return new ColorRGBA(r, g, b, alpha);
|
||||
} else {
|
||||
switch (diffuseShader) {
|
||||
case FRESNEL:
|
||||
case ORENNAYAR:
|
||||
case TOON:
|
||||
break;// TODO: find what is the proper modification
|
||||
case MINNAERT:
|
||||
case LAMBERT:// TODO: check if that is correct
|
||||
float ref = ((Number) materialStructure.getFieldValue("ref")).floatValue();
|
||||
r *= ref;
|
||||
g *= ref;
|
||||
b *= ref;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown diffuse shader type: " + diffuseShader.toString());
|
||||
}
|
||||
return new ColorRGBA(r, g, b, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a specular color used by the material.
|
||||
*
|
||||
* @param materialStructure
|
||||
* the material structure filled with data
|
||||
* @return a specular color used by the material
|
||||
*/
|
||||
private ColorRGBA readSpecularColor(Structure materialStructure, SpecularShader specularShader) {
|
||||
float r = ((Number) materialStructure.getFieldValue("specr")).floatValue();
|
||||
float g = ((Number) materialStructure.getFieldValue("specg")).floatValue();
|
||||
float b = ((Number) materialStructure.getFieldValue("specb")).floatValue();
|
||||
float alpha = ((Number) materialStructure.getFieldValue("alpha")).floatValue();
|
||||
switch (specularShader) {
|
||||
case BLINN:
|
||||
case COOKTORRENCE:
|
||||
case TOON:
|
||||
case WARDISO:// TODO: find what is the proper modification
|
||||
break;
|
||||
case PHONG:// TODO: check if that is correct
|
||||
float spec = ((Number) materialStructure.getFieldValue("spec")).floatValue();
|
||||
r *= spec * 0.5f;
|
||||
g *= spec * 0.5f;
|
||||
b *= spec * 0.5f;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown specular shader type: " + specularShader.toString());
|
||||
}
|
||||
return new ColorRGBA(r, g, b, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method determines the type of the texture.
|
||||
@ -167,4 +368,92 @@ public final class MaterialContext {
|
||||
throw new IllegalStateException("Unknown texture type: " + texType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return he material's name
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a copy of diffuse color
|
||||
*/
|
||||
public ColorRGBA getDiffuseColor() {
|
||||
return diffuseColor.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an enum describing the type of a diffuse shader used by this material
|
||||
*/
|
||||
public DiffuseShader getDiffuseShader() {
|
||||
return diffuseShader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a copy of specular color
|
||||
*/
|
||||
public ColorRGBA getSpecularColor() {
|
||||
return specularColor.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an enum describing the type of a specular shader used by this material
|
||||
*/
|
||||
public SpecularShader getSpecularShader() {
|
||||
return specularShader;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an ambient color used by the material
|
||||
*/
|
||||
public ColorRGBA getAmbientColor() {
|
||||
return ambientColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the sihiness of this material
|
||||
*/
|
||||
public float getShininess() {
|
||||
return shininess;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <b>true</b> if the material is shadeless and <b>false</b> otherwise
|
||||
*/
|
||||
public boolean isShadeless() {
|
||||
return shadeless;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <b>true</b> if the material uses vertex color and <b>false</b> otherwise
|
||||
*/
|
||||
public boolean isVertexColor() {
|
||||
return vertexColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <b>true</b> if the material is transparent and <b>false</b> otherwise
|
||||
*/
|
||||
public boolean isTransparent() {
|
||||
return transparent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <b>true</b> if the material uses tangents and <b>false</b> otherwise
|
||||
*/
|
||||
public boolean isvTangent() {
|
||||
return vTangent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param texture
|
||||
* the texture for which its mtex structure definition will be
|
||||
* fetched
|
||||
* @return mtex structure of the current texture or <b>null</b> if none
|
||||
* exists
|
||||
*/
|
||||
public Structure getMTex(Texture texture) {
|
||||
return textureToMTexMap.get(texture);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,6 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.jme3.asset.BlenderKey.FeaturesToLoad;
|
||||
import com.jme3.asset.GeneratedTextureKey;
|
||||
import com.jme3.material.MatParam;
|
||||
import com.jme3.material.MatParamTexture;
|
||||
import com.jme3.material.Material;
|
||||
@ -59,9 +58,7 @@ import com.jme3.shader.VarType;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.Image.Format;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.Texture.MinFilter;
|
||||
import com.jme3.texture.Texture.Type;
|
||||
import com.jme3.texture.Texture.WrapMode;
|
||||
import com.jme3.util.BufferUtils;
|
||||
|
||||
public class MaterialHelper extends AbstractBlenderHelper {
|
||||
@ -204,125 +201,67 @@ public class MaterialHelper extends AbstractBlenderHelper {
|
||||
if(materialContext.textures.size() > 0) {
|
||||
LOGGER.log(Level.WARNING, "Attetion! Many textures found for material: {0}. Only the first of each supported mapping types will be used!", materialContext.name);
|
||||
}
|
||||
|
||||
DiffuseShader diffuseShader = this.getDiffuseShader(structure);
|
||||
ColorRGBA diffuseColor = this.getDiffuseColor(structure, diffuseShader);
|
||||
float[] diffuseColorArray = new float[] {diffuseColor.r, diffuseColor.g, diffuseColor.b};
|
||||
|
||||
// texture
|
||||
Type colorTextureType = null;
|
||||
Map<String, Texture> texturesMap = new HashMap<String, Texture>();
|
||||
Type firstTextureType = null;
|
||||
if ((blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0) {
|
||||
TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
|
||||
for (int i=0;i<materialContext.texturesCount;++i) {
|
||||
Structure mtex = materialContext.mTexs.get(i);
|
||||
|
||||
int texflag = ((Number) mtex.getFieldValue("texflag")).intValue();
|
||||
boolean negateTexture = (texflag & 0x04) == 0;
|
||||
|
||||
int mapto = ((Number) mtex.getFieldValue("mapto")).intValue();
|
||||
if (mapto != 0) {
|
||||
Structure tex = materialContext.textures.get(i);
|
||||
Texture texture = textureHelper.getTexture(tex, blenderContext);
|
||||
if (texture != null) {
|
||||
if(firstTextureType == null) {
|
||||
firstTextureType = texture.getType();
|
||||
} else if(firstTextureType != texture.getType()) {
|
||||
LOGGER.warning("The texture with the name: " + texture.getName() + " is of different type than the first applied texture! It will not be applied!");
|
||||
continue;
|
||||
}
|
||||
|
||||
// NOTE: Enable mipmaps FOR ALL TEXTURES EVER
|
||||
texture.setMinFilter(MinFilter.Trilinear);
|
||||
|
||||
if ((mapto & 0x01) != 0) {// Col
|
||||
mapto &= 0xFFFFFFFE;//this is temporary to force loading of one texture of a mapping type (will be removed when textures merging is created)
|
||||
// Map to COLOR channel or DIFFUSE
|
||||
// Set diffuse to white so it doesn't get multiplied by texture
|
||||
// result.setColor(shadeless ? "Color" : "Diffuse", ColorRGBA.White.clone());
|
||||
// result.setBoolean("UseMaterialColors", Boolean.FALSE);
|
||||
// blending the texture with material color and texture's defined color
|
||||
int blendType = ((Number) mtex.getFieldValue("blendtype")).intValue();
|
||||
float[] color = new float[] { ((Number) mtex.getFieldValue("r")).floatValue(), ((Number) mtex.getFieldValue("g")).floatValue(), ((Number) mtex.getFieldValue("b")).floatValue() };
|
||||
float colfac = ((Number) mtex.getFieldValue("colfac")).floatValue();
|
||||
texture = textureHelper.blendTexture(diffuseColorArray, texture, color, colfac, blendType, negateTexture, blenderContext);
|
||||
texture.setWrap(WrapMode.Repeat);
|
||||
//TODO: textures merging
|
||||
if (materialContext.shadeless) {
|
||||
texturesMap.put(firstTextureType==Type.ThreeDimensional ? TEXTURE_TYPE_3D : TEXTURE_TYPE_COLOR, texture);
|
||||
} else {
|
||||
texturesMap.put(firstTextureType==Type.ThreeDimensional ? TEXTURE_TYPE_3D : TEXTURE_TYPE_DIFFUSE, texture);
|
||||
}
|
||||
}
|
||||
if(firstTextureType == Type.TwoDimensional) {//for now other mappings available for images only
|
||||
if ((mapto & 0x02) != 0 && !materialContext.shadeless) {// Nor
|
||||
mapto &= 0xFFFFFFFD;//this is temporary to force loading of one texture of a mapping type (will be removed when textures merging is created)
|
||||
Texture normalMapTexture;
|
||||
if (texture.getKey() instanceof GeneratedTextureKey) {
|
||||
normalMapTexture = textureHelper.convertToNormalMapTexture(texture, ((Number) mtex.getFieldValue("norfac")).floatValue());
|
||||
normalMapTexture.setMinFilter(MinFilter.Trilinear);
|
||||
} else {
|
||||
normalMapTexture = texture;
|
||||
}
|
||||
texturesMap.put(TEXTURE_TYPE_NORMAL, normalMapTexture);
|
||||
}
|
||||
if ((mapto & 0x04) != 0 && !materialContext.shadeless) {// Spec
|
||||
mapto &= 0xFFFFFFFB;//this is temporary to force loading of one texture of a mapping type (will be removed when textures merging is created)
|
||||
// Map to SPECULAR
|
||||
texturesMap.put(TEXTURE_TYPE_SPECULAR, texture);
|
||||
}
|
||||
if ((mapto & 0x40) != 0) {// Emit
|
||||
mapto &= 0xFFFFFFF8;//this is temporary to force loading of one texture of a mapping type (will be removed when textures merging is created)
|
||||
texturesMap.put(TEXTURE_TYPE_GLOW, texture);
|
||||
}
|
||||
if ((mapto & 0x80) != 0 && !materialContext.shadeless) {// Alpha
|
||||
mapto &= 0xFFFFFF7F;//this is temporary to force loading of one texture of a mapping type (will be removed when textures merging is created)
|
||||
texturesMap.put(TEXTURE_TYPE_ALPHA, texture);
|
||||
}
|
||||
} else {
|
||||
LOGGER.warning("The following mappings: [Nor, Spec, Alpha] are available for 2D textures only!");
|
||||
}
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, "Texture not found!");
|
||||
}
|
||||
TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
|
||||
for(Entry<Number, Texture> textureEntry : materialContext.loadedTextures.entrySet()) {
|
||||
int mapto = textureEntry.getKey().intValue();
|
||||
Texture texture = textureEntry.getValue();
|
||||
if ((mapto & MaterialContext.MTEX_COL) != 0) {
|
||||
colorTextureType = texture.getType();
|
||||
if (materialContext.shadeless) {
|
||||
texturesMap.put(colorTextureType==Type.ThreeDimensional ? TEXTURE_TYPE_3D : TEXTURE_TYPE_COLOR, texture);
|
||||
} else {
|
||||
texturesMap.put(colorTextureType==Type.ThreeDimensional ? TEXTURE_TYPE_3D : TEXTURE_TYPE_DIFFUSE, texture);
|
||||
}
|
||||
}
|
||||
if(texture.getType()==Type.TwoDimensional) {//so far only 2D textures can be mapped in other way than color
|
||||
if ((mapto & MaterialContext.MTEX_NOR) != 0 && !materialContext.shadeless) {
|
||||
Structure mTex = materialContext.getMTex(texture);
|
||||
Texture normalMapTexture = textureHelper.convertToNormalMapTexture(texture, ((Number) mTex.getFieldValue("norfac")).floatValue());
|
||||
texturesMap.put(TEXTURE_TYPE_NORMAL, normalMapTexture);
|
||||
}
|
||||
if ((mapto & MaterialContext.MTEX_EMIT) != 0) {
|
||||
texturesMap.put(TEXTURE_TYPE_GLOW, texture);
|
||||
}
|
||||
if ((mapto & MaterialContext.MTEX_SPEC) != 0 && !materialContext.shadeless) {
|
||||
texturesMap.put(TEXTURE_TYPE_SPECULAR, texture);
|
||||
}
|
||||
if ((mapto & MaterialContext.MTEX_ALPHA) != 0 && !materialContext.shadeless) {
|
||||
texturesMap.put(TEXTURE_TYPE_ALPHA, texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//creating the material
|
||||
if(firstTextureType==Type.ThreeDimensional) {
|
||||
if(colorTextureType==Type.ThreeDimensional) {
|
||||
result = new Material(blenderContext.getAssetManager(), "jme3test/texture/tex3D.j3md");
|
||||
} else {
|
||||
if (materialContext.shadeless) {
|
||||
result = new Material(blenderContext.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
} else {
|
||||
result = new Material(blenderContext.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
|
||||
result.setBoolean("UseMaterialColors", Boolean.TRUE);
|
||||
|
||||
// setting the colors
|
||||
result.setBoolean("Minnaert", materialContext.diffuseShader == DiffuseShader.MINNAERT);
|
||||
if (!materialContext.transparent) {
|
||||
materialContext.diffuseColor.a = 1;
|
||||
}
|
||||
result.setColor("Diffuse", materialContext.diffuseColor);
|
||||
|
||||
result.setBoolean("WardIso", materialContext.specularShader == SpecularShader.WARDISO);
|
||||
result.setColor("Specular", materialContext.specularColor);
|
||||
|
||||
result.setColor("Ambient", materialContext.ambientColor);
|
||||
result.setFloat("Shininess", materialContext.shininess);
|
||||
}
|
||||
|
||||
if (materialContext.vertexColor) {
|
||||
result.setBoolean(materialContext.shadeless ? "VertexColor" : "UseVertexColor", true);
|
||||
}
|
||||
|
||||
if (materialContext.shadeless) {
|
||||
// color of shadeless? doesn't seem to work in blender ..
|
||||
diffuseColor = ColorRGBA.White.clone();
|
||||
} else {
|
||||
result.setBoolean("UseMaterialColors", Boolean.TRUE);
|
||||
|
||||
// setting the colors
|
||||
result.setBoolean("Minnaert", diffuseShader == DiffuseShader.MINNAERT);
|
||||
if (!materialContext.transparent) {
|
||||
diffuseColor.a = 1;
|
||||
}
|
||||
result.setColor("Diffuse", diffuseColor);
|
||||
|
||||
SpecularShader specularShader = this.getSpecularShader(structure);
|
||||
result.setBoolean("WardIso", specularShader == SpecularShader.WARDISO);
|
||||
result.setColor("Specular", this.getSpecularColor(structure, specularShader));
|
||||
|
||||
result.setColor("Ambient", this.getAmbientColor(structure));
|
||||
result.setFloat("Shininess", this.getShininess(structure));
|
||||
}
|
||||
}
|
||||
|
||||
//applying textures
|
||||
@ -487,125 +426,6 @@ public class MaterialHelper extends AbstractBlenderHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the diffuse color
|
||||
*
|
||||
* @param materialStructure
|
||||
* @param diffuseShader
|
||||
* @return
|
||||
*/
|
||||
public ColorRGBA getDiffuseColor(Structure materialStructure, DiffuseShader diffuseShader) {
|
||||
// bitwise 'or' of all textures mappings
|
||||
int commonMapto = ((Number) materialStructure.getFieldValue("mapto")).intValue();
|
||||
|
||||
// diffuse color
|
||||
float r = ((Number) materialStructure.getFieldValue("r")).floatValue();
|
||||
float g = ((Number) materialStructure.getFieldValue("g")).floatValue();
|
||||
float b = ((Number) materialStructure.getFieldValue("b")).floatValue();
|
||||
float alpha = ((Number) materialStructure.getFieldValue("alpha")).floatValue();
|
||||
if ((commonMapto & 0x01) == 0x01) {// Col
|
||||
return new ColorRGBA(r, g, b, alpha);
|
||||
} else {
|
||||
switch (diffuseShader) {
|
||||
case FRESNEL:
|
||||
case ORENNAYAR:
|
||||
case TOON:
|
||||
break;// TODO: find what is the proper modification
|
||||
case MINNAERT:
|
||||
case LAMBERT:// TODO: check if that is correct
|
||||
float ref = ((Number) materialStructure.getFieldValue("ref")).floatValue();
|
||||
r *= ref;
|
||||
g *= ref;
|
||||
b *= ref;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown diffuse shader type: " + diffuseShader.toString());
|
||||
}
|
||||
return new ColorRGBA(r, g, b, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an enum describing the type of a diffuse shader used by this material.
|
||||
*
|
||||
* @param materialStructure
|
||||
* the material structure filled with data
|
||||
* @return an enum describing the type of a diffuse shader used by this material
|
||||
*/
|
||||
public DiffuseShader getDiffuseShader(Structure materialStructure) {
|
||||
int diff_shader = ((Number) materialStructure.getFieldValue("diff_shader")).intValue();
|
||||
return DiffuseShader.values()[diff_shader];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an ambient color used by the material.
|
||||
*
|
||||
* @param materialStructure
|
||||
* the material structure filled with data
|
||||
* @return an ambient color used by the material
|
||||
*/
|
||||
public ColorRGBA getAmbientColor(Structure materialStructure) {
|
||||
float r = ((Number) materialStructure.getFieldValue("ambr")).floatValue();
|
||||
float g = ((Number) materialStructure.getFieldValue("ambg")).floatValue();
|
||||
float b = ((Number) materialStructure.getFieldValue("ambb")).floatValue();
|
||||
float alpha = ((Number) materialStructure.getFieldValue("alpha")).floatValue();
|
||||
return new ColorRGBA(r, g, b, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an enum describing the type of a specular shader used by this material.
|
||||
*
|
||||
* @param materialStructure
|
||||
* the material structure filled with data
|
||||
* @return an enum describing the type of a specular shader used by this material
|
||||
*/
|
||||
public SpecularShader getSpecularShader(Structure materialStructure) {
|
||||
int spec_shader = ((Number) materialStructure.getFieldValue("spec_shader")).intValue();
|
||||
return SpecularShader.values()[spec_shader];
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a specular color used by the material.
|
||||
*
|
||||
* @param materialStructure
|
||||
* the material structure filled with data
|
||||
* @return a specular color used by the material
|
||||
*/
|
||||
public ColorRGBA getSpecularColor(Structure materialStructure, SpecularShader specularShader) {
|
||||
float r = ((Number) materialStructure.getFieldValue("specr")).floatValue();
|
||||
float g = ((Number) materialStructure.getFieldValue("specg")).floatValue();
|
||||
float b = ((Number) materialStructure.getFieldValue("specb")).floatValue();
|
||||
float alpha = ((Number) materialStructure.getFieldValue("alpha")).floatValue();
|
||||
switch (specularShader) {
|
||||
case BLINN:
|
||||
case COOKTORRENCE:
|
||||
case TOON:
|
||||
case WARDISO:// TODO: find what is the proper modification
|
||||
break;
|
||||
case PHONG:// TODO: check if that is correct
|
||||
float spec = ((Number) materialStructure.getFieldValue("spec")).floatValue();
|
||||
r *= spec * 0.5f;
|
||||
g *= spec * 0.5f;
|
||||
b *= spec * 0.5f;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Unknown specular shader type: " + specularShader.toString());
|
||||
}
|
||||
return new ColorRGBA(r, g, b, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the sihiness of this material or DEFAULT_SHININESS value if not present.
|
||||
*
|
||||
* @param materialStructure
|
||||
* the material structure filled with data
|
||||
* @return the sihiness of this material or DEFAULT_SHININESS value if not present
|
||||
*/
|
||||
public float getShininess(Structure materialStructure) {
|
||||
float shininess = ((Number) materialStructure.getFieldValue("emit")).floatValue();
|
||||
return shininess > 0.0f ? shininess : DEFAULT_SHININESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the table of materials connected to the specified structure. The given structure can be of any type (ie. mesh or
|
||||
* curve) but needs to have 'mat' field/
|
||||
|
@ -278,7 +278,7 @@ import com.jme3.texture.Texture;
|
||||
* @param tex texture structure
|
||||
* @param texres
|
||||
*/
|
||||
protected void applyBrightnessAndContrast(BrightnessAndContrastData bacd, TextureResult texres) {
|
||||
protected void applyBrightnessAndContrast(BrightnessAndContrastData bacd, TexturePixel texres) {
|
||||
texres.red = (texres.red - 0.5f) * bacd.contrast + bacd.brightness;
|
||||
if (texres.red < 0.0f) {
|
||||
texres.red = 0.0f;
|
||||
@ -299,7 +299,7 @@ import com.jme3.texture.Texture;
|
||||
* @param contrast
|
||||
* @param brightness
|
||||
*/
|
||||
protected void applyBrightnessAndContrast(TextureResult texres, float contrast, float brightness) {
|
||||
protected void applyBrightnessAndContrast(TexturePixel texres, float contrast, float brightness) {
|
||||
texres.intensity = (texres.intensity - 0.5f) * contrast + brightness;
|
||||
if (texres.intensity < 0.0f) {
|
||||
texres.intensity = 0.0f;
|
||||
@ -308,20 +308,6 @@ import com.jme3.texture.Texture;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The result pixel of generated texture computations;
|
||||
*
|
||||
* @author Marcin Roguski (Kaelthas)
|
||||
*/
|
||||
protected static class TextureResult implements Cloneable {
|
||||
public float intensity, red, green, blue, alpha;
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class constaining the colorband data.
|
||||
*
|
||||
|
@ -118,13 +118,13 @@ public final class TextureGeneratorBlend extends TextureGenerator {
|
||||
protected Texture generate(Structure tex, int width, int height, int depth, BlenderContext blenderContext) {
|
||||
int flag = ((Number) tex.getFieldValue("flag")).intValue();
|
||||
int stype = ((Number) tex.getFieldValue("stype")).intValue();
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
|
||||
float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD, x, y;
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
|
||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||
Format format = colorBand != null ? Format.RGBA8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 4 : 1;
|
||||
boolean flipped = (flag & NoiseGenerator.TEX_FLIPBLEND) != 0;
|
||||
|
||||
byte[] data = new byte[width * height * depth * bytesPerPixel];
|
||||
@ -150,6 +150,7 @@ public final class TextureGeneratorBlend extends TextureGenerator {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (colorBand[colorbandIndex][3] * 255.0f);
|
||||
} else {
|
||||
this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
|
||||
data[index++] = (byte) (texres.intensity * 255.0f);
|
||||
|
@ -68,7 +68,7 @@ public class TextureGeneratorClouds extends TextureGenerator {
|
||||
@Override
|
||||
protected Texture generate(Structure tex, int width, int height, int depth, BlenderContext blenderContext) {
|
||||
float[] texvec = new float[] { 0, 0, 0 };
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
|
||||
// reading the data from the texture structure
|
||||
float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
|
||||
@ -80,8 +80,8 @@ public class TextureGeneratorClouds extends TextureGenerator {
|
||||
int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
|
||||
float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
Format format = sType == TEX_COLOR || colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||
int bytesPerPixel = sType == TEX_COLOR || colorBand != null ? 3 : 1;
|
||||
Format format = sType == TEX_COLOR || colorBand != null ? Format.RGBA8 : Format.Luminance8;
|
||||
int bytesPerPixel = sType == TEX_COLOR || colorBand != null ? 4 : 1;
|
||||
BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
|
||||
|
||||
byte[] data = new byte[width * height * depth * bytesPerPixel];
|
||||
@ -103,6 +103,7 @@ public class TextureGeneratorClouds extends TextureGenerator {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (colorBand[colorbandIndex][3] * 255.0f);
|
||||
} else if (sType == TEX_COLOR) {
|
||||
texres.red = texres.intensity;
|
||||
texres.green = NoiseGenerator.NoiseFunctions.turbulence(texvec[1], texvec[0], texvec[2], noisesize, noiseDepth, noiseBasis, isHard);
|
||||
@ -115,6 +116,7 @@ public class TextureGeneratorClouds extends TextureGenerator {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (255);//1.0f * 255.0f
|
||||
} else {
|
||||
this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
|
||||
data[index++] = (byte) (texres.intensity * 255.0f);
|
||||
|
@ -34,6 +34,7 @@ package com.jme3.scene.plugins.blender.textures;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.scene.plugins.blender.BlenderContext;
|
||||
import com.jme3.scene.plugins.blender.file.Structure;
|
||||
import com.jme3.scene.plugins.blender.textures.NoiseGenerator.NoiseFunction;
|
||||
@ -65,13 +66,13 @@ public class TextureGeneratorDistnoise extends TextureGenerator {
|
||||
int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue();
|
||||
int noisebasis2 = ((Number) tex.getFieldValue("noisebasis2")).intValue();
|
||||
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
float[] texvec = new float[] { 0, 0, 0 };
|
||||
int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
|
||||
float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||
Format format = colorBand != null ? Format.RGBA8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 4 : 1;
|
||||
BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
|
||||
|
||||
byte[] data = new byte[width * height * depth * bytesPerPixel];
|
||||
@ -82,6 +83,7 @@ public class TextureGeneratorDistnoise extends TextureGenerator {
|
||||
for (int k = -halfD; k < halfD; ++k) {
|
||||
texvec[2] = dDelta * k;
|
||||
texres.intensity = this.musgraveVariableLunacrityNoise(texvec[0], texvec[1], texvec[2], distAmount, noisebasis, noisebasis2);
|
||||
texres.intensity = FastMath.clamp(texres.intensity, 0.0f, 1.0f);
|
||||
if (colorBand != null) {
|
||||
int colorbandIndex = (int) (texres.intensity * 1000.0f);
|
||||
texres.red = colorBand[colorbandIndex][0];
|
||||
@ -92,6 +94,7 @@ public class TextureGeneratorDistnoise extends TextureGenerator {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (colorBand[colorbandIndex][3] * 255.0f);
|
||||
} else {
|
||||
this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
|
||||
data[index++] = (byte) (texres.intensity * 255.0f);
|
||||
|
@ -34,6 +34,7 @@ package com.jme3.scene.plugins.blender.textures;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.scene.plugins.blender.BlenderContext;
|
||||
import com.jme3.scene.plugins.blender.file.Structure;
|
||||
import com.jme3.texture.Image;
|
||||
@ -126,13 +127,13 @@ public class TextureGeneratorMagic extends TextureGenerator {
|
||||
int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
|
||||
float turbul = ((Number) tex.getFieldValue("turbul")).floatValue() / 5.0f;
|
||||
float[] texvec = new float[] { 0, 0, 0 };
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
|
||||
float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
|
||||
|
||||
byte[] data = new byte[width * height * depth * 3];
|
||||
byte[] data = new byte[width * height * depth * 4];
|
||||
for (int i = -halfW; i < halfW; ++i) {
|
||||
texvec[0] = wDelta * i;
|
||||
for (int j = -halfH; j < halfH; ++j) {
|
||||
@ -145,11 +146,12 @@ public class TextureGeneratorMagic extends TextureGenerator {
|
||||
xyz[2] = -(float) Math.cos((-texvec[0] - texvec[1] + texvec[2]) * 5.0f);
|
||||
|
||||
if (colorBand != null) {
|
||||
texres.intensity = 0.3333f * (xyz[0] + xyz[1] + xyz[2]);
|
||||
texres.intensity = FastMath.clamp(0.3333f * (xyz[0] + xyz[1] + xyz[2]), 0.0f, 1.0f);
|
||||
int colorbandIndex = (int) (texres.intensity * 1000.0f);
|
||||
texres.red = colorBand[colorbandIndex][0];
|
||||
texres.green = colorBand[colorbandIndex][1];
|
||||
texres.blue = colorBand[colorbandIndex][2];
|
||||
texres.alpha = colorBand[colorbandIndex][3];
|
||||
} else {
|
||||
if (noisedepth > 0) {
|
||||
xyz[0] *= turb;
|
||||
@ -169,17 +171,19 @@ public class TextureGeneratorMagic extends TextureGenerator {
|
||||
texres.red = 0.5f - xyz[0];
|
||||
texres.green = 0.5f - xyz[1];
|
||||
texres.blue = 0.5f - xyz[2];
|
||||
texres.alpha = 1.0f;
|
||||
}
|
||||
this.applyBrightnessAndContrast(bacd, texres);
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (texres.alpha * 255.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(BufferUtils.createByteBuffer(data));
|
||||
return new Texture3D(new Image(Format.RGB8, width, height, depth, dataArray));
|
||||
return new Texture3D(new Image(Format.RGBA8, width, height, depth, dataArray));
|
||||
}
|
||||
|
||||
private static interface NoiseDepthFunction {
|
||||
|
@ -64,12 +64,12 @@ public class TextureGeneratorMarble extends TextureGeneratorWood {
|
||||
@Override
|
||||
protected Texture generate(Structure tex, int width, int height, int depth, BlenderContext blenderContext) {
|
||||
float[] texvec = new float[] { 0, 0, 0 };
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
|
||||
float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||
Format format = colorBand != null ? Format.RGBA8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 4 : 1;
|
||||
BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
|
||||
MarbleData marbleData = new MarbleData(tex);
|
||||
|
||||
@ -91,6 +91,7 @@ public class TextureGeneratorMarble extends TextureGeneratorWood {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (colorBand[colorbandIndex][3] * 255.0f);
|
||||
} else {
|
||||
this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
|
||||
data[index++] = (byte) (texres.intensity * 255.0f);
|
||||
|
@ -62,13 +62,13 @@ public class TextureGeneratorMusgrave extends TextureGenerator {
|
||||
protected Texture generate(Structure tex, int width, int height, int depth, BlenderContext blenderContext) {
|
||||
int stype = ((Number) tex.getFieldValue("stype")).intValue();
|
||||
float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
float[] texvec = new float[] { 0, 0, 0 };
|
||||
int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
|
||||
float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||
Format format = colorBand != null ? Format.RGBA8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 4 : 1;
|
||||
MusgraveData musgraveData = new MusgraveData(tex);
|
||||
MusgraveFunction musgraveFunction;
|
||||
BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
|
||||
@ -101,6 +101,7 @@ public class TextureGeneratorMusgrave extends TextureGenerator {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (colorBand[colorbandIndex][3] * 255.0f);
|
||||
} else {
|
||||
this.applyBrightnessAndContrast(bacd, texres);
|
||||
data[index++] = (byte) (texres.intensity * 255.0f);
|
||||
|
@ -62,11 +62,11 @@ public class TextureGeneratorNoise extends TextureGenerator {
|
||||
protected Texture generate(Structure tex, int width, int height, int depth, BlenderContext blenderContext) {
|
||||
int val, random, loop;
|
||||
int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue();
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||
Format format = colorBand != null ? Format.RGBA8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 4 : 1;
|
||||
BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
|
||||
|
||||
byte[] data = new byte[width * height * depth * bytesPerPixel];
|
||||
@ -81,7 +81,7 @@ public class TextureGeneratorNoise extends TextureGenerator {
|
||||
random >>= 2;
|
||||
val *= random & 3;
|
||||
}
|
||||
texres.intensity = val;
|
||||
texres.intensity = FastMath.clamp(val, 0.0f, 1.0f);
|
||||
if (colorBand != null) {
|
||||
int colorbandIndex = (int) (texres.intensity * 1000.0f);
|
||||
texres.red = colorBand[colorbandIndex][0];
|
||||
@ -92,6 +92,7 @@ public class TextureGeneratorNoise extends TextureGenerator {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (colorBand[colorbandIndex][3] * 255.0f);
|
||||
} else {
|
||||
this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
|
||||
data[index++] = (byte) (texres.intensity * 255.0f);
|
||||
|
@ -72,12 +72,12 @@ public class TextureGeneratorStucci extends TextureGenerator {
|
||||
}
|
||||
|
||||
float[] texvec = new float[] { 0, 0, 0 };
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
|
||||
float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD, noiseValue, ofs;;
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||
Format format = colorBand != null ? Format.RGBA8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 4 : 1;
|
||||
|
||||
byte[] data = new byte[width * height * depth * bytesPerPixel];
|
||||
for (int i = -halfW; i < halfW; ++i) {
|
||||
@ -98,6 +98,7 @@ public class TextureGeneratorStucci extends TextureGenerator {
|
||||
texres.red = colorBand[colorbandIndex][0];
|
||||
texres.green = colorBand[colorbandIndex][1];
|
||||
texres.blue = colorBand[colorbandIndex][2];
|
||||
texres.alpha = colorBand[colorbandIndex][3];
|
||||
}
|
||||
|
||||
if (stype == NoiseGenerator.TEX_WALLOUT) {
|
||||
@ -111,6 +112,7 @@ public class TextureGeneratorStucci extends TextureGenerator {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (texres.alpha * 255.0f);
|
||||
} else {
|
||||
data[index++] = (byte) (texres.intensity * 255.0f);
|
||||
}
|
||||
|
@ -71,14 +71,14 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
|
||||
int distm = ((Number) tex.getFieldValue("vn_distm")).intValue();
|
||||
int voronoiColorType = ((Number) tex.getFieldValue("vn_coltype")).intValue();
|
||||
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
float[] texvec = new float[] { 0, 0, 0 };
|
||||
int halfW = width >> 1, halfH = height >> 1, halfD = depth >> 1, index = 0;
|
||||
float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
|
||||
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
Format format = voronoiColorType != 0 || colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||
int bytesPerPixel = voronoiColorType != 0 || colorBand != null ? 3 : 1;
|
||||
Format format = voronoiColorType != 0 || colorBand != null ? Format.RGBA8 : Format.Luminance8;
|
||||
int bytesPerPixel = voronoiColorType != 0 || colorBand != null ? 4 : 1;
|
||||
BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
|
||||
|
||||
float[] da = new float[4], pa = new float[12];
|
||||
@ -111,8 +111,10 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
|
||||
texres.red = colorBand[colorbandIndex][0];
|
||||
texres.green = colorBand[colorbandIndex][1];
|
||||
texres.blue = colorBand[colorbandIndex][2];
|
||||
texres.alpha = colorBand[colorbandIndex][3];
|
||||
} else if (voronoiColorType != 0) {
|
||||
texres.red = texres.green = texres.blue = 0.0f;
|
||||
texres.alpha = 1.0f;
|
||||
for(int m=0; m<12; m+=3) {
|
||||
weight = voronoiWeights[m/3];
|
||||
this.cellNoiseV(pa[m], pa[m + 1], pa[m + 2], hashPoint);
|
||||
@ -145,6 +147,7 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (texres.alpha * 255.0f);
|
||||
} else {
|
||||
this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
|
||||
data[index++] = (byte) (texres.intensity * 255.0f);
|
||||
|
@ -73,15 +73,15 @@ public class TextureGeneratorWood extends TextureGenerator {
|
||||
@Override
|
||||
protected Texture generate(Structure tex, int width, int height, int depth, BlenderContext blenderContext) {
|
||||
float[] texvec = new float[] { 0, 0, 0 };
|
||||
TextureResult texres = new TextureResult();
|
||||
TexturePixel texres = new TexturePixel();
|
||||
int halfW = width >> 1;
|
||||
int halfH = height >> 1;
|
||||
int halfD = depth >> 1;
|
||||
float wDelta = 1.0f / halfW, hDelta = 1.0f / halfH, dDelta = 1.0f / halfD;
|
||||
|
||||
float[][] colorBand = this.computeColorband(tex, blenderContext);
|
||||
Format format = colorBand != null ? Format.RGB8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 3 : 1;
|
||||
Format format = colorBand != null ? Format.RGBA8 : Format.Luminance8;
|
||||
int bytesPerPixel = colorBand != null ? 4 : 1;
|
||||
WoodIntensityData woodIntensityData = new WoodIntensityData(tex);
|
||||
BrightnessAndContrastData bacd = new BrightnessAndContrastData(tex);
|
||||
|
||||
@ -106,6 +106,7 @@ public class TextureGeneratorWood extends TextureGenerator {
|
||||
data[index++] = (byte) (texres.red * 255.0f);
|
||||
data[index++] = (byte) (texres.green * 255.0f);
|
||||
data[index++] = (byte) (texres.blue * 255.0f);
|
||||
data[index++] = (byte) (colorBand[colorbandIndex][3] * 255.0f);
|
||||
} else {
|
||||
this.applyBrightnessAndContrast(texres, bacd.contrast, bacd.brightness);
|
||||
data[index++] = (byte) (texres.intensity * 255.0f);
|
||||
|
@ -50,6 +50,7 @@ import com.jme3.asset.BlenderKey;
|
||||
import com.jme3.asset.BlenderKey.FeaturesToLoad;
|
||||
import com.jme3.asset.GeneratedTextureKey;
|
||||
import com.jme3.asset.TextureKey;
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.math.FastMath;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
|
||||
@ -59,10 +60,12 @@ import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
|
||||
import com.jme3.scene.plugins.blender.file.FileBlockHeader;
|
||||
import com.jme3.scene.plugins.blender.file.Pointer;
|
||||
import com.jme3.scene.plugins.blender.file.Structure;
|
||||
import com.jme3.scene.plugins.blender.materials.MaterialContext;
|
||||
import com.jme3.scene.plugins.blender.materials.MaterialHelper;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.Image.Format;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.Texture.MinFilter;
|
||||
import com.jme3.texture.Texture.WrapMode;
|
||||
import com.jme3.texture.Texture2D;
|
||||
import com.jme3.texture.Texture3D;
|
||||
@ -215,6 +218,8 @@ public class TextureHelper extends AbstractBlenderHelper {
|
||||
if (result != null) {
|
||||
result.setName(tex.getName());
|
||||
result.setWrap(WrapMode.Repeat);
|
||||
// NOTE: Enable mipmaps FOR ALL TEXTURES EVER
|
||||
result.setMinFilter(MinFilter.Trilinear);
|
||||
if(type != TEX_IMAGE) {//only generated textures should have this key
|
||||
result.setKey(new GeneratedTextureKey(tex.getName()));
|
||||
}
|
||||
@ -261,7 +266,7 @@ public class TextureHelper extends AbstractBlenderHelper {
|
||||
newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f));
|
||||
newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f));
|
||||
newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f));
|
||||
newData.put(dataIndex++, (byte) 255.0f);//1.0f * 255.0f
|
||||
newData.put(dataIndex++, (byte) (materialColorClone[3] * 255.0f));
|
||||
}
|
||||
if(texture.getType()==Texture.Type.TwoDimensional) {
|
||||
return new Texture2D(new Image(Format.RGBA8, width, height, newData));
|
||||
@ -272,6 +277,78 @@ public class TextureHelper extends AbstractBlenderHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method merges the given textures. The result texture has no alpha
|
||||
* factor (is always opaque).
|
||||
*
|
||||
* @param sources
|
||||
* the textures to be merged
|
||||
* @param materialContext
|
||||
* the context of the material
|
||||
* @return merged textures
|
||||
*/
|
||||
public Texture mergeTextures(List<Texture> sources, MaterialContext materialContext) {
|
||||
Texture result = null;
|
||||
if(sources!=null && sources.size()>0) {
|
||||
//checking the sizes of the textures (tehy should perfectly match)
|
||||
int lastTextureWithoutAlphaIndex = 0;
|
||||
int width = sources.get(0).getImage().getWidth();
|
||||
int height = sources.get(0).getImage().getHeight();
|
||||
int depth = sources.get(0).getImage().getDepth();
|
||||
|
||||
for(Texture source : sources) {
|
||||
if(source.getImage().getWidth() != width) {
|
||||
throw new IllegalArgumentException("The texture " + source.getName() + " has invalid width! It should be: " + width + '!');
|
||||
}
|
||||
if(source.getImage().getHeight() != height) {
|
||||
throw new IllegalArgumentException("The texture " + source.getName() + " has invalid height! It should be: " + height + '!');
|
||||
}
|
||||
if(source.getImage().getDepth() != depth) {
|
||||
throw new IllegalArgumentException("The texture " + source.getName() + " has invalid depth! It should be: " + depth + '!');
|
||||
}
|
||||
//support for more formats is not necessary at the moment
|
||||
if(source.getImage().getFormat()!=Format.RGB8 && source.getImage().getFormat()!=Format.BGR8) {
|
||||
++lastTextureWithoutAlphaIndex;
|
||||
}
|
||||
}
|
||||
|
||||
//remove textures before the one without alpha (they will be covered anyway)
|
||||
if(lastTextureWithoutAlphaIndex > 0 && lastTextureWithoutAlphaIndex<sources.size()-1) {
|
||||
sources = sources.subList(lastTextureWithoutAlphaIndex, sources.size()-1);
|
||||
}
|
||||
int pixelsAmount = width * height * depth;
|
||||
|
||||
ByteBuffer data = BufferUtils.createByteBuffer(pixelsAmount * 3);
|
||||
TexturePixel resultPixel = new TexturePixel();
|
||||
TexturePixel sourcePixel = new TexturePixel();
|
||||
ColorRGBA diffuseColor = materialContext.getDiffuseColor();
|
||||
for (int i = 0; i < pixelsAmount; ++i) {
|
||||
for (int j = 0; j < sources.size(); ++j) {
|
||||
Image image = sources.get(j).getImage();
|
||||
ByteBuffer sourceData = image.getData(0);
|
||||
if(j==0) {
|
||||
resultPixel.fromColor(diffuseColor);
|
||||
sourcePixel.fromImage(image.getFormat(), sourceData, i);
|
||||
resultPixel.merge(sourcePixel);
|
||||
} else {
|
||||
sourcePixel.fromImage(image.getFormat(), sourceData, i);
|
||||
resultPixel.merge(sourcePixel);
|
||||
}
|
||||
}
|
||||
data.put((byte)(255 * resultPixel.red));
|
||||
data.put((byte)(255 * resultPixel.green));
|
||||
data.put((byte)(255 * resultPixel.blue));
|
||||
resultPixel.clear();
|
||||
}
|
||||
|
||||
ArrayList<ByteBuffer> arrayData = new ArrayList<ByteBuffer>(1);
|
||||
arrayData.add(data);
|
||||
//TODO: add different texture types
|
||||
result = new Texture3D(new Image(Format.RGB8, width, height, depth, arrayData));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method alters the material color in a way dependent on the type of the image.
|
||||
* For example the color remains untouched if the texture is of Luminance type.
|
||||
@ -293,46 +370,52 @@ public class TextureHelper extends AbstractBlenderHelper {
|
||||
protected float setupMaterialColor(ByteBuffer data, Format imageFormat, boolean neg, float[] materialColor) {
|
||||
float tin = 0.0f;
|
||||
byte pixelValue = data.get();// at least one byte is always taken :)
|
||||
float firstPixelValue = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
float firstPixelValue = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
switch (imageFormat) {
|
||||
case ABGR8:
|
||||
pixelValue = data.get();
|
||||
materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
break;
|
||||
case BGR8:
|
||||
materialColor[2] = firstPixelValue;
|
||||
pixelValue = data.get();
|
||||
materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[0] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
break;
|
||||
case RGB8:
|
||||
materialColor[0] = firstPixelValue;
|
||||
pixelValue = data.get();
|
||||
materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
case Luminance8:
|
||||
tin = neg ? 1.0f - firstPixelValue : firstPixelValue;
|
||||
materialColor[3] = tin;
|
||||
neg = false;//do not negate the materialColor, it must be unchanged
|
||||
break;
|
||||
case RGBA8:
|
||||
materialColor[0] = firstPixelValue;
|
||||
pixelValue = data.get();
|
||||
materialColor[1] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
materialColor[1] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[2] = pixelValue >= 0 ? 1.0f - pixelValue / 255.0f : (~pixelValue + 1) / 255.0f;
|
||||
data.get(); // ignore alpha
|
||||
materialColor[2] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[3] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
break;
|
||||
case Luminance8:
|
||||
tin = neg ? 1.0f - firstPixelValue : firstPixelValue;
|
||||
neg = false;//do not negate the materialColor, it must be unchanged
|
||||
case ABGR8:
|
||||
materialColor[3] = firstPixelValue;
|
||||
pixelValue = data.get();
|
||||
materialColor[2] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[1] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[0] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
break;
|
||||
case BGR8:
|
||||
materialColor[2] = firstPixelValue;
|
||||
pixelValue = data.get();
|
||||
materialColor[1] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[0] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
materialColor[3] = 1.0f;
|
||||
break;
|
||||
case RGB8:
|
||||
materialColor[0] = firstPixelValue;
|
||||
pixelValue = data.get();
|
||||
materialColor[1] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get();
|
||||
materialColor[2] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
materialColor[3] = 1.0f;
|
||||
break;
|
||||
case Luminance8Alpha8:
|
||||
tin = neg ? 1.0f - firstPixelValue : firstPixelValue;
|
||||
neg = false;//do not negate the materialColor, it must be unchanged
|
||||
data.get(); // ignore alpha
|
||||
pixelValue = data.get(); // ignore alpha
|
||||
materialColor[3] = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
break;
|
||||
case Luminance16:
|
||||
case Luminance16Alpha16:
|
||||
|
@ -0,0 +1,95 @@
|
||||
package com.jme3.scene.plugins.blender.textures;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.jme3.math.ColorRGBA;
|
||||
import com.jme3.texture.Image.Format;
|
||||
|
||||
/*package*/ class TexturePixel implements Cloneable {
|
||||
private static final Logger LOGGER = Logger.getLogger(TexturePixel.class.getName());
|
||||
|
||||
public float intensity, red, green, blue, alpha;
|
||||
|
||||
public void fromColor(ColorRGBA colorRGBA) {
|
||||
this.intensity = 0;
|
||||
this.red = colorRGBA.r;
|
||||
this.green = colorRGBA.g;
|
||||
this.blue = colorRGBA.b;
|
||||
this.alpha = colorRGBA.a;
|
||||
}
|
||||
|
||||
public void fromImage(Format imageFormat, ByteBuffer data, int pixelIndex) {
|
||||
int firstByteIndex;
|
||||
byte pixelValue;
|
||||
switch(imageFormat) {
|
||||
case ABGR8:
|
||||
firstByteIndex = pixelIndex << 2;
|
||||
pixelValue = data.get(firstByteIndex);
|
||||
this.alpha = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 1);
|
||||
this.blue = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 2);
|
||||
this.green = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 3);
|
||||
this.red = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
break;
|
||||
case RGBA8:
|
||||
firstByteIndex = pixelIndex << 2;
|
||||
pixelValue = data.get(firstByteIndex);
|
||||
this.red = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 1);
|
||||
this.green = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 2);
|
||||
this.blue = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 3);
|
||||
this.alpha = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
break;
|
||||
case BGR8:
|
||||
firstByteIndex = pixelIndex * 3;
|
||||
pixelValue = data.get(firstByteIndex);
|
||||
this.blue = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 1);
|
||||
this.green = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 2);
|
||||
this.red = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
this.alpha = 1.0f;
|
||||
break;
|
||||
case RGB8:
|
||||
firstByteIndex = pixelIndex * 3;
|
||||
pixelValue = data.get(firstByteIndex);
|
||||
this.red = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 1);
|
||||
this.green = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
pixelValue = data.get(firstByteIndex + 2);
|
||||
this.blue = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
this.alpha = 1.0f;
|
||||
break;
|
||||
case Luminance8:
|
||||
pixelValue = data.get(pixelIndex);
|
||||
this.intensity = pixelValue >= 0 ? pixelValue / 255.0f : 1.0f - (~pixelValue) / 255.0f;
|
||||
break;
|
||||
default:
|
||||
LOGGER.log(Level.FINEST, "Unknown type of texture: {0}. Black pixel used!", imageFormat);
|
||||
this.intensity = this.blue = this.red = this.green = this.alpha = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public void merge(TexturePixel pixel) {
|
||||
float oneMinusAlpha = 1 - pixel.alpha;
|
||||
this.red = oneMinusAlpha * this.red + pixel.alpha*pixel.red;
|
||||
this.green = oneMinusAlpha * this.green + pixel.alpha*pixel.green;
|
||||
this.blue = oneMinusAlpha * this.blue + pixel.alpha*pixel.blue;
|
||||
//alpha should be always 1.0f as a result
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.intensity = this.blue = this.red = this.green = this.alpha = 0.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user