View Full Version : Polygon Angle Relative to Camera Angle?

 AtrusDni06 June 2007, 03:44 AMHey Guys, im working on a script that would help in projection mapping objects. It would work like this: First you import a Boujou( or any camera track) into maya. Then make your model that you want to project. Finally the script would look at each polygon of the model for the entire sequence, and, when the polygon is most facing the camera, it would create a shader with the image sequence mapped to it and assign it to the face. The part that I am completely stumped on is determining the angle of a polygon to the camera. I am no math wiz, and would really appreciate any explanations to the math / syntax involved. I know I can get the normal's vector with polyInfo, and what I am thinking of is getting the world vector of the camera, getting the normal vector of the face, and comparing the two. I have heard of an inverse matrix mentioned on these forums before, is that what I should be after? Any information would be greatly appreciated. Thanks guys.
AtrusDni
06 June 2007, 05:29 PM
Anybody? Does anyone have any ideas?

_stev_
06 June 2007, 10:45 PM
Well, I can help with the math. Say you have your face normal, and camera vector (pointing away from object).

Vector1 = face normal
Vector2 = camera vector

So you want to loop through your faces and find the smallest angle between the two vectors.

angleBetween = acos ( dot vector1 vector2 )

Here you find the dot product of the two vectors (the vector's should be normalized), and get the arc cosine of that. This gives you the angle between the two vectors. Loop through all faces and take the smallest one. That's the one that is facing the camera.

Let me know if you need help with the syntax part (I don't have Maya right now).

Later,
Stev

_stev_
06 June 2007, 03:30 AM
This proc will return the index of the face most facing the camera. The proc arguments are the polyObject and the camera.

global proc int sakFindFacingFace (string \$obj, string \$camera) {
string \$allNormals[] = `polyInfo -fn \$obj`;
vector \$normals[];
float \$camMtx[] = `xform -q -m \$camera`;
vector \$camVec = <<\$camMtx[8],\$camMtx[9],\$camMtx[10]>>;

for (\$i=0;\$i<size(\$allNormals);\$i++) {
string \$tmp[];
string \$tmp2[];
tokenize \$allNormals[\$i] ":" \$tmp;
tokenize \$tmp[1] " " \$tmp2;
float \$pooX = \$tmp2[0];
float \$pooY = \$tmp2[1];
float \$pooZ = \$tmp2[2];
vector \$tmpVec = <<\$pooX,\$pooY,\$pooZ>>;
\$normals[\$i] = \$tmpVec;
}

float \$smallestAngle = 180.0;
int \$faceIndex = 0;

for (\$f=0;\$f<size(\$normals);\$f++) {
if (`acos (dot(\$normals[\$f], \$camVec))` < \$smallestAngle) {
\$smallestAngle = `acos (dot(\$normals[\$f], \$camVec))`;
\$faceIndex = \$f;
}
}

return \$faceIndex;
}

This is the important part:
acos (dot(\$normals[\$f], \$camVec))

Whenever this is smallest, the poly is most facing the camera.

Kind of the reverse of what you want to do, but you'd do it the same way. So you would get the face normal at each frame loop through that, each time checking to see if the angle has gotten smaller.

Stev

_stev_
06 June 2007, 04:27 AM
So this proc will work with one face for a time range:

global proc int sakFindFacingFrame (string \$faceObj, string \$camera) {
float \$startTime = `playbackOptions -q -minTime`;
float \$endTime = `playbackOptions -q -maxTime`;
float \$smallestAngle = 180.0;
int \$frame = 0;

for (\$i=\$startTime;\$i<=\$endTime;\$i++) {
currentTime -e \$i;
float \$camMtx[] = `xform -q -m \$camera`;
vector \$camVec = <<\$camMtx[8],\$camMtx[9],\$camMtx[10]>>;
string \$tmp[];
string \$tmp2[];
string \$normalInfo[] = `polyInfo -fn \$faceObj`;
tokenize \$normalInfo[0] ":" \$tmp;
tokenize \$tmp[1] " " \$tmp2;
float \$pooX = \$tmp2[0];
float \$pooY = \$tmp2[1];
float \$pooZ = \$tmp2[2];
vector \$tmpVec = <<\$pooX,\$pooY,\$pooZ>>;

if (`acos (dot(\$tmpVec, \$camVec))` < \$smallestAngle) {
\$smallestAngle = `acos (dot(\$tmpVec, \$camVec))`;
\$frame = \$i;
}
}
return \$frame;
}

To use the proc give it a face and a camera.

sakFindFacingFrame pSphere1.f[232] camera1

This one works the same as the first one I posted, but instead of looping through the faces, it loops through the time range.

Stev

AtrusDni
06 June 2007, 05:14 PM
awesome! thanks _stev_! You rock! :thumbsup::bounce::buttrock:

CGTalk Moderation
06 June 2007, 05:14 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.

1