Support for UV-coordinates mapping (only for the first texture at the moment).
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8234 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
3383e2e086
commit
7c1c6dc065
engine/src/blender/com/jme3/scene/plugins/blender
materials
meshes
textures
@ -14,32 +14,32 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper;
|
||||
import com.jme3.texture.Texture.Type;
|
||||
|
||||
public final class MaterialContext {
|
||||
private static final Logger LOGGER = Logger.getLogger(MaterialContext.class.getName());
|
||||
|
||||
/*package*/ final String name;
|
||||
/*package*/ final List<Structure> mTexs;
|
||||
/*package*/ final List<Structure> textures;
|
||||
/*package*/ final int texturesCount;
|
||||
/*package*/ final Type textureType;
|
||||
|
||||
/*package*/ final boolean shadeless;
|
||||
/*package*/ final boolean vertexColor;
|
||||
/*package*/ final boolean transparent;
|
||||
/*package*/ final boolean vtangent;
|
||||
|
||||
/*package*/ int uvCoordinatesType = -1;
|
||||
/*package*/ int projectionType;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(MaterialContext.class.getName());
|
||||
|
||||
/* package */final String name;
|
||||
/* package */final List<Structure> mTexs;
|
||||
/* package */final List<Structure> textures;
|
||||
/* package */final int texturesCount;
|
||||
/* package */final Type textureType;
|
||||
|
||||
/* package */final boolean shadeless;
|
||||
/* package */final boolean vertexColor;
|
||||
/* package */final boolean transparent;
|
||||
/* package */final boolean vtangent;
|
||||
|
||||
/* package */int uvCoordinatesType = -1;
|
||||
/* package */int projectionType;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
/*package*/ MaterialContext(Structure structure, DataRepository dataRepository) throws BlenderFileException {
|
||||
/* package */MaterialContext(Structure structure, DataRepository dataRepository) throws BlenderFileException {
|
||||
name = structure.getName();
|
||||
|
||||
|
||||
int mode = ((Number) structure.getFieldValue("mode")).intValue();
|
||||
shadeless = (mode & 0x4) != 0;
|
||||
vertexColor = (mode & 0x80) != 0;
|
||||
transparent = (mode & 0x10000) != 0;
|
||||
vtangent = (mode & 0x4000000) != 0; // NOTE: Requires tangents
|
||||
|
||||
|
||||
mTexs = new ArrayList<Structure>();
|
||||
textures = new ArrayList<Structure>();
|
||||
DynamicArray<Pointer> mtexsArray = (DynamicArray<Pointer>) structure.getFieldValue("mtex");
|
||||
@ -49,41 +49,41 @@ public final class MaterialContext {
|
||||
Pointer p = mtexsArray.get(i);
|
||||
if (p.isNotNull() && (separatedTextures & 1 << i) == 0) {
|
||||
Structure mtex = p.fetchData(dataRepository.getInputStream()).get(0);
|
||||
|
||||
//the first texture determines the texture coordinates type
|
||||
if(uvCoordinatesType == -1) {
|
||||
|
||||
// the first texture determines the texture coordinates type
|
||||
if (uvCoordinatesType == -1) {
|
||||
uvCoordinatesType = ((Number) mtex.getFieldValue("texco")).intValue();
|
||||
projectionType = ((Number) mtex.getFieldValue("mapping")).intValue();
|
||||
} else if(uvCoordinatesType != ((Number) mtex.getFieldValue("texco")).intValue()) {
|
||||
LOGGER.log(Level.WARNING, "The texture with index: {0} has different UV coordinates type than the first texture! This texture will NOT be loaded!", i+1);
|
||||
} else if (uvCoordinatesType != ((Number) mtex.getFieldValue("texco")).intValue()) {
|
||||
LOGGER.log(Level.WARNING, "The texture with index: {0} has different UV coordinates type than the first texture! This texture will NOT be loaded!", i + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Pointer pTex = (Pointer) mtex.getFieldValue("tex");
|
||||
if(pTex.isNotNull()) {
|
||||
if (pTex.isNotNull()) {
|
||||
Structure tex = pTex.fetchData(dataRepository.getInputStream()).get(0);
|
||||
int type = ((Number) tex.getFieldValue("type")).intValue();
|
||||
Type textureType = this.getType(type);
|
||||
if(textureType != null) {
|
||||
if(firstTextureType == null) {
|
||||
if (textureType != null) {
|
||||
if (firstTextureType == null) {
|
||||
firstTextureType = textureType;
|
||||
mTexs.add(mtex);
|
||||
textures.add(tex);
|
||||
} else if(firstTextureType == textureType) {
|
||||
} else if (firstTextureType == textureType) {
|
||||
mTexs.add(mtex);
|
||||
textures.add(tex);
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, "The texture with index: {0} is of different dimension than the first one! This texture will NOT be loaded!", i+1);
|
||||
LOGGER.log(Level.WARNING, "The texture with index: {0} is of different dimension than the first one! This texture will NOT be loaded!", i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.texturesCount = mTexs.size();
|
||||
this.textureType = firstTextureType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the current material's texture UV coordinates type.
|
||||
* @return uv coordinates type
|
||||
@ -91,7 +91,7 @@ public final class MaterialContext {
|
||||
public int getUvCoordinatesType() {
|
||||
return uvCoordinatesType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the proper projection type for the material's texture.
|
||||
* This applies only to 2D textures.
|
||||
@ -108,7 +108,7 @@ public final class MaterialContext {
|
||||
public int getTextureDimension() {
|
||||
return this.textureType == Type.TwoDimensional ? 2 : 3;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the amount of textures applied for the current
|
||||
* material.
|
||||
@ -118,10 +118,26 @@ public final class MaterialContext {
|
||||
public int getTexturesCount() {
|
||||
return textures == null ? 0 : textures.size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the projection array that indicates where the current coordinate factor X, Y or Z (represented
|
||||
* by the index in the array) will be used where (indicated by the value in the array).
|
||||
* For example the configuration: [1,2,3] means that X - coordinate will be used as X, Y as Y and Z as Z.
|
||||
* The configuration [2,1,0] means that Z will be used instead of X coordinate, Y will be used as Y and
|
||||
* Z will not be used at all (0 will be in its place).
|
||||
* @param textureIndex
|
||||
* the index of the texture
|
||||
* @return texture projection array
|
||||
*/
|
||||
public int[] getProjection(int textureIndex) {
|
||||
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 determines the type of the texture.
|
||||
* @param texType texture type (from blender)
|
||||
* @param texType
|
||||
* texture type (from blender)
|
||||
* @return texture type (used by jme)
|
||||
*/
|
||||
private Type getType(int texType) {
|
||||
@ -142,7 +158,7 @@ public final class MaterialContext {
|
||||
case TextureHelper.TEX_NONE:// No texture, do nothing
|
||||
return null;
|
||||
case TextureHelper.TEX_POINTDENSITY:
|
||||
case TextureHelper.TEX_VOXELDATA:
|
||||
case TextureHelper.TEX_VOXELDATA:
|
||||
case TextureHelper.TEX_PLUGIN:
|
||||
case TextureHelper.TEX_ENVMAP:
|
||||
LOGGER.log(Level.WARNING, "Texture type NOT supported: {0}", texType);
|
||||
|
@ -200,6 +200,10 @@ public class MaterialHelper extends AbstractBlenderHelper {
|
||||
|
||||
MaterialContext materialContext = new MaterialContext(structure, dataRepository);
|
||||
LOGGER.log(Level.INFO, "Material's name: {0}", materialContext.name);
|
||||
|
||||
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);
|
||||
@ -232,6 +236,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
|
||||
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());
|
||||
@ -251,6 +256,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
|
||||
}
|
||||
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());
|
||||
@ -261,13 +267,16 @@ public class MaterialHelper extends AbstractBlenderHelper {
|
||||
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 {
|
||||
|
@ -408,8 +408,8 @@ public class MeshHelper extends AbstractBlenderHelper {
|
||||
MaterialContext materialContext = dataRepository.getMaterialContext(entry.getKey());
|
||||
if(materialContext != null && materialContext.getTexturesCount()>0) {
|
||||
UVCoordinatesGenerator.generateUVCoordinates(materialContext.getUvCoordinatesType(),
|
||||
materialContext.getProjectionType(),
|
||||
materialContext.getTextureDimension(), entry.getValue());
|
||||
materialContext.getProjectionType(), materialContext.getTextureDimension(),
|
||||
materialContext.getProjection(0), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,10 +90,12 @@ public class UVCoordinatesGenerator {
|
||||
* the projection type for 2D textures
|
||||
* @param textureDimension
|
||||
* the dimension of the texture (only 2D and 3D)
|
||||
* @param coordinatesSwappingIndexes
|
||||
* an array that tells how UV-coordinates need to be swapped
|
||||
* @param geometries
|
||||
* a list of geometries the UV coordinates will be applied to
|
||||
*/
|
||||
public static void generateUVCoordinates(int texco, int projection, int textureDimension, List<Geometry> geometries) {
|
||||
public static void generateUVCoordinates(int texco, int projection, int textureDimension, int[] coordinatesSwappingIndexes, List<Geometry> geometries) {
|
||||
if (textureDimension != 2 && textureDimension != 3) {
|
||||
throw new IllegalStateException("Unsupported texture dimension: " + textureDimension);
|
||||
}
|
||||
@ -123,20 +125,14 @@ public class UVCoordinatesGenerator {
|
||||
case TEXCO_NORM:
|
||||
inputData = BufferUtils.getFloatArray(mesh.getFloatBuffer(VertexBuffer.Type.Normal));
|
||||
break;
|
||||
case TEXCO_REFL:
|
||||
case TEXCO_GLOB:
|
||||
|
||||
break;
|
||||
case TEXCO_TANGENT:
|
||||
|
||||
break;
|
||||
case TEXCO_STRESS:
|
||||
|
||||
break;
|
||||
case TEXCO_LAVECTOR:
|
||||
case TEXCO_OBJECT:
|
||||
case TEXCO_OSA:
|
||||
case TEXCO_PARTICLE_OR_STRAND:
|
||||
case TEXCO_REFL:
|
||||
case TEXCO_SPEED:
|
||||
case TEXCO_STICKY:
|
||||
case TEXCO_VIEW:
|
||||
@ -169,15 +165,20 @@ public class UVCoordinatesGenerator {
|
||||
}
|
||||
} else {
|
||||
Vector3f min = bb.getMin(null);
|
||||
float[] uvCoordsResults = new float[4];//used for coordinates swapping
|
||||
float[] ext = new float[] { bb.getXExtent() * 2, bb.getYExtent() * 2, bb.getZExtent() * 2 };
|
||||
|
||||
// now transform the coordinates so that they are in the range of <0; 1>
|
||||
for (int i = 0; i < inputData.length; i += 3) {
|
||||
inputData[i] = (inputData[i] - min.x) / ext[0];
|
||||
inputData[i + 1] = (inputData[i + 1] - min.y) / ext[1];
|
||||
inputData[i + 2] = (inputData[i + 2] - min.z) / ext[2];
|
||||
uvCoordsResults[1] = (inputData[i] - min.x) / ext[0];
|
||||
uvCoordsResults[2] = (inputData[i + 1] - min.y) / ext[1];
|
||||
uvCoordsResults[3] = (inputData[i + 2] - min.z) / ext[2];
|
||||
|
||||
|
||||
inputData[i] = uvCoordsResults[coordinatesSwappingIndexes[0]];
|
||||
inputData[i + 1] = uvCoordsResults[coordinatesSwappingIndexes[1]];
|
||||
inputData[i + 2] = uvCoordsResults[coordinatesSwappingIndexes[2]];
|
||||
}
|
||||
result.setupData(Usage.Static, textureDimension, Format.Float, BufferUtils.createFloatBuffer(inputData));
|
||||
}
|
||||
result.setupData(Usage.Static, textureDimension, Format.Float, BufferUtils.createFloatBuffer(inputData));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user