Fixes to normals loading.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9521 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
0e24cf969b
commit
fde6b4a447
@ -13,7 +13,7 @@ import com.jme3.util.BufferUtils;
|
||||
|
||||
/*package*/ class MeshBuilder {
|
||||
/** An array of reference vertices. */
|
||||
private Vector3f[] vertices;
|
||||
private Vector3f[][] verticesAndNormals;
|
||||
/** An list of vertices colors. */
|
||||
private List<byte[]> verticesColors;
|
||||
/** 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'
|
||||
positions (it simply tells which vertex is referenced where in the result list). */
|
||||
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. */
|
||||
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).
|
||||
* 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.
|
||||
* @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
|
||||
*/
|
||||
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.");
|
||||
}
|
||||
this.vertices = vertices;
|
||||
this.verticesAndNormals = verticesAndNormals;
|
||||
this.verticesColors = verticesColors;
|
||||
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
|
||||
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) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if(!vertexReferenceMap.containsKey(index[i])) {
|
||||
this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
|
||||
vertexList.add(vertices[index[i]]);
|
||||
vertexList.add(verticesAndNormals[index[i]][0]);
|
||||
if(verticesColors != null) {
|
||||
vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
|
||||
}
|
||||
normalList.add(globalNormalMap.get(vertices[index[i]]));
|
||||
normalList.add(verticesAndNormals[index[i]][1]);
|
||||
if(uvCoordinatesList != null) {
|
||||
uvsMap.put(vertexList.size(), uvs[i]);
|
||||
uvCoordinatesList.add(uvs[i]);
|
||||
@ -143,20 +139,21 @@ import com.jme3.util.BufferUtils;
|
||||
if(!vertexAlreadyUsed) {
|
||||
this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
|
||||
uvsMap.put(vertexList.size(), uvs[i]);
|
||||
vertexList.add(vertices[index[i]]);
|
||||
vertexList.add(verticesAndNormals[index[i]][0]);
|
||||
if(verticesColors != null) {
|
||||
vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
|
||||
}
|
||||
normalList.add(globalNormalMap.get(vertices[index[i]]));
|
||||
normalList.add(verticesAndNormals[index[i]][1]);
|
||||
uvCoordinatesList.add(uvs[i]);
|
||||
index[i] = vertexList.size() - 1;
|
||||
}
|
||||
} else {
|
||||
index[i] = vertexList.indexOf(vertices[index[i]]);
|
||||
index[i] = vertexList.indexOf(verticesAndNormals[index[i]]);
|
||||
}
|
||||
indexList.add(index[i]);
|
||||
}
|
||||
} else {
|
||||
Vector3f n = FastMath.computeNormal(verticesAndNormals[v1][0], verticesAndNormals[v2][0], verticesAndNormals[v3][0]);
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
indexList.add(vertexList.size());
|
||||
this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
|
||||
@ -164,11 +161,11 @@ import com.jme3.util.BufferUtils;
|
||||
uvCoordinatesList.add(uvs[i]);
|
||||
uvsMap.put(vertexList.size(), uvs[i]);
|
||||
}
|
||||
vertexList.add(vertices[index[i]]);
|
||||
vertexList.add(verticesAndNormals[index[i]][0]);
|
||||
if(verticesColors != null) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
|
@ -106,10 +106,10 @@ public class MeshHelper extends AbstractBlenderHelper {
|
||||
}
|
||||
|
||||
// reading vertices and their colors
|
||||
Vector3f[] vertices = this.getVertices(structure, blenderContext);
|
||||
Vector3f[][] verticesAndNormals = this.getVerticesAndNormals(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");
|
||||
if(pMFace.isNotNull()) {
|
||||
@ -415,32 +415,38 @@ public class MeshHelper extends AbstractBlenderHelper {
|
||||
* the structure containing the mesh data
|
||||
* @param blenderContext
|
||||
* 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
|
||||
* this exception is thrown when the blend file structure is somehow invalid or corrupted
|
||||
*/
|
||||
@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");
|
||||
List<Structure> mVerts = pMVert.fetchData(blenderContext.getInputStream());
|
||||
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");
|
||||
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 {
|
||||
for (int i = 0; i < verticesAmount; ++i) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user