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));
|
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.
|
* Subtracts two vectors.
|
||||||
*
|
*
|
||||||
|
@ -69,10 +69,7 @@ public abstract class TriangulationHelper {
|
|||||||
Map<Integer, Integer> vertexToTexCoordMap = mapVertexIndicesToTexCoordIndices(face);
|
Map<Integer, Integer> vertexToTexCoordMap = mapVertexIndicesToTexCoordIndices(face);
|
||||||
|
|
||||||
// Calculate the face normal
|
// Calculate the face normal
|
||||||
Coordinate normal = vertexToCoordinate(ObjUtils.calculateNormalVector(
|
Coordinate normal = vertexToCoordinate(ObjUtils.calculateNormalVector(obj, face));
|
||||||
obj.getVertex(face.getVertexIndices()[0]),
|
|
||||||
obj.getVertex(face.getVertexIndices()[1]),
|
|
||||||
obj.getVertex(face.getVertexIndices()[2])));
|
|
||||||
|
|
||||||
// Project the 3D face to a 2D polygon with only X and Y coordinates.
|
// 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.
|
// This is necessary because the JTS library only works with 2D polygons for triangulation.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user