I have a plane with lots of vertices that randomly move up and down. However, the normals don’t get updated, and that makes the plane shaded flat. I have found codes that update the normals, however, they look a bit weird as instead of shading the whole polygon flat, the make a part around the vertex darker, following the edges.
I believe there’s two ways to finding the normal of a polygon:
mathutils.geometry.normal
cross product of two vectors of two edges or vectors of the triangle.
I’d like to try the 2nd method as I can learn from it, but I don’t exactly know how to code it.
First, I need the vectors. getVectTo won’t work as you need an object’s origin as the start point, not an XYZ point.
Then, I need to find the cross product, somehow like this:
a1 = firstvertex.XYZ()
a2 = secondvertex.XYZ()
a3 = thirdvertex.XYZ()
vec1 = vector from a1 to a2
vec2 = vector from a1 to a3
polyNormal = crossproduct(vec1 and vec2)
Finding the cross product would be something like this:
vec1.cross(vec2)
However, I don’t know the Python code, and that’s where I need help.
The first method probably is just a shortcut of the second method…
Once I have the normal, I need a way to set the normal of the polygon, not the vertex.
to get the vector from one position vector (in this case the position of a vertex) to another you just substract the two position vectors (destination - origin), so you could do getVectTo once for each vertex and then substract properly to get what you are looking for
and i think cross product in blender python is done by doing vec1.cross(vec2), it should work as long a you import the mathutils library like so
import Blender
from Blender import Mathutils
from Blender.Mathutils import *
Allright, I got it working, it does the same as the first method… :yes: But atleast I learned something. I understand vectors (mostly) now, sorry for saying stupid things earlier.
If I hear you right, you’re trying to do flat shaded after moving verts, but it’s com8ng out smooth shaded?
This likely isn’t an issue with the normal calculation, instead it is probable that the mesh is smooth shaded to begin with.
In BGE (and most game engines) a vertex has only a single normal. As a result, when things are flat shaded, you need multiple vertices for each intersection of edges. Because of this, if the mesh in blender is smooth shaded, attempting to make it flat shaded by recalculating normals will not work - their aren’t enough vertices to store the information.
To prove this, print out how many vertices are in a cube - once in smooth shaded (8) and once in flat shaded (24).
Now, even if your mesh is flat shaded, BGE may try and be clever and reduce the number of vertices by making flat flat-shaded faces vertices share data. If your plane is flat shaded, and still doesn’t appear so in BGE, try using an edge split modifier after marking all edges as sharp. This will split all the faces in the mesh so the vertices are definitely separate.
Finally, you don;t need get vect to. Simply:
mathutils.Vector([vert1.x, vert1.y, vert1.z]) - mathutils.Vector([vert2.x, vert2.y, vert2.z]) will work.
(I can’t remember the format of vert.XYZ(), it may already come as a mathutils.Vector in which case vert1.XYZ() - vert2.XYZ() is sufficient.)
Vectors do not have a position. They have a direction and a length. They can be anywhere in space.
Special vectors are positional or location vectors. They are placed at the space origin (in object space it is the object origin). The vector to a vertex is the location vector (in object space from object origin).
Normal vectors have no origin at all. For simpler imagination they are typically draws at the vertex location. They do not need that. The “normal” attribute defines:
they have a length of 1.0 (the bge does not require that)
they are orthogonal to something (here -> orthogonal to the polygon that spans between the two edges)
Hmmm, yes, I got it working before all these new replies. Turns out that positions aren’t just a list, but a 3D vector… Anyway, maybe for shading the polygons flat I shoud use the normal calculated with the Python code, pass it over to OpenGL somehow, and set the normal there. However, I don’t know almost any OpenGL or how to use it in BGE, so it’s going to be hard… Can you set a polygon’s normal with Python?
as sayd sdfgeoff, something change if the mesh starts in blender as smooth or flat, but is not the number of vertex(still the same), anyhow if the mesh starts as flat this seem that work … pretty (in reality should not because the triangles are not counted)
def remake_normals_flat(mesh):
# check that the mesh is "flat" in blender otherwise not work
for p in [mesh.getPolygon(index) for index in range(mesh.numPolygons)]:
vertexes = [p.getMesh().getVertex(p.getMaterialIndex(),p.getVertexIndex(vn)) for vn in range(p.getNumVertex())]
normal = mathutils.geometry.normal(*[v.XYZ for v in vertexes])
for v in vertexes:
v.normal = normal