How to calculate normals for a trianglemesh?

Started by
16 comments, last by jor1980 10 years ago

Hi, I am creating a meshviewer using jme3 I read the meshes data from a file that has no normals data. So I need to create them with my code but I don´t know how can I create the normals for a trianglesmesh from my java code in jmonkey.

Advertisement

For polygons, cross product two of the edges. Like (v2-v1)x(v3-v2). Then normalize it.

Once you have all the face normals, you can calculate vertex normals by averaging all the face normals that the vertex belongs to. Easiest way to do it is to zero out all the vertex normals, then loop over all the faces and add the face normal into each of its vertices' normal. Then loop over all the vertex normals and normalize them.


For polygons, cross product two of the edges. Like (v2-v1)x(v3-v2). Then normalize it.

If the winding order for the triangle is v1, v2, v3 - the crossproduct should be (v2-v1) x (v3-v1) to get the correct direction, assuming that clockwise winding order implies left-hand rule crossproducts and counter-clockwise order implies right-hand rule crossproducts.

Also, if the mesh faces do not share vertices - i.e., a vertex is used in only one face - the algorithm DekuTree64 will work, but comprises a lot of extra calcs. In this case, simply calculate the face normal via the crossproduct mentioned and set the normal for each of the 3 face vertices to that face normal.

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.


In this case, simply calculate the face normal via the crossproduct mentioned and set the normal for each of the 3 face vertices to that face normal.

Wouldn't that produce ugly lighting results?

EDIT: For anything that isn't a cube that is.

"I AM ZE EMPRAH OPENGL 3.3 THE CORE, I DEMAND FROM THEE ZE SHADERZ AND MATRIXEZ"

My journals: dustArtemis ECS framework and Making a Terrain Generator


For polygons, cross product two of the edges. Like (v2-v1)x(v3-v2). Then normalize it.

If the winding order for the triangle is v1, v2, v3 - the crossproduct should be (v2-v1) x (v3-v1) to get the correct direction, assuming that clockwise winding order implies left-hand rule crossproducts and counter-clockwise order implies right-hand rule crossproducts.

Also, if the mesh faces do not share vertices - i.e., a vertex is used in only one face - the algorithm DekuTree64 will work, but comprises a lot of extra calcs. In this case, simply calculate the face normal via the crossproduct mentioned and set the normal for each of the 3 face vertices to that face normal.

If he's reading the mesh from a file, the only way to know if a face is not connected to other faces is going through all the faces and checking if any of it's vertices are in the face you're interested. And if you check every face you'll have to iterate over the full mesh a lot of times.

To me it looks like more work, with DekuTree64 method you must go over the vertices once (to set the vertex normals to 0), over the faces only once (to compute the face normal and add it to each vertex of that face), and then over the vertices once again (to normalize the vertex normal).


Wouldn't that produce ugly lighting results?

EDIT: For anything that isn't a cube that is.

Cubes aren't the only thing with "flat" faces. smile.png He didn't mention whether the mesh in question was organic, a mechanical object, etc. Buildings, platforms, etc., look much better with flat faces.


If he's reading the mesh from a file, the only way to know if a face is not connected to other faces is going through all the faces

Not necessarily. If a mesh is loaded for a specific purpose in a scene, etc., one would know the characteristics of the mesh. If the mesh is known to have "flat" faces, I'd skip the extra calcs. That's why I qualified my comment with "if the mesh faces do not share vertices.."

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

The mesh in question is a human face. As i am using jmonkey i would like to know if it has any method to make all this calculations or if is it another java api to make this calculations?

I made what you told, calculate the face´s normals and then lopp throw the vertex to calculate the vertex normals. My result is very confusing, despite i set facecullmode to off, this is my render result:

Any clue about the problem?could be something with the normals calculation?l5jn.jpg

Reviewing my code and the results I got I think that my problem is that some os the faces are clockWise and other counterclockwise, as I didn´t know how to determine if a face is clockwise or counterclockwise I calculated the face's normals like this:


//Calculate the face normal, true for clockwise false counterclockwise(not confirmed)
		static Vector3f calculateFaceNormal(Vector3f v1,Vector3f v2,Vector3f v3, Boolean isClockWise){
			//cross product
			Vector3f crossProduct;
			if(isClockWise)
				crossProduct=v2.subtract(v1).mult(v3.subtract(v2));
			else
				crossProduct=v2.subtract(v1).mult(v3.subtract(v1));
			
			//normalize
			return crossProduct.normalize();
		}

So I think that I must change this code in a way to know if a face is clockwise or counterclockwise and then choose the right crossProduct for it. but I don´t know how to determine that.

The file must be saved using some convention, every face should be stored clockwise or counterclockwise. But I'm guessing that when you open the file in another program it shows ok, right? Can you share the file? I'd like to take a look of it. Have you tried other files?

This topic is closed to new replies.

Advertisement