PDA

View Full Version : ClosestPointOnMesh and Runtime expression


lab00
12-12-2007, 02:46 PM
Hi,
I've some particles arranged in a random way on a poly surface UV space (position of
particles is given by goalU & V = rand(0,1) and the poly surface is the goal object for
particles).
Because i've instanced an object to the particles and i wanted to orient these depending
on
the normal of the face which the particles is on, i used ClosestPointOnMesh node.
(I wished to use CPOM command but i'm using Maya 2008 and by what i knew there isn't
anymore CPOM command, but only the node, isn't it?)
So i attached the polySurface.worldMesh[0] to CPOM1.inMesh and i added this to the
particles runtime expression:

float $Nx, $Ny, $Nz;
vector $norm;
vector $pos = particleShape1.position;

setAttr closestPointOnMesh1.inPositionX ($pos.x);
setAttr closestPointOnMesh1.inPositionY ($pos.y);
setAttr closestPointOnMesh1.inPositionZ ($pos.z);

$Nx =`getAttr closestPointOnMesh1.normalX`;
$Ny =`getAttr closestPointOnMesh1.normalY`;
$Nz =`getAttr closestPointOnMesh1.normalZ`;

$norm = <<$Nx, $Ny, $Nz>>;


This works, and in $norm there is the normal vector of the face which the particle is on.
Despite i've always known that one shouldn't Never use setAttr and getAttr in a runtime
expression because of the resulting slowdown, i've used these here, because i didn't find
another way.
Infact if i used this instead:

float $Nx, $Ny, $Nz;
vector $norm;
vector $pos = particleShape1.position;

closestPointOnMesh1.inPositionX = $pos.x;
closestPointOnMesh1.inPositionY = $pos.y;
closestPointOnMesh1.inPositionZ = $pos.z;

$Nx = closestPointOnMesh1.normalX;
$Ny = closestPointOnMesh1.normalY;
$Nz = closestPointOnMesh1.normalZ;

$norm = <<$Nx, $Ny, $Nz>>;

it wouldn't work, because the $norm vector is filled with the same value for all the
particles, and i think this is because using `=` instead of setAttr and getAttr doesn't
make the DG refresh every particle cycle, instead it refresh only at the start of every
frame calculating the normal once in a frame and not once per particle.
Correct me if i'm wrong, please.

I would know if is it right to use setAttr and getAttr in this case(despite is very sloooww...) or if there is a better way to do this.

Thank you very much for the help.

ctp
12-13-2007, 01:31 AM
Select the particleShape and look in the AttributeEditor... there's a section there on the particleShape node that says "Goal Weights and Objects". Open that section and look for a button that says "create goalWorldNormal0PP". This will add such a perParticle attribute to your particleShape. Next, under the "Instancer (Geometry Replacement)" section, you can now choose the "AimDirection" to be based on the newly created goalWorldNormal0PP attribute.
You might have to adjust the alignment and freeze transformations of the object you instance... eg. if it's a cone, have it point along the x-axis, and have it's pivot at it's base, and tranforms all zero'ed out. (then move it away afterwards, if it gets in the way there at the origin :)

Hope that helps.

I'm using Maya 8.5, so I don't know about the commands in 2008. But in 8.5 the command is called "nearestPointOnMesh" (not listed in the docs - and remember to activate the plugin) whereas the node is called "closestPointOnMesh".

lab00
12-17-2007, 10:33 AM
Thak you very much and sorry for the long time i didn't reply, i'll try it soon.
Bye

CGTalk Moderation
12-17-2007, 10:33 AM
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.