Skip to main content

History: Tutorial 9

Source of version: 5 (current)

Copy to clipboard
            !!My mouse said move did it not?
Wow, this is fun. We have a sky, we have some terrain, and we even have a plane. But the controls suck, and flies like a rock.
Guess we better do something about that then. We are going to be working exclusively with TutorialFrameListener.
First we need to add some variables to the header file. These variables need to be added below -+mbFirstPerson+-:
{CODE(wrap="1", colors="c++")}Real mfAfterburner;
Real mfSpeed;
Real mfPitch;
Real mfYaw;
Real mfRoll;
Real mfShipRoll;
Real mfShipPitch;
float rotX;
float rotY;{CODE}

Now we are going to change the code in -+TutorialFrameListener::frameStarted()+-. First, delete the code that is associated with the checks of -+KC_UP+-, -+KC_DOWN+-, -+KC_LEFT+- and -+KC_RIGHT+-. All you should have left in the method is the following:
{CODE(wrap="1", colors="c++")}bool TutorialFrameListener::frameStarted(const FrameEvent& evt)
{
    Real MoveFactor = 80.0 * evt.timeSinceLastFrame;
    mInputDevice->capture();
    if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
        return false;
    if(mInputDevice->isKeyDown(Ogre::KC_F))
    {
        while (mInputDevice->isKeyDown(Ogre::KC_F))
        mInputDevice->capture();
        if (mbFirstPerson)
        {
            // third person
            mCameraNode->setPosition( Vector3( 0, 50, -200) );
            mbFirstPerson = false;
        }
        else
        {
            // first person
            mCameraNode->setPosition( Vector3( 0, 5, 40) );
            mbFirstPerson = true;
        };
    }
    return true;
}{CODE}

Now add the following code after the check for -+KC_ESCAPE+- and before the check for -+KC_F+-:
{CODE(wrap="1", colors="c++")}// Increase speed
if (mInputDevice->isKeyDown(KC_EQUALS) || mInputDevice->isKeyDown(KC_ADD))
{
    mfSpeed += 10;
    if (mfSpeed > 200)
        mfSpeed = 200;
}
// Decrease speed
if (mInputDevice->isKeyDown(KC_MINUS) || mInputDevice->isKeyDown(KC_SUBTRACT))
{
    mfSpeed -= 5;
    if (mfSpeed < 0)
        mfSpeed = 0;
}
// hit our afterburners
mfAfterburner = 0;
if (mInputDevice->isKeyDown(KC_TAB) )
{
    mfAfterburner = 500;
}{CODE}
This code adjusts our speed, faster, slower, or afterburners.
{CODE(wrap="1", colors="c++")}rotX = -mInputDevice->getMouseRelativeX() * 0.5;
rotY = mInputDevice->getMouseRelativeY() * 0.5;
// process mfYaw (rudder function):
mfYaw += rotX;
mfShipRoll -= rotX / 5;
// process mfPitch (elevator function):
mfPitch += rotY;
mfShipPitch += rotY / 5;
if (mfPitch > 45) // (higher value, turn sharper)
    mfPitch = 45;
if (mfPitch < -45)
    mfPitch = -45;
if (mfYaw > 45)
    mfYaw = 45;
if (mfYaw < -45)
    mfYaw = -45;
if (mfRoll > 45)
    mfRoll = 45;
if (mfRoll < -45)
    mfRoll = -45;
if (mfShipPitch > 35)
    mfShipPitch = 35;
if (mfShipPitch < -35)
    mfShipPitch = -35;
if (mfShipRoll > 90)
    mfShipRoll = 90;
if (mfShipRoll < -90)
    mfShipRoll = -90;{CODE}
We use our mouse to get yaw and pitch values. We do a valid values check so we don’t get odd behavior.
{CODE(wrap="1", colors="c++")}// dampen the changes
mfPitch *= 0.9;
mfYaw *= 0.9;
mfRoll *= 0.9;
mfShipPitch *= 0.95;
mfShipRoll *= 0.95;{CODE}
Let’s remove the angle changes over time. Basically the ship will re-center.
{CODE(wrap="1", colors="c++")}// set angles for controlNode
if ((Math::Abs( mfPitch ) > 0.01) ||
    (Math::Abs( mfYaw ) > 0.01) ||
    (Math::Abs( mfRoll ) > 0.01))
{
    mControlNode->roll(Radian (Degree (mfRoll * evt.timeSinceLastFrame )));
    mControlNode->pitch(Radian (Degree  (mfPitch * evt.timeSinceLastFrame )));
    mControlNode->yaw(Radian (Degree( mfYaw * evt.timeSinceLastFrame )));
};{CODE}
Adjust the controlNodes angles, this will change our view of the terrain.
{CODE(wrap="1", colors="c++")}// set angles for ship node to make it looked banked in third person
if ((Math::Abs( mfShipRoll ) > 0.01) ||
    (Math::Abs( mfShipPitch ) > 0.01))
{
    Quaternion qRoll, qPitch;
    qRoll.FromAngleAxis(Radian (Degree (mfShipRoll)), Vector3::UNIT_Z);
    qPitch.FromAngleAxis(Radian (Degree (mfShipPitch)), Vector3::UNIT_X);    
    mShipNode->setOrientation( qRoll * qPitch );
};{CODE}
This is cool. In third person, the ship will roll doing a turn and pitch when going up and down.
{CODE(wrap="1", colors="c++")}static Vector3 vec;
vec = Vector3::ZERO;
vec.z = (mfSpeed + mfAfterburner) * evt.timeSinceLastFrame;
// Translate the controlNode by the speed
Vector3 trans = mControlNode->getOrientation() * vec;
mControlNode->translate(trans);{CODE}
This little bit of code will move us around the terrain a number of units depending on the speed in the
direction we are looking.

__Ok, COMPILE AND RUN!!!!!!!!!__

{img fileId="1632" thumb="y" alt="xorekis9_1.png" rel="box[g]"} 

If everything worked as planned. You should have aircraft like controls now, and can fly your ship around.
If someone else comes up with a better way of doing aircraft controls, I would be interested in updating this
tutorial.

__Congratulation, You have created a Simple Flight Simulator With Ogre !!! __ :)

((Tutorial 10))