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
3.0
Kae..pl 13 years ago
parent 3383e2e086
commit 7c1c6dc065
  1. 90
      engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java
  2. 9
      engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java
  3. 4
      engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java
  4. 25
      engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java

@ -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…
Cancel
Save