Calculating normals fast for TriMesh?


Let's assume I have 3 Vector3f verticies, each have it's own xyz coords in space. On their base a simple TriMesh is generated.

What is the best way to properly calculate normals using xyz coordinates of all 3 vetricies? Is there any function for this in jme? Or maybe some source code examples?


new Triangle(p1, p2, p3).calculateNormal();

And what if I am not using Triangle directly, only TriMesh?

Naive approach:

If your points are p1, p2, p3:

a = p1.subtract(p2);

b = p2.subtract(p3);

c = p3.subtract(p1);

n1 = a.cross©;

n2 = b.cross(a);

n3 = c.cross(b);

Didn't look into simplifying. I'm not sure about the direction of the normals, but this way they should be all on one side of the mesh. If you want the other side, change the order of the subtractions. Also I don't know about the length you need. If they have to be length=1, normalize n1 to n3.

Your blog looks interesting btw. Will have a look into that :slight_smile:

edit: Oh, wait… you only want one normal? Hm… how is that defined? n1 to n3 are all normal to the triangle, only their lengths vary. Does it need to be the area of the triangle or something? Btw, maybe you could look into the source of the method Fungi posted.

You can easily get the array of indices/positions from TriMesh (there's methods for them, see the javadoc). Just loop over the triangle count, and now for each triangle you have the positional data and the indices of the normals.

The triangle class would be very unnecessary if you're only looking to calculate the normals, which itself is a simple calculation:

Given V1, V2, V3

Edge1 = V2 - V1

Edge2 = V3 - V1

Normal = Cross(Edge1, Edge2)

As Bo said, this is the face normal to the triangle (not the vertices). In many cases the vertices assume this normal. However, if you want to weight normals based on the adjacent triangles, that'll require some more work.

Direction of the normal should be consistent with winding order, so unless if you change that, it shouldn't be a problem…

jme seems to have NormalGenerator for TriMesh already. Look at the com.jme.util.geom.NormalGenerator.

Thanks everybody!

Now I have plenty of info to get things right. As Bo said, for now I just calculate a normal for one vertex of the triangle and assign them to other two, so they all are the same. Starick is right about the fact that this approach isn't too good in all cases, but for now this should be good.

Thanks Bo for interest in my blog. As you can see, it's been a while since I have posted my last post there. A lot of things have changed, as well as the approach to handle all the geometry. I will post some updates soon :slight_smile: