Use all face vertices to calculate face normal
This ensures correct normals, even for e.g. freeform fins of which the 3 first vertices are concave
This commit is contained in:
parent
b3ef442350
commit
dfd497b9d1
@ -355,6 +355,39 @@ public class ObjUtils {
|
||||
return normalizeVector(crossProduct(u, v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the normal vector for a given face of the object.
|
||||
*
|
||||
* @param obj The object.
|
||||
* @param face The face of the object for which to calculate the normal vector.
|
||||
* @return The calculated normal vector.
|
||||
*/
|
||||
public static FloatTuple calculateNormalVector(DefaultObj obj, DefaultObjFace face) {
|
||||
FloatTuple[] vertices = getVertices(obj, face);
|
||||
return calculateNormalNewell(vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the normal of a polygon using the Newell's method.
|
||||
*
|
||||
* @param vertices a list of vertices representing the polygon
|
||||
* @return the normalized normal vector of the polygon
|
||||
*/
|
||||
private static FloatTuple calculateNormalNewell(FloatTuple[] vertices) {
|
||||
float x = 0f;
|
||||
float y = 0f;
|
||||
float z = 0f;
|
||||
for (int i = 0; i < vertices.length; i++) {
|
||||
FloatTuple current = vertices[i];
|
||||
FloatTuple next = vertices[(i + 1) % vertices.length];
|
||||
|
||||
x += (current.getY() - next.getY()) * (current.getZ() + next.getZ());
|
||||
y += (current.getZ() - next.getZ()) * (current.getX() + next.getX());
|
||||
z += (current.getX() - next.getX()) * (current.getY() + next.getY());
|
||||
}
|
||||
return normalizeVector(new DefaultFloatTuple(x, y, z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtracts two vectors.
|
||||
*
|
||||
|
@ -69,10 +69,7 @@ public abstract class TriangulationHelper {
|
||||
Map<Integer, Integer> vertexToTexCoordMap = mapVertexIndicesToTexCoordIndices(face);
|
||||
|
||||
// Calculate the face normal
|
||||
Coordinate normal = vertexToCoordinate(ObjUtils.calculateNormalVector(
|
||||
obj.getVertex(face.getVertexIndices()[0]),
|
||||
obj.getVertex(face.getVertexIndices()[1]),
|
||||
obj.getVertex(face.getVertexIndices()[2])));
|
||||
Coordinate normal = vertexToCoordinate(ObjUtils.calculateNormalVector(obj, face));
|
||||
|
||||
// Project the 3D face to a 2D polygon with only X and Y coordinates.
|
||||
// This is necessary because the JTS library only works with 2D polygons for triangulation.
|
||||
|
Loading…
x
Reference in New Issue
Block a user