I wanted to place several items on an undulating surface that orientated themselves to the surface normals. I queried particles that were attached to a surface which returned the particles Location and Normal Vector.

To place an object at the particle’s location was simple enough, and was a case of using


I now needed to convert the normal vector into rotational information to orient the object to that of the surface.

My first approach was to use arcTan and SOHCAHTOA to determine the angle of theta for each axis of rotation. This was quite involved, and was not working correctly (Now that I look back, it was probably due to my vector’s not being normalised).

After a handy tip from Chad Vernon on the Maya-Python list, I discovered the super-magic matrix that allows you to map 3 orthonormal basis vectors directly to a signal matrix. This is what it looks like.

⎡  x.x      x.y     x.z     0  ⎤
⎢  n.x      n.y     n.z     0  ⎥
⎢  t.x      t.y     t.z     0  ⎥
⎣  0        0       0       1  ⎦

This uses three vectors x, n and t where each vector is defined as:

n = The normal vector from querying the surface.

t = A vector that is at tangent to vector n

x = A Vector that is orthogonal to n and t

Starting with one vector, we need to construct the other two. First we need create a temporary vector that will help decide roughly which direction the x vector will point. I defined vector temp as simply {0.0, 1.0, 0.0}, which points straight up in Y.

By now calculating the cross product of n and temp we receive vector t. The angle of ∂ is not 90°, but thats ok as the angle between n and t is.

Now by finding the cross product of nt we receive vector x

We need to normalize each vector first. Now with n, t and x we can substitute these back into the matrix, and apply it to an object at the surface position.

Voila, we now have an object that is placed at a given point on a mesh’s surface, and oriented to the surface normal.

I also found Adam Mechtley’s video tutorial aim-constraints handy to visualise the need for the temp vector:


« »