From 7c1c6dc065eb104217e32411092599cd6cf3328d Mon Sep 17 00:00:00 2001 From: "Kae..pl" Date: Sat, 10 Sep 2011 14:06:52 +0000 Subject: [PATCH] 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 --- .../blender/materials/MaterialContext.java | 90 +++++++++++-------- .../blender/materials/MaterialHelper.java | 9 ++ .../plugins/blender/meshes/MeshHelper.java | 4 +- .../textures/UVCoordinatesGenerator.java | 25 +++--- 4 files changed, 77 insertions(+), 51 deletions(-) diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java index f6e13d755..4302aea52 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.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 mTexs; - /*package*/ final List 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 mTexs; + /* package */final List 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(); textures = new ArrayList(); DynamicArray mtexsArray = (DynamicArray) 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); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java index f27c27d2b..5c21bebdf 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java @@ -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 { diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java index af8f032e9..fe3e0c34e 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java @@ -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()); } } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java index d2963dab3..114932b58 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java @@ -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 geometries) { + public static void generateUVCoordinates(int texco, int projection, int textureDimension, int[] coordinatesSwappingIndexes, List 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)); }