Просмотр исходного кода

Fixes to normals loading.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9521 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Kae..pl 13 лет назад
Родитель
Сommit
fde6b4a447

+ 14 - 40
engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshBuilder.java

@@ -13,7 +13,7 @@ import com.jme3.util.BufferUtils;
 
 
 /*package*/ class MeshBuilder {
 /*package*/ class MeshBuilder {
 	/** An array of reference vertices. */
 	/** An array of reference vertices. */
-	private Vector3f[] vertices;
+	private Vector3f[][] verticesAndNormals;
 	/** An list of vertices colors. */
 	/** An list of vertices colors. */
 	private List<byte[]> verticesColors;
 	private List<byte[]> verticesColors;
 	/** A variable that indicates if the model uses generated textures. */
 	/** A variable that indicates if the model uses generated textures. */
@@ -22,8 +22,6 @@ import com.jme3.util.BufferUtils;
 	/** This map's key is the vertex index from 'vertices 'table and the value are indices from 'vertexList'
 	/** This map's key is the vertex index from 'vertices 'table and the value are indices from 'vertexList'
     positions (it simply tells which vertex is referenced where in the result list). */
     positions (it simply tells which vertex is referenced where in the result list). */
     private Map<Integer, Map<Integer, List<Integer>>> globalVertexReferenceMap;
     private Map<Integer, Map<Integer, List<Integer>>> globalVertexReferenceMap;
-    /** A map between vertex and its normal vector. */
-    private Map<Vector3f, Vector3f> globalNormalMap = new HashMap<Vector3f, Vector3f>();
     
     
     /** A map between vertex index and its UV coordinates. */
     /** A map between vertex index and its UV coordinates. */
     private Map<Integer, Vector2f> uvsMap = new HashMap<Integer, Vector2f>();
     private Map<Integer, Vector2f> uvsMap = new HashMap<Integer, Vector2f>();
@@ -42,17 +40,17 @@ import com.jme3.util.BufferUtils;
      * Constructor. Stores the given array (not copying it).
      * Constructor. Stores the given array (not copying it).
      * The second argument describes if the model uses generated textures. If yes then no vertex amount optimisation is applied.
      * The second argument describes if the model uses generated textures. If yes then no vertex amount optimisation is applied.
      * The amount of vertices is always faceCount * 3.
      * The amount of vertices is always faceCount * 3.
-     * @param vertices the reference vertices array
+     * @param verticesAndNormals the reference vertices and normals array
      * @param usesGeneratedTextures a variable that indicates if the model uses generated textures or not
      * @param usesGeneratedTextures a variable that indicates if the model uses generated textures or not
      */
      */
-	public MeshBuilder(Vector3f[] vertices, List<byte[]> verticesColors, boolean usesGeneratedTextures) {
-		if(vertices == null || vertices.length == 0) {
+	public MeshBuilder(Vector3f[][] verticesAndNormals, List<byte[]> verticesColors, boolean usesGeneratedTextures) {
+		if(verticesAndNormals == null || verticesAndNormals.length == 0) {
 			throw new IllegalArgumentException("No vertices loaded to build mesh.");
 			throw new IllegalArgumentException("No vertices loaded to build mesh.");
 		}
 		}
-		this.vertices = vertices;
+		this.verticesAndNormals = verticesAndNormals;
 		this.verticesColors = verticesColors;
 		this.verticesColors = verticesColors;
 		this.usesGeneratedTextures = usesGeneratedTextures;
 		this.usesGeneratedTextures = usesGeneratedTextures;
-		globalVertexReferenceMap = new HashMap<Integer, Map<Integer, List<Integer>>>(vertices.length);
+		globalVertexReferenceMap = new HashMap<Integer, Map<Integer, List<Integer>>>(verticesAndNormals.length);
 	}
 	}
 	
 	
 	/**
 	/**
@@ -115,17 +113,15 @@ import com.jme3.util.BufferUtils;
         
         
         //creating faces
         //creating faces
         Integer[] index = new Integer[] {v1, v2, v3};
         Integer[] index = new Integer[] {v1, v2, v3};
-		Vector3f n = FastMath.computeNormal(vertices[v1], vertices[v2], vertices[v3]);
-        this.addNormal(n, globalNormalMap, smooth, vertices[v1], vertices[v2], vertices[v3]);
         if(smooth && !usesGeneratedTextures) {
         if(smooth && !usesGeneratedTextures) {
 			for (int i = 0; i < 3; ++i) {
 			for (int i = 0; i < 3; ++i) {
         		if(!vertexReferenceMap.containsKey(index[i])) {
         		if(!vertexReferenceMap.containsKey(index[i])) {
             		this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
             		this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
-            		vertexList.add(vertices[index[i]]);
+            		vertexList.add(verticesAndNormals[index[i]][0]);
             		if(verticesColors != null) {
             		if(verticesColors != null) {
             			vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
             			vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
             		}
             		}
-            		normalList.add(globalNormalMap.get(vertices[index[i]]));
+            		normalList.add(verticesAndNormals[index[i]][1]);
             		if(uvCoordinatesList != null) {
             		if(uvCoordinatesList != null) {
             			uvsMap.put(vertexList.size(), uvs[i]);
             			uvsMap.put(vertexList.size(), uvs[i]);
             			uvCoordinatesList.add(uvs[i]);
             			uvCoordinatesList.add(uvs[i]);
@@ -143,20 +139,21 @@ import com.jme3.util.BufferUtils;
             		if(!vertexAlreadyUsed) {
             		if(!vertexAlreadyUsed) {
             			this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
             			this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
             			uvsMap.put(vertexList.size(), uvs[i]);
             			uvsMap.put(vertexList.size(), uvs[i]);
-            			vertexList.add(vertices[index[i]]);
+            			vertexList.add(verticesAndNormals[index[i]][0]);
             			if(verticesColors != null) {
             			if(verticesColors != null) {
             				vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
             				vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
             			}
             			}
-                		normalList.add(globalNormalMap.get(vertices[index[i]]));
+            			normalList.add(verticesAndNormals[index[i]][1]);
             			uvCoordinatesList.add(uvs[i]);
             			uvCoordinatesList.add(uvs[i]);
             			index[i] = vertexList.size() - 1;
             			index[i] = vertexList.size() - 1;
             		}
             		}
             	} else {
             	} else {
-            		index[i] = vertexList.indexOf(vertices[index[i]]);
+            		index[i] = vertexList.indexOf(verticesAndNormals[index[i]]);
             	}
             	}
         		indexList.add(index[i]);
         		indexList.add(index[i]);
         	}
         	}
         } else {
         } else {
+        	Vector3f n = FastMath.computeNormal(verticesAndNormals[v1][0], verticesAndNormals[v2][0], verticesAndNormals[v3][0]);
         	for (int i = 0; i < 3; ++i) {
         	for (int i = 0; i < 3; ++i) {
         		indexList.add(vertexList.size());
         		indexList.add(vertexList.size());
         		this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
         		this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
@@ -164,11 +161,11 @@ import com.jme3.util.BufferUtils;
         			uvCoordinatesList.add(uvs[i]);
         			uvCoordinatesList.add(uvs[i]);
         			uvsMap.put(vertexList.size(), uvs[i]);
         			uvsMap.put(vertexList.size(), uvs[i]);
         		}
         		}
-        		vertexList.add(vertices[index[i]]);
+        		vertexList.add(verticesAndNormals[index[i]][0]);
         		if(verticesColors != null) {
         		if(verticesColors != null) {
         			vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
         			vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
         		}
         		}
-        		normalList.add(globalNormalMap.get(vertices[index[i]]));
+        		normalList.add(n);
         	}
         	}
         }
         }
 	}
 	}
@@ -266,29 +263,6 @@ import com.jme3.util.BufferUtils;
 		return vertexMap.size() == 0;
 		return vertexMap.size() == 0;
 	}
 	}
 	
 	
-	/**
-     * This method adds a normal to a normals' map. This map is used to merge normals of a vertor that should be rendered smooth.
-     * 
-     * @param normalToAdd
-     *            a normal to be added
-     * @param normalMap
-     *            merges normals of faces that will be rendered smooth; the key is the vertex and the value - its normal vector
-     * @param smooth
-     *            the variable that indicates wheather to merge normals (creating the smooth mesh) or not
-     * @param vertices
-     *            a list of vertices read from the blender file
-     */
-    private void addNormal(Vector3f normalToAdd, Map<Vector3f, Vector3f> normalMap, boolean smooth, Vector3f... vertices) {
-        for (Vector3f v : vertices) {
-            Vector3f n = normalMap.get(v);
-            if (!smooth || n == null) {
-                normalMap.put(v, normalToAdd.clone());
-            } else {
-                n.addLocal(normalToAdd).normalizeLocal();
-            }
-        }
-    }
-    
     /**
     /**
      * This method fills the vertex reference map. The vertices are loaded once and referenced many times in the model. This map is created
      * This method fills the vertex reference map. The vertices are loaded once and referenced many times in the model. This map is created
      * to tell where the basic vertices are referenced in the result vertex lists. The key of the map is the basic vertex index, and its key
      * to tell where the basic vertices are referenced in the result vertex lists. The key of the map is the basic vertex index, and its key

+ 19 - 13
engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java

@@ -106,10 +106,10 @@ public class MeshHelper extends AbstractBlenderHelper {
         }
         }
         
         
         // reading vertices and their colors
         // reading vertices and their colors
-        Vector3f[] vertices = this.getVertices(structure, blenderContext);
+        Vector3f[][] verticesAndNormals = this.getVerticesAndNormals(structure, blenderContext);
         List<byte[]> verticesColors = this.getVerticesColors(structure, blenderContext);
         List<byte[]> verticesColors = this.getVerticesColors(structure, blenderContext);
         
         
-        MeshBuilder meshBuilder = new MeshBuilder(vertices, verticesColors, this.areGeneratedTexturesPresent(materials));
+        MeshBuilder meshBuilder = new MeshBuilder(verticesAndNormals, verticesColors, this.areGeneratedTexturesPresent(materials));
 
 
         Pointer pMFace = (Pointer) structure.getFieldValue("mface");
         Pointer pMFace = (Pointer) structure.getFieldValue("mface");
         if(pMFace.isNotNull()) {
         if(pMFace.isNotNull()) {
@@ -415,32 +415,38 @@ public class MeshHelper extends AbstractBlenderHelper {
      *            the structure containing the mesh data
      *            the structure containing the mesh data
      * @param blenderContext
      * @param blenderContext
      *            the blender context
      *            the blender context
-     * @return a list of vertices colors, each color belongs to a single vertex
+     * @return a list of two - element arrays, the first element is the vertex and the second - its normal
      * @throws BlenderFileException
      * @throws BlenderFileException
      *             this exception is thrown when the blend file structure is somehow invalid or corrupted
      *             this exception is thrown when the blend file structure is somehow invalid or corrupted
      */
      */
     @SuppressWarnings("unchecked")
     @SuppressWarnings("unchecked")
-    private Vector3f[] getVertices(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
-        int verticesAmount = ((Number) meshStructure.getFieldValue("totvert")).intValue();
-        Vector3f[] vertices = new Vector3f[verticesAmount];
-        if (verticesAmount == 0) {
-            return vertices;
+    private Vector3f[][] getVerticesAndNormals(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
+        int count = ((Number) meshStructure.getFieldValue("totvert")).intValue();
+        Vector3f[][] result = new Vector3f[count][2];
+        if (count == 0) {
+            return result;
         }
         }
 
 
         Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
         Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
         List<Structure> mVerts = pMVert.fetchData(blenderContext.getInputStream());
         List<Structure> mVerts = pMVert.fetchData(blenderContext.getInputStream());
         if(this.fixUpAxis) {
         if(this.fixUpAxis) {
-        	for (int i = 0; i < verticesAmount; ++i) {
+        	for (int i = 0; i < count; ++i) {
                 DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
                 DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
-                vertices[i] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(2).floatValue(), -coordinates.get(1).floatValue());
+                result[i][0] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(2).floatValue(), -coordinates.get(1).floatValue());
+                
+                DynamicArray<Number> normals = (DynamicArray<Number>) mVerts.get(i).getFieldValue("no");
+                result[i][1] = new Vector3f(normals.get(0).shortValue()/32767.0f, normals.get(2).shortValue()/32767.0f, -normals.get(1).shortValue()/32767.0f);
             }
             }
         } else {
         } else {
-        	for (int i = 0; i < verticesAmount; ++i) {
+        	for (int i = 0; i < count; ++i) {
                 DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
                 DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
-                vertices[i] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(1).floatValue(), coordinates.get(2).floatValue());
+                result[i][0] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(1).floatValue(), coordinates.get(2).floatValue());
+                
+                DynamicArray<Number> normals = (DynamicArray<Number>) mVerts.get(i).getFieldValue("no");
+                result[i][1] = new Vector3f(normals.get(0).shortValue()/32767.0f, normals.get(1).shortValue()/32767.0f, normals.get(2).shortValue()/32767.0f);
             }
             }
         }
         }
-        return vertices;
+        return result;
     }
     }
 
 
     @Override
     @Override