Rotation Nick Yaw Roll

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
Squarefox
Competition winner
Posts: 118
Joined: Tue Aug 19, 2008 6:46 pm
Location: Delta quadrant, Borg nexus 0001
Contact:

Rotation Nick Yaw Roll

Post by Squarefox »

Hello,

I want to apply nick, yaw and roll angles to a scene node. The nick yaw and roll angles are settable by keys.
I tried the following code. Sadly it results in some strange rotations if applying nick, yaw and roll angles.
If applying only one of these, it works. Can anyone help me with this?

Code: Select all

 
// position ship and camera
irr::core::vector3df angles = irr::core::vector3df(0.0f,0.0f,0.0f);
 
if (eventReceiver.IsKeyPressed(irr::EKEY_CODE::KEY_KEY_F))
{
    angles.X += 0.5f;
    angles.X -= (static_cast<int>(angles.X) / 360) * 360;
}
if (eventReceiver.IsKeyPressed(irr::EKEY_CODE::KEY_KEY_R))
{
    angles.X -= 0.5f;
    angles.X -= (static_cast<int>(angles.X) / 360) * 360;
}
if (eventReceiver.IsKeyPressed(irr::EKEY_CODE::KEY_KEY_E))
{
    angles.Y += 0.5f;
    angles.Y -= (static_cast<int>(angles.Y) / 360) * 360;
}
if (eventReceiver.IsKeyPressed(irr::EKEY_CODE::KEY_KEY_Q))
{
    angles.Y -= 0.5f;
    angles.Y -= (static_cast<int>(angles.Y) / 360) * 360;
}
if (eventReceiver.IsKeyPressed(irr::EKEY_CODE::KEY_KEY_A))
{
    angles.Z += 0.5f;
    angles.Z -= (static_cast<int>(angles.Z) / 360) * 360;
}
if (eventReceiver.IsKeyPressed(irr::EKEY_CODE::KEY_KEY_D))
{
    angles.Z -= 0.5f;
    angles.Z -= (static_cast<int>(angles.Z) / 360) * 360;
}
 
const double M_PI = 3.1415926535897932384626433832795028841971693993751;
const double M_DegToRad = M_PI / 180.0;
// factors for degree measure to radian measure
const double angleYawRAD = angles.Y * M_DegToRad;
const double angleNickRAD = angles.X * M_DegToRad;
const double angleRollRAD = angles.Z * M_DegToRad;
 
// compute sinus and cosinus values for the given angles
// for negative angles: cos(-x) = cos(x), sin(-x) = -sin(x)
const double cosAngleYaw = cos(angleYawRAD);    
const double sinAngleYaw = sin(angleYawRAD);
const double cosAngleNick = cos(angleNickRAD);
const double sinAngleNick = sin(angleNickRAD);
const double cosAngleRoll = cos(angleRollRAD);
const double sinAngleRoll = sin(angleRollRAD);
 
// compute new coordinate system vectors
// normalize for numerical stability
front = cosAngleYaw * front + sinAngleYaw * left;
front.normalize();
// use cross product for second vector (also for numerical stability)
left = front.crossProduct(up);
left.normalize();
 
front = cosAngleNick * front + sinAngleNick * up;
front.normalize();  
up = left.crossProduct(front);
up.normalize();
 
left = cosAngleRoll * left + sinAngleRoll * up;
left.normalize();
up = left.crossProduct(front);
up.normalize();
 
irr::core::matrix4 matrix;
matrix.buildCameraLookAtMatrixLH(irr::core::vector3df(0.0f,0.0f,0.0f),front,up);
angles = matrix.getRotationDegrees();
 
playerShip->setRotation(angles);
 
The initial values for front, left and up are:
irr::core::vector3df front = irr::core::vector3df(0.0f, 0.0f, 1.0f);
irr::core::vector3df left = irr::core::vector3df(1.0f, 0.0f, 0.0f);
irr::core::vector3df up = irr::core::vector3df(0.0f, 1.0f, 0.0f);

Regards,
Squarefox
mongoose7
Posts: 1227
Joined: Wed Apr 06, 2011 12:13 pm

Re: Rotation Nick Yaw Roll

Post by mongoose7 »

For flight, it is usual to apply roll first, then pitch and yaw.

Why don't you just set the ship: playerShip->setRotation(angle.X, angle.Y, angel.Z)?

I know you then have to work out the camera. But note that you are accumulating the angle, but also you incorporate the angles in the front, left and up vectors - a double accumulation.
Squarefox
Competition winner
Posts: 118
Joined: Tue Aug 19, 2008 6:46 pm
Location: Delta quadrant, Borg nexus 0001
Contact:

Re: Rotation Nick Yaw Roll

Post by Squarefox »

Because setRotation() does global coordinate transformations.
Image you first roll by 180°. Then do a yaw rotation. You would rotate in the opposite direction as specified.

I need to rotate around the axis of the local coordinate system.
Here a roll by 180° would also rotate the local coordinate system, so the next yaw rotation would give the correct result.
Squarefox
Competition winner
Posts: 118
Joined: Tue Aug 19, 2008 6:46 pm
Location: Delta quadrant, Borg nexus 0001
Contact:

Re: Rotation Nick Yaw Roll

Post by Squarefox »

Hi,

I now did some math by myself and solved it this way:

Code: Select all

 
// compute final angles
angles.Z = atan2(-left.Y,-left.X)*irr::core::RADTODEG;
const float tmp = atan2(up.Z,front.Z);
angles.X = tmp*irr::core::RADTODEG;
angles.Y = atan2(left.Z,front.Z/cos(tmp))*irr::core::RADTODEG;
 
// set rotation
playerShip->setRotation(angles);
 
It works now!

Regards,
Squarefox
AReichl
Posts: 269
Joined: Wed Jul 13, 2011 2:34 pm

Re: Rotation Nick Yaw Roll

Post by AReichl »

Post Reply