View Full Version : How to align an object to a normal vector of a face?

 MrSparkle03 March 2006, 05:09 PMHi, I want to use to normal direction which is returned by the intersectRay function to align an object. The object's z-axis should point to the normal direction. I tried to directly manipulate the object's transform matrix but it failed: p2 = intersectRay \$ p1 \$.transform = matrix3 (normalize -(cross p2.dir [0,1,0])) [0,1,0] (normalize p2.dir) p2.pos Thanks, Christian
eek
03 March 2006, 05:16 PM
This might help (taken from maxscript help)

The following code implements the "Normal Align" feature of the UVW_Map modifier. The "Normal Align" button is not directly accessible to MAXScript. This function can be used as a replacement, and might help you understand the usefulness of the Vector Cross Product.

Script:

fn alignUVGizmo theObj theFace =

(

--First get the face normal vector.

--It is shown in BLUE on the image

faceNormal = incoordsys theObj (getFaceNormal theObj theFace)

--This is the desired up vector in world space

--It is shown in YELLOW on the image

worldUpVector = [0,0,1]

--Now get the cross-product of the face normal and the up vector.

--This will give you a vector that is perpendicular to the plane defined

--by the normal and the up vector. Normalize it to get a normal vector

--pointing to the right.

--It is shown in RED on the image

rightVector = normalize (cross worldUpVector faceNormal)

--Now using the face normal and the new vector,

--get a vector that is perpendicular to the plane defined by the two.

--This is the "local up vector", the vector that is the projection of

--the world up vector on the face you selected. This one is perpendicular

--to both the face normal and the right vector, and you have 3 normals now

--that define the X, Y and Z of your new orthogonal coordinate system

--for the UVW gizmo!

--Note that this new vector can be seen as the SHADOW of the World Up vector

--on the face of the object in the above image.

-- It is now displayed in green in the image below:

upVector = normalize ( cross rightVector faceNormal )

--Using the 3 vectors, define a matrix3 value which represents the

--coordinate system of the gizmo. The face normal is the Z axis,

--the right vector is the X axis, and the local up vector is the Y axis:

theMatrix = matrix3 rightVector upVector faceNormal [0,0,0]

theMap = Uvwmap()

theMap.gizmo.transform = theMatrix

)

MrSparkle
03 March 2006, 05:30 PM

Bobo
03 March 2006, 07:38 PM
Hi,
I want to use to normal direction which is returned by the intersectRay function to align an object. The object's z-axis should point to the normal direction.

I tried to directly manipulate the object's transform matrix but it failed:
p2 = intersectRay \$ p1
\$.transform = matrix3 (normalize -(cross p2.dir [0,1,0])) [0,1,0] (normalize p2.dir) p2.pos

Thanks,
Christian

Every Node in Max has a .DIR property which represent its Z axis. So in order to align an object to a normal, in the simplest case when you don't care about the rest of the axes, you can just assign the vector to that property.

(
s = sphere pos:[10,20,30]
theMesh = snapshotasmesh s
for f = 1 to theMesh.numfaces do
(
theClone = instance t
theClone.dir = getFaceNormal theMesh f
theClone.pos = meshop.getFaceCenter theMesh f
)
)

The other way would be to use MatrixFromNormal, set the .row4 to the position of the object and assign to the .transform property.

(
s = sphere pos:[10,20,30]
theMesh = snapshotasmesh s
for f = 1 to theMesh.numfaces do
(
theClone = instance t
theClone.transform = matrixFromNormal (getFaceNormal theMesh f)
theClone.pos = meshop.getFaceCenter theMesh f

--ALTERNATIVE:
-- theTM = matrixFromNormal (getFaceNormal theMesh f)
-- theTM.row4 = meshop.getFaceCenter theMesh f
-- theClone.transform = theTM
)
)

Of course, the example from the Online Help takes the UP vector into account, so it is much more general and advanced.