T3D 1.1 Final - 3D math works fine ... nothing to see here ...
by Steve Acaster · in Torque 3D Professional · 06/14/2011 (4:52 pm) · 5 replies
T3D 1.1 Final
win7 32bit
target:
3D vector math
issue:
Using "localiszed" 3D vector math to get the angle from an object to another returns the wrong result if angle is > 180.
Using a forward facing vector (getForwardVector) of an object (rather than global Yaxis which works as expected), if the angle is >180 it appears that the returned result comes "via the path of least resistance" ... eg: if the angle should be 320 degrees it is actually returned as 40, as though the result has come from an anticlockwise count rather than the proper clockwise around the model count, thus making it impossible to tell which side of the first object the target object is on.
Repeat:
First up, add some scripts to do the math for us.
Note: I'm pretty sure my math is correct but obviously check.
Startup T3D so that you have a player in-game. Check the player's normal in the "getTransform()" is "global forwards (Y axis)", it'll make the first part of the test easier (0 1 0). Note the player's ID so you can call it from the console. I'm using PlayerID as an example here.
Create 2 new objects called "target"1 and "target2". Place them in-front of the player at a "guessed by eye" angle of around 45 degrees to the front of the player, with "target1" on the RIGHT and "target2" on the LEFT.
Now test the "global angle" of "target1". Type into the console:
It'll be somewhere around the 45 degree guess you made when placing "target1" in front and to the right of the player.
Next try the "local angle" from the player:
This should return something similar to what globalXYangle on "target1" did.
Now for the bit with the bug.
First test the "global angle" of "target2" on the left of the player. Type into the console:
It should come up with a result around 315 degrees. All is well.
Next try the "local angle" from the player:
And see that the result is NOT near 315 degrees, but around 45 degrees - as though it counted the closest direction of anticlockwise rather than going around the whole object in degrees like it should.
Also see that the echoes show not sign of this inversion so it's not like a script modifier can be added to show which side the result should be on.
Suggest:
Fix it!
Returning an angle based on a local get****Vector should always come from a clockwise direction going around the object and not counting backwards because it's closer.
win7 32bit
target:
3D vector math
issue:
Using "localiszed" 3D vector math to get the angle from an object to another returns the wrong result if angle is > 180.
Using a forward facing vector (getForwardVector) of an object (rather than global Yaxis which works as expected), if the angle is >180 it appears that the returned result comes "via the path of least resistance" ... eg: if the angle should be 320 degrees it is actually returned as 40, as though the result has come from an anticlockwise count rather than the proper clockwise around the model count, thus making it impossible to tell which side of the first object the target object is on.
Repeat:
First up, add some scripts to do the math for us.
//uses global Yaxis as forward vector
function globalXYangle(%posOne, %posTwo)// this actually works
{
%vec = VectorSub(%posOne, %posTwo);
//get the angle
%rotAngleZ = mATan( firstWord(%vec), getWord(%vec, 1) );
//add pi to the angle
%rotAngleZ += 3.14159;
echo("radians = " @ %rotAngleZ);
%rotAngleZ = mRadToDeg(%rotAngleZ);//yorks in - for returning a degree angle, take out if you want radians
echo("degrees = " @ %rotAngleZ);
return %rotAngleZ;
}
//uses local object orientation
function getVectorAngle(%vec1, %vec2)
{
%vec1n = VectorNormalize(%vec1);
%vec2n = VectorNormalize(%vec2);
%vdot = VectorDot(%vec1n, %vec2n);
echo("vdot = " @ %vdot);
%angle = mACos(%vdot);
echo("radians = " @ %angle);
// convert to degrees and return
%degangle = mRadToDeg(%angle);
return %degangle;
}
function getAngleTo(%obj, %tgt)
{
%angle = getVectorAngle(%obj.getForwardVector(), VectorSub(%tgt.getPosition(), %obj.getPosition()));
return %angle;
}Note: I'm pretty sure my math is correct but obviously check.
Startup T3D so that you have a player in-game. Check the player's normal in the "getTransform()" is "global forwards (Y axis)", it'll make the first part of the test easier (0 1 0). Note the player's ID so you can call it from the console. I'm using PlayerID as an example here.
Create 2 new objects called "target"1 and "target2". Place them in-front of the player at a "guessed by eye" angle of around 45 degrees to the front of the player, with "target1" on the RIGHT and "target2" on the LEFT.
Now test the "global angle" of "target1". Type into the console:
globalXYangle(playerID.getPosition(), target1.getPosition());
It'll be somewhere around the 45 degree guess you made when placing "target1" in front and to the right of the player.
Next try the "local angle" from the player:
getAngleTo(playerID, target1);
This should return something similar to what globalXYangle on "target1" did.
Now for the bit with the bug.
First test the "global angle" of "target2" on the left of the player. Type into the console:
globalXYangle(playerID.getPosition(), target2.getPosition());
It should come up with a result around 315 degrees. All is well.
Next try the "local angle" from the player:
getAngleTo(playerID, target2);
And see that the result is NOT near 315 degrees, but around 45 degrees - as though it counted the closest direction of anticlockwise rather than going around the whole object in degrees like it should.
Also see that the echoes show not sign of this inversion so it's not like a script modifier can be added to show which side the result should be on.
Suggest:
Fix it!
Returning an angle based on a local get****Vector should always come from a clockwise direction going around the object and not counting backwards because it's closer.
About the author
One Bloke ... In His Bedroom ... Making Indie Games ...
#2
However none of my previously working "getAngle" functions are returning anything valid. They all use mATan.
Sean, do you have a "get360Angle" script I can test? I still think something is dodgy in the 3D math area ...
[EDIT]
And now everything is working fine and as expected! :)
... nothing to see here ... move along ... wft!?
06/15/2011 (5:19 am)
Well, that would explain that then ... I probably shouldn't file bug reports on math at 2am ;)However none of my previously working "getAngle" functions are returning anything valid. They all use mATan.
Sean, do you have a "get360Angle" script I can test? I still think something is dodgy in the 3D math area ...
[EDIT]
And now everything is working fine and as expected! :)
... nothing to see here ... move along ... wft!?
#3
06/15/2011 (8:12 am)
lol! Dot products are fun!
#5
3d vector maths can be tedious. something which is so easy to visualize is a pain in the ass to obtain a numerical value for. my personal favorite is using the cross product and visualizing right hand curl while having to visualize a left hand curl for everything else in torque. =)
06/15/2011 (7:11 pm)
glad you got it sorted out Steve.3d vector maths can be tedious. something which is so easy to visualize is a pain in the ass to obtain a numerical value for. my personal favorite is using the cross product and visualizing right hand curl while having to visualize a left hand curl for everything else in torque. =)
Torque 3D Owner Sean H.