Przeglądaj źródła

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
Kae..pl 14 lat temu
rodzic
commit
7c1c6dc065

+ 53 - 37
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<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);

+ 9 - 0
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 {

+ 2 - 2
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());
 				}
 			}
 		}

+ 13 - 12
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<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));
 		}