-
Notifications
You must be signed in to change notification settings - Fork 241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Check for degenerate triangles #242
Comments
It might be better to use the actual code that crashes for the triangle degeneracy check. Right now I'm using this for culling bad triangles in my prototype mesh processing tools: var crossScratch1 = new Cartesian3();
var crossScratch2 = new Cartesian3();
function areaWeightedTriangleNormal(position0, position1, position2, result) {
var leg1 = Cartesian3.subtract(position1, position0, crossScratch1);
var leg2 = Cartesian3.subtract(position2, position0, crossScratch2);
return Cartesian3.cross(leg1, leg2, result);
}
function isNormalLousy(normal) {
// check if normalizing this vector will result in NaNs
var magnitude = Cartesian3.magnitude(normal);
var resultX = normal.x / magnitude;
var resultY = normal.y / magnitude;
var resultZ = normal.z / magnitude;
return isNaN(resultX) || isNaN(resultY) || isNaN(resultZ);
} Since this is based on |
We found another issue. When to triangles share vertices but have opposite winding order, the smooth normal computation for the shared vertices can cause this normalization problem: If we have triangles [0, 1, 2] and [0, 3, 2] of equal area, the normals computed for vertices 0 and 2 will turn out to be zero since the face normals for the two triangles cancel out, since with counterclockwise winding the normal for [0, 1, 2] points into the screen and [0, 3, 2] points out. |
Offline discussion: Also, this problem could end up happening for any shape with one or more shared vertices where the normals on some faces are negate the others (eg. a hexagon with a center and the face normals result in the normal at the center being 0. Probably the best compromise in this situation would be to duplicate the vertex for that specific vertex. However, in the case where there is more than two competing faces at the vertex (like the hexagon example), the question then becomes which face gets the duplicated vertex and all the other faces keep one vertex. But this could probably be solved by duplicating the vertex for all the faces. |
I think it's still worth implementing a winding order correction stage, but perhaps it should also include a documented toggle to switch between winding order correction and vertex duplication. Most "bad winding order" cases we've run into seem to be cases where the user isn't aware of the weird winding order, in which case automatic correction is more helpful. |
Let's just fix the winding order so it is consistent. There are (robust, I believe) algorithms surveyed in Real-Time Rendering. Perhaps @erich666 can suggest his favorite. |
Generating smooth normals goes through Cesium's
GeometryPipeline.computeNormal
function which will throw when normalizing a zero-vector normal. Rather than patching up broken normals we should fix the root cause which seems to be degenerate triangles. For this we can use some of the code lifted from @likangning93. This also affects face normals, so that may be an easier place to start.Sample model:
node bin/gltf-pipeline.js face.gltf -f
ornode bin/gltf-pipeline.js face.gltf -m
face.gltf.txt
The text was updated successfully, but these errors were encountered: