Game Development Community

Get in C++ the Z rotation like in script via GetTransform

by Martin Schultz · in Torque Game Engine · 01/18/2007 (7:38 am) · 3 replies

Hi guys,

I need help. I have a script (found in the forums) that outputs the positive or negative angle between two objects. Need that for driving my AI vehicle. Here's the original script, that works pretty good:
function playerToTargetAngleScript(%posTarget)
{
	//RETURNS THE ANGLE TO TARGET
	//TAKING THE PLAYERS CURRENT HEADING INTO CONSIDERATION
	
	//GET THE CURRENT TRANSFORM OF THE PLAYER
	%myCurrentTransform = $PLAYEROBJECT.GetTransform();
   
	//GET THE ANGLE TOWARD THE TARGET
	%distFromTarget = VectorSub(%myCurrentTransform, %posTarget);
	%distFromTarget = VectorNormalize(%distFromTarget);
	%xValue = getWord(%distFromTarget,0);
	%yValue = getWord(%distFromTarget,1);
	%myAngle = mAtan(%xValue,%yValue);
	
	//KEEP IT BETWEEN 0 AND 2PI
	if (%myAngle != 0)
	{
		%myAngle += 3.141592;            
		while(%myAngle > 6.283185)
			%myAngle -= 6.283185;
	}
	
	//DETERMINE THE OFFSET BETWEEN CURRENT ANGLE AND TARGET ANGLE
	[b]%currentAngle = getWord(%myCurrentTransform,6);[/b]
	%angleDiff = %myAngle - %currentAngle;
         
	//KEEP IT BETWEEN 0 AND 2PI
	while(%angleDiff < 0)
		%angleDiff += 6.283185;
            
	while(%angleDiff > 6.283185)
		%angleDiff -= 6.283185;
         
	//ADJUST THE OFFSET TO TAKE THE SHORT WAY AROUND IN RADIANS
	if(%angleDiff > 3.141592)
		%angleDiff -= 6.283185;
			
	//RETURN THE ANGLE AND DIRECTION WE NEED TO TURN
	error("angleDiff 2: " @ %angleDiff);
	return %angleDiff;
}

Now I thought I transfer this script into C++ code to have it available directly in the corresponding AI class. I started and got stuck at the bold marked line:
[b]%currentAngle = getWord(%myCurrentTransform,6);[/b]
What I learned so far is that this line copies the very last parameter out of a script-based getTransform() call. So, if I dump my players getTransform in the console, this is the output:
playerObj.getTransform(): 171.098 -19.8115 176.311 0.285065 -0.881662 -0.376037 [b]0.115968[/b]
The bold marked value is the one I'd like to have. I search now a long time and read a hundreds of posts, but I still don't understand how I get this last parameter within the C++ code. If I understood it right, the script based getTransform output is an output of the position (first 3 values) and the rotation as quaternion (net 4 params). But how do I get this rotation as quaternion within C++? Does anyone have a clue?

Thanks for any help :)
Martin

#1
01/18/2007 (7:56 am)
Open up engine\sim\sceneObject.cc:

Have a look at this code:
ConsoleMethod( SceneObject, getTransform, const char*, 2, 2, "Get transform of object.")
{
   char *returnBuffer = Con::getReturnBuffer(256);
   const MatrixF& mat = object->getTransform();
   Point3F pos;
   mat.getColumn(3,&pos);
[b]   AngAxisF aa(mat);[/b]
   dSprintf(returnBuffer,256,"%g %g %g %g %g %g %g",
            pos.x,pos.y,pos.z,aa.axis.x,aa.axis.y,aa.axis.z,[b]aa.angle[/b]);
   return returnBuffer;
}

That's how they do it in C++. Always remember, if you want to perform an operation in C++, which can be performed in script, just look for the ConsoleMethod or ConsoleFunction. You'll usually find your answers there.
#2
01/18/2007 (8:16 am)
Ahhhhhhhhhhhhhhh I feel so stupid... :-)

Thanks a lot Michael, you're my hero for today!

Here's the final method for anyone who wants to do too driving AI:
F32 playerToTargetAngle() 
{
	// Kudos to Randall who wrote the original code in TorqueScript!

	// get the current transform of the plaxer
	Point3F pos = getPosition();

	// get the angle torward the target. Assumes that mMoveDestination is set!
	Point3F distFromTarget = pos - mMoveDestination;
	distFromTarget.normalizeSafe();
	F32 myAngle = mAtan(distFromTarget.x, distFromTarget.y);

	// Keep the angle between 0 and 2PI
	if (myAngle != 0)
	{
		myAngle += Float_Pi;            
		while(myAngle > Float_2Pi)
			myAngle -= Float_2Pi;
	}

	// Determine the offset between current angle and target angle
	const MatrixF& mat = getTransform();
	Point3F rot;
	mat.getColumn(3,&rot);
	AngAxisF aa(mat);
	F32 currentAngle = aa.angle;
	F32 angleDiff = myAngle - currentAngle;
				

	// Keep it between 0 and 2PI
	while(angleDiff < 0)
		angleDiff += Float_2Pi;

	while(angleDiff > Float_2Pi)
		angleDiff -= Float_2Pi;

	if(angleDiff > Float_Pi)
		angleDiff -= Float_2Pi;
	
	return angleDiff;
}

Martin :-)
#3
01/19/2007 (7:49 am)
Argh. The above is crap. Does only work for some certain angles. Better use Badguy's getSteeringAngle(). It works pretty accurat and flawless! Just posting this if someone aimed to use the above code. Don't do so. :-)