PDA

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


MrSparkle
03-28-2006, 04:09 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

eek
03-28-2006, 04: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()

modPanel.addModToSelection theMap ui:on

theMap.gizmo.transform = theMatrix



)

MrSparkle
03-28-2006, 04:30 PM
Thank you for your quick reply! This helped me very much.

Bobo
03-28-2006, 06: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]
t = teapot radius:5
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]
t = teapot radius:5
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.

Finally, shameless plug, you could buy my new DVD to learn more... ;)

MrSparkle
03-28-2006, 11:49 PM
Thanks, Bobo. This is even easier and need less code - and it works, too.

CGTalk Moderation
03-28-2006, 11:49 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.