Problem storing world matrix into a float array during loop

Hi there.
I’ve been trying to solve this simple yet persistent problem for over a week and I think I’ve hit a dead end.
I was wondering if anyone could help me out here.

When I try to get the world matrix from an object by storing its information into a float array, like the example below, it works just fine:

float $matrix[] = getAttr object.worldMatrix;

But once I place this inside a for loop it gives me some “weird” numbers. So far I couldn’t figure out why, during the for loop, the same line won’t get the correct world matrix.

I’ll try to explain what I’m trying to do and what’s happening. Plus Im posting the code in case anyone would like to try for yourself.

I wrote a few lines of MEL to make sure the spine joints of my auto-rig will have the X axis as the twisting axis and the Y axis always facing forward(world positive Z). Got it to work just fine, but if the spine (or any joint) is straight up, the Y axis will point towards the world negative X axis (after the joint orient).

So I wrote the following code to rotate the X axis so that the Y axis will always point forward.
I first orient the spine xyz with Y world up. Then I go one by one, get the worldMatrix, check the axis vectors then according to the result it will rotate the x axis.

joint -e -oj “xyz” -sao “yup” -ch ($name + “_COG_C_joint”);
select -r -hi ($name + “_Spine1_C_joint”);
string $sel[] = ls -sl;

for($i=0; $i < size($sel); $i++){

float $mat[] = `getAttr ($sel[$i] + ".worldMatrix")`;//here's the problem

if($mat[2] &gt; $mat[6] && $mat[4] == 0){
    rotate 180 0 0 ($sel[$i] + ".rotateAxis");
} else if($mat[4]&gt;0 && $mat[6] == 0){
    rotate 90 0 0 ($sel[$i] + ".rotateAxis");
} else if($mat[4]&lt;0 && $mat[6] == 0){
    rotate -90 0 0 ($sel[$i] + ".rotateAxis");
}; 

};

After the loop “fixes” the first spine joint, it will bypass all other joints.
After checking each variable, I found out the array was giving these following numbers below. After the first joint, all other joints were giving the same “weird” numbers. As far as I know the axis vectors are normalized and will always add up to 1(I didn’t change the scale at all).

$mat[2] = -7.850462293e-17 (Xz)
$mat[4] = 0 (Yx)
$mat[6] = 7.850462293e-17 (Yz)

But if I do it manually, before or after the loop, the values are the following:

$mat[2] = 0 (Xz)
$mat[4] = -1 (Yx)
$mat[6] = 0 (Yz)

I hope my explanation is not too vague. Is hard trying to explain it in a few lines.
If you ever had this problem and/or know the answer, please help me out.
Thanks.
Dimitri

I just tried the another loop with the following line:
float $tz = getAttr object.translateZ;
It’s giving me “weird” values…
Is there a problem where Maya will store random values inside variables?
Some sort of memory problem perhaps…
thanks.

The “odd” values you are seeing are perfectly normal, and are a result of the way floating-point numbers are handled by the CPU. -7.850462293e-17 is exponential notation for -0.00000000000000007850462293. That number is damn near close to 0, but not exactly zero which is why the comparison is failing. This is why you should never compare against and exact floating point number. What you want to do instead is compare against an epsilon value like this:


float $a = -7.850462293e-17;
float $b = 0.0;
float $epsilon = 0.00001;

if( abs($b - $a) <= $epsilon )
    print("These are equal");

Maya has two commands that do this already: equivalent and equivalentTol.

Here’s some “light” reading

http://realtimecollisiondetection.net/blog/?p=89

Thank you so much!
I feel silly for calling them “weird” numbers.
I got the script to work and now I know more about floats.
I’m gonna read it right now.
Thanks!