simple chopper control

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

simple chopper control

Post by smso »

Simple control codes for your helicopter / chopper scene node.

Updated: 18 June, 2012

http://code.google.com/p/irrcodes/downl ... 062012.zip

Make sure the forward direction of the scene node is along the z axis.
ctor:
ChopperControl* chopperControl = new ChopperControl(device, node);

In the device run loop:

while(device->run())
if (device->isWindowActive())
{
chopperControl->update();

driver->beginScene(true, true, 0);
smgr->drawAll();

chopperControl->drawLandingGuide(selector, 0xFFFF0000);

driver->endScene();
...
}


dtor:
if (chopperControl) { delete chopperControl; chopperControl = 0; }

In the event receiver class:

class EventReceiver: public IEventReceiver
{
public:

virtual bool OnEvent(const SEvent& event)
{
if (chopperControl)
chopperControl->OnEvent(event);
...
}



Regards
smso
Last edited by smso on Mon Jun 18, 2012 5:31 am, edited 6 times in total.
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: simple chopper control

Post by smso »

Add updateCockpitCamera() function to ChopperControl:

In header file:

Code: Select all

        virtual void updateCockpitCamera
        (
                scene::ICameraSceneNode* camera,
                const core::vector3df& cameraOffset = core::vector3df(0.0f)
        );
 
In src file:

Code: Select all

void ChopperControl::updateCockpitCamera
(
        scene::ICameraSceneNode* camera,
        const core::vector3df& cameraOffset
)
{
        this->updateAbsolutePosition();
        
        // target:
        camera->updateAbsolutePosition();
        core::vector3df camPos = camera->getAbsolutePosition();
        core::vector3df targetVector = camera->getTarget() - camPos;
        
        core::vector3df forward = core::vector3df(0.0f, 0.0f, 1.0f);
        core::matrix4 pitchMatrix = PitchEmpty->getAbsoluteTransformation();
        pitchMatrix.rotateVect(forward);
        forward.normalize();
        
        
        
        // pos:
        core::vector3df pos = RootEmpty->getAbsolutePosition();
        
        
        // up:
        core::vector3df upVector = core::vector3df(0.0f, 1.0f, 0.0f);
        core::matrix4 rollMatrix = RollEmpty->getAbsoluteTransformation();
        rollMatrix.rotateVect(upVector);
        upVector.normalize();
        
        core::vector3df offset = cameraOffset;
        rollMatrix.rotateVect(offset);
 
        // set cam prop.
        camera->setTarget(forward * targetVector.getLength() + pos + offset);
        camera->setPosition(pos + offset);
        camera->setUpVector(upVector);
}
 
Regards
smso
teto
Posts: 159
Joined: Thu Dec 03, 2009 9:37 pm
Location: /home
Contact:

Re: simple chopper control

Post by teto »

could you provide a binary for testing ?
Using trunk with mingw/gcc 4.6, Windows 7 64 bits driver opengl
netpipe
Posts: 669
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

Re: simple chopper control

Post by netpipe »

this is awesome thanks ... WEEEE

http://i.imgur.com/7TGcn.png
Live long and phosphor!
-- https://github.com/netpipe/Luna Game Engine Status 95%
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: simple chopper control

Post by smso »

teto wrote:could you provide a binary for testing ?
See:
http://irrlicht.sourceforge.net/forum/v ... =9&t=46250
for an example to use the ChopperControl class.

Regards
smso
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: simple chopper control

Post by smso »

Added:

Code: Select all

void resetCockpitView();
and
codes to control cockpit view by mouse.

Try:
Press F4 to switch between cockpit view and 3rd person view.
When in cockpit view, move mouse to rotate view.
Press V to reset cockpit view.

See my first post to download the updated files.

Sorry the files are growing fat :)

Regards
smso
ACE247
Posts: 704
Joined: Tue Mar 16, 2010 12:31 am

Re: simple chopper control

Post by ACE247 »

Great work smso! :D
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: simple chopper control

Post by smso »

New bugs-fixed version available. (Or see link at first post)

http://code.google.com/p/irrcodes/downl ... 062012.zip

Added:
1. HUD
2. topview camera
3. model files of uh1

Screenshot of cockpit view:
http://code.google.com/p/irrcodes/downl ... enshot.png

Press 'F1' for the help screen.

Regards
smso
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: simple chopper control

Post by smso »

To make the chopper roll to yaw (, in other words, to couple yaw and roll action) for easier handling, change the 2 functions of class ChopperControl as follows:

Code: Select all

void ChopperControl::update()
{
        u32 time = Device->getTimer()->getTime();
        f32 deltaTime = f32(time - LastTime) * 0.001f;
        
        if (IsResettingRoll)
        {
                f32 t = (time - ResetRollStartTime) * 0.001f;
                f32 interpolate = 1.0f - exp(- RATE_CONSTANT * t);
                //printf("interpolate=%f\n", interpolate);
                
                f32 rollAngleDegs = (1.0f - interpolate) * OldRollAngleDegs;
                RollEmpty->setRotation(core::vector3df(0.0f, 0.0f, rollAngleDegs));
                
                if (interpolate > STOPPING_INTERPOLATE)
                {
                        RollEmpty->setRotation(core::vector3df(0.0f));
                        IsResettingRoll = false;
                }
        }
        
        if (IsResettingPitch)
        {
                f32 t = (time - ResetPitchStartTime) * 0.001f;
 
                f32 interpolate = 0.0f;
                f32 pitchAngleDegs = 0.0f;
 
                if (PitchEmptyTargetRot.X == 0.0f)
                {
                        interpolate = 1.0f - exp(- RATE_CONSTANT * t);
                        pitchAngleDegs = (1.0f - interpolate) * OldPitchAngleDegs;
                }
                else if (PitchEmptyTargetRot.X > 0.0f)
                {
                        interpolate = 1.0f - exp(- RATE_CONSTANT * t);
                        pitchAngleDegs = OldPitchAngleDegs + interpolate * (180.0f - OldPitchAngleDegs);
                }
                else if (PitchEmptyTargetRot.X < 0.0f)
                {
                        interpolate = exp(RATE_CONSTANT * t);
                        pitchAngleDegs = OldPitchAngleDegs + (1.0f - interpolate) * (OldPitchAngleDegs + 180.0f);
                }
                
                PitchEmpty->setRotation(core::vector3df(pitchAngleDegs, 0.0f, 0.0f));
                if (interpolate > STOPPING_INTERPOLATE)
                {
                        PitchEmpty->setRotation(PitchEmptyTargetRot);
                        IsResettingPitch = false;
                }
        }
        
        if (IsResettingHover)
        {
                f32 t = (time - ResetHoverStartTime) * 0.001f;
                f32 interpolate = 1.0f - exp(- RATE_CONSTANT * t);
                
                Power = (1.0f - interpolate) * (OldPower - HOVER_POWER) + HOVER_POWER;
                
                if (interpolate > STOPPING_INTERPOLATE)
                {
                        Power = HOVER_POWER;
                        IsResettingHover = false;
                }
        }
        
        if (IsResettingCockpitView)
        {
                f32 t = (time - ResetCockpitViewStartTime) * 0.001f;
                f32 interpolate = 1.0f - exp(- RATE_CONSTANT * t);
                
                f32 yawAngleDegs = (1.0f - interpolate) * OldCameraYawAngleDegs;
                CameraYawEmpty->setRotation(core::vector3df(0.0f, yawAngleDegs, 0.0f));
 
                f32 pitchAngleDegs = (1.0f - interpolate) * OldCameraPitchAngleDegs;
                CameraPitchEmpty->setRotation(core::vector3df(pitchAngleDegs, 0.0f, 0.0f));
                
                if (interpolate > STOPPING_INTERPOLATE)
                {
                        CameraYawEmpty->setRotation(core::vector3df(0.0f));
                        CameraPitchEmpty->setRotation(core::vector3df(0.0f));
                        IsResettingCockpitView = false;
                }
        }
 
        
        ////////////////////////////////////////////////////////////////////////////
        // sideway movement:
        f32 rollEmptyRotZ = RollEmpty->getRotation().Z;
        f32 pitchEmptyRotX = PitchEmpty->getRotation().X;
        
        if (Power > 0.0f)
        {
                f32 x = - SIDEWAY_SPEED_CONST * sin(rollEmptyRotZ * core::DEGTORAD) * Power * deltaTime;
                f32 z = FORWARD_SPEED_CONST * sin(pitchEmptyRotX * core::DEGTORAD) * Power * deltaTime;
                
                if ((pitchEmptyRotX > 90.0f) && (pitchEmptyRotX < 270.0f))
                {
                        this->moveInLocalXDir(-x);
                        this->moveInLocalZDir(-z);
                }
                else
                {
                        this->moveInLocalXDir(x);
                        this->moveInLocalZDir(z);
                }       
        }
 
        ////////////////////////////////////////////////////////////////////////////
        // Pressing 'Q' and 'E' now do rolling to yaw instead of rolling alone
        // roll to yaw:
        f32 rollToYawRate = 30.0f;
        f32 yawDegs = 0.0f;
        if ((pitchEmptyRotX > 90.0f) && (pitchEmptyRotX < 270.0f)) // inverted
                yawDegs = sin(RollEmpty->getRotation().Z * core::DEGTORAD) * deltaTime * rollToYawRate;
        else
                yawDegs = - sin(RollEmpty->getRotation().Z * core::DEGTORAD) * deltaTime * rollToYawRate;
        
        this->yaw(yawDegs);
        ////////////////////////////////////////////////////////////////////////////
        
        // ascend:
        this->ascend(deltaTime);
        
        // rotate cockpit view:
        this->rotateCockpitView();
        
        LastTime = time;
}

Code: Select all

bool ChopperControl::OnEvent(const SEvent& event)
{
                ...
                else if (event.KeyInput.Key == irr::KEY_KEY_R) //
                {
                        this->resetRoll();
                }
                else if (event.KeyInput.Key == irr::KEY_KEY_T) //
                {
                        this->resetRoll();
                        this->resetPitch();
                }
                ...
}
Regards,
smso
Post Reply