PDA

View Full Version : Normal in World coordinates


rodbrew
10-06-2010, 12:19 AM
How can you get a vertex normal in world coordinates. I've tried just (getNorm obj 1) * obj.transform but that doesn't seem to give the correct resultant vector.

I've read that you can calculate them yourself from edges but I'm wondering how fast this would be since I'm using it in a particle flow script.

Thanks,
Rod

denisT
10-06-2010, 12:43 AM
How can you get a vertex normal in world coordinates. I've tried just (getNorm obj 1) * obj.transform but that doesn't seem to give the correct resultant vector.

I've read that you can calculate them yourself from edges but I'm wondering how fast this would be since I'm using it in a particle flow script.

Thanks,
Rod

you can't believe but the getnormal returns the vertex normal in world space of coordinates. The problem is that it returns it wrong. In MXS to be 100% sure about the vertex normal value you have to use Edit_Normals modifier or calculate the value yourself. You have to calculate the normal using the face normals (forget about edges) and their smoothing groups.

rodbrew
10-06-2010, 03:07 AM
Uhhggghhh, well thats good to know. I can stop pulling my hair out. Thought I had a workaround by taking a snapshot of the mesh and I thought I had it working but after some testing, nope its not. At least not all the time.

I guess I could use face centers instead of verts but not quite as quick I don't think.

If I was to compute the normals myself would I have to cycle through all the faces until I found a face with the vert I'm interested in and then get the edges to compute normals. Does anyone have a quick algorithm for doing this?

Thanks
Rod

denisT
10-06-2010, 04:27 AM
Uhhggghhh, well thats good to know. I can stop pulling my hair out. Thought I had a workaround by taking a snapshot of the mesh and I thought I had it working but after some testing, nope its not. At least not all the time.

I guess I could use face centers instead of verts but not quite as quick I don't think.

If I was to compute the normals myself would I have to cycle through all the faces until I found a face with the vert I'm interested in and then get the edges to compute normals. Does anyone have a quick algorithm for doing this?

Thanks
Rod

it seams like i am answering the same question the third-forth-fifth time. but it's OK. I can do it again because it's kinda personal between me and max :)

to get the right value for a vertex normal, you have to get all face normals surround the vert. After that you have to check the smoothing groups of those faces and average only the faces with shared smoothing groups. there is no such things as VERTEX normal. there is the normal value in the face's corner. some corners of neighbor faces can have the same normal because they are in the same smoothing group.

when you ask the GETNORMAL of any vertex, the mesh interface returns you the right value if this vertex surrounded by faces with the same smoothing group. if the vertex is on the border of SM groups the interface returns whatever it wants.

to get the normal of a vert is not very slow. give me your version and i will show how to optimize the code.

best,

denisT
10-06-2010, 04:44 AM
... I'm using it in a particle flow script.


well... that's a bit different story. i guess that you are using the vertex normal as direction of the particle emission. if you can use the face normal instead of the vertex normal that would be better. to get the face normal takes almost nothing for the performance.

rodbrew
10-06-2010, 07:58 PM
Ok so I went with the calculate my own normals method. Not really concerned with smoothing groups or even which face I get the vertex normal from so I'm just cycling through the faces until I hit a face with a vertex I need. I also take a snapshot of the emitter mesh so I don't have to worry about transforming the vertex positions into world space. Here's the code snippet, seems quick enough but maybe I'm missing a better way.

Thanks again,
Rod


for j = 1 to numverts do
found = false
faceId = 1
while found != true do
(
tmpFace = getFace emitterMesh faceID
if tmpFace.x == j or tmpFace.y == j or tmpFace.z == j then
(
found = true
)
faceID += 1
)
if tmpFace.x == j then
(
v1 = ((getvert emitterMesh tmpFace.y) - (getvert emitterMesh tmpFace.x))
v2 = ((getvert emitterMesh tmpFace.z) - (getvert emitterMesh tmpFace.x))
vNorm = normalize (cross v1 v2)
)
else
(
if tmpFace.y == j then
(
v1 = ((getvert emitterMesh tmpFace.z) - (getvert emitterMesh tmpFace.y))
v2 = ((getvert emitterMesh tmpFace.x) - (getvert emitterMesh tmpFace.y))
vNorm = normalize (cross v1 v2)
)
else
(
v1 = ((getvert emitterMesh tmpFace.x) - (getvert emitterMesh tmpFace.z))
v2 = ((getvert emitterMesh tmpFace.y) - (getvert emitterMesh tmpFace.z))
vNorm = normalize (cross v1 v2)
)
)
)

denisT
10-06-2010, 09:21 PM
Ok so I went with the calculate my own normals method. Not really concerned with smoothing groups or even which face I get the vertex normal from so I'm just cycling through the faces until I hit a face with a vertex I need. I also take a snapshot of the emitter mesh so I don't have to worry about transforming the vertex positions into world space. Here's the code snippet, seems quick enough but maybe I'm missing a better way.

Thanks again,
Rod


for j = 1 to numverts do
found = false
faceId = 1
while found != true do
(
tmpFace = getFace emitterMesh faceID
if tmpFace.x == j or tmpFace.y == j or tmpFace.z == j then
(
found = true
)
faceID += 1
)
if tmpFace.x == j then
(
v1 = ((getvert emitterMesh tmpFace.y) - (getvert emitterMesh tmpFace.x))
v2 = ((getvert emitterMesh tmpFace.z) - (getvert emitterMesh tmpFace.x))
vNorm = normalize (cross v1 v2)
)
else
(
if tmpFace.y == j then
(
v1 = ((getvert emitterMesh tmpFace.z) - (getvert emitterMesh tmpFace.y))
v2 = ((getvert emitterMesh tmpFace.x) - (getvert emitterMesh tmpFace.y))
vNorm = normalize (cross v1 v2)
)
else
(
v1 = ((getvert emitterMesh tmpFace.x) - (getvert emitterMesh tmpFace.z))
v2 = ((getvert emitterMesh tmpFace.y) - (getvert emitterMesh tmpFace.z))
vNorm = normalize (cross v1 v2)
)
)
)


to make it faster you can use:
1. meshop.getFacesUsingVert to get all faces surround the vert
2. getFaceNormal to get the face normal

CGTalk Moderation
10-06-2010, 09:21 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.