Free Flight (space flight) functions

A forum to store posts deemed exceptionally wise and useful
BlindSide
Admin
Posts: 2821
Joined: Thu Dec 08, 2005 9:09 am
Location: NZ!

Post by BlindSide »

Cool this looks pretty useful. I was gonna go ahead and use Quats but I guess its not entirely necessary when you have this. (I might still have to use em over the network though, sending matrices can't be very efficient :P).
ShadowMapping for Irrlicht!: Get it here
Need help? Come on the IRC!: #irrlicht on irc://irc.freenode.net
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

MasterGod wrote:P.S
I've modified it just a bit to suit my movement animator which made it much more better now :D yay.. (though I didn't upload the changes, [not sure if 'yet'] - but it can all be accessed in my engine and I'll later edit this post with a link to the code)
Here it is:
http://nusoftwarege.svn.sourceforge.net ... iew=markup
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
squisher
Competition winner
Posts: 91
Joined: Sat May 17, 2008 2:23 am
Contact:

Post by squisher »

arras wrote:EXAMPLE CODE

Here is small example program which shows use of all free flight functions. You don't need any media to run it:
[edited 20.03.2008 this code should work with Irrlicht 1.4]
Thanks Arras, you have no idea how much this helped me!!
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Glad it still helps somebody :wink:
acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

Post by acropole »

it don't works for me.

When I rotatte the camera with the mouse it's ok, but when I move it with the keyboard the traget don't follow.

updateCamera is called every frame in the main loop

Code: Select all

#include "amhEventReceiver.h"
#include <fstream>
#include <string>

// on event
bool amhEventReceiver::OnEvent(const SEvent& event){
	
	if(event.EventType == EET_KEY_INPUT_EVENT){
		keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
	}
	if(event.EventType == EET_GUI_EVENT){
		return checkGuiEvent(event);
	}
	if(event.EventType == EET_MOUSE_INPUT_EVENT){
		onMouseEvent();
	}
	if(event.EventType == EET_LOG_TEXT_EVENT){
	}
	if(event.EventType == EET_USER_EVENT){
	}

	return false;
}

bool amhEventReceiver::onMouseEvent(void){
	if(Game->game_state == IN_GAME){
		position2di cursorPos = cursorControl->getPosition();

		if(cursorPos.X != centerPos.X || cursorPos.Y != centerPos.Y){

			cursorPos.X -= centerPos.X;
			cursorPos.Y -= centerPos.Y;

			yaw(mouseSpeed * cursorPos.X*PI/180.0f);
			pitch(mouseSpeed * cursorPos.Y*PI/180.0f);
			cursorControl->setPosition(centerPos);
		}
	}
	return true;
}

void amhEventReceiver::updateCamera(){ 
    // get transformation matrix of node 
    matrix4 m; 
    m.setRotationDegrees(node->getRotation()); 

    vector3df frv = vector3df (0.0f, 0.0f, 100.0f); 
    m.transformVect(frv); 
    
    vector3df upv = vector3df (0.0f, 1.0f, 0.0f); 
    m.transformVect(upv); 

    camera->setPosition(node->getPosition()); //position camera in front of the ship 
    camera->setUpVector(upv); //set up vector of camera 
	camera->setTarget(node->getAbsolutePosition() + frv); //set target of camera (look at point)
}

void amhEventReceiver::move(vector3df dir){
	matrix4 m; 
	m.setRotationDegrees(node->getRotation()); 
	m.transformVect(dir); 
	node->setPosition(node->getPosition() + dir);
}

void amhEventReceiver::rotate(vector3df rot) 
{ 
    matrix4 m; 
    m.setRotationDegrees(node->getRotation()); 
    matrix4 n; 
    n.setRotationDegrees(rot); 
    m *= n; 
    node->setRotation( m.getRotationDegrees() ); 
} 

//--- turn ship left or right --- 
void amhEventReceiver::yaw(f32 rot){ 
    rotate(vector3df(0.0f, rot, 0.0f) ); 
} 

//--- pitch ship up or down --- 
void amhEventReceiver::pitch(f32 rot){ 
    rotate(vector3df(rot, 0.0f, 0.0f) ); 
} 

//--- roll ship left or right --- 
void amhEventReceiver::roll(f32 rot){ 
    rotate(vector3df(0.0f, 0.0f, rot) ); 
}

// gui events
bool amhEventReceiver::checkGuiEvent(const SEvent& event){
	IGUIEnvironment* env = device->getGUIEnvironment();
	s32 id = event.GUIEvent.Caller->getID();

	switch(event.GUIEvent.EventType){
		case EGET_SCROLL_BAR_CHANGED:
			if (id == 104)	{
				s32 barpos = ((IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
				for (s32 i=0; i<EGDC_COUNT ; ++i){
					SColor col = env->getSkin()->getColor((EGUI_DEFAULT_COLOR)i);
					col.setAlpha(barpos);
					env->getSkin()->setColor((EGUI_DEFAULT_COLOR)i, col);
				}	
			}
			break;
		case EGET_BUTTON_CLICKED:
			if(id == 101){
				if(smgr->loadScene("media/maps/test01.irr")){
					Game->game_state = IN_GAME;
					cursorControl->setPosition(centerPos);

					node = smgr->addSceneNode("empty");

					target = smgr->addSceneNode("empty", node);
					target->setPosition(vector3df(0.0f, 100.0f, 0.0f));

					smgr->addCameraSceneNode(node);
					camera = smgr->getActiveCamera();

					smgr->getGUIEnvironment()->removeFocus(smgr->getGUIEnvironment()->getFocus());
				}
			}
			if(id == 103){
				Game->game_state = GAME_EXIT;
			}
		break;
	}
	return false;
}
// keyboards, mous and GUI events
void amhEventReceiver::checkKeys(){
	if(keys[KEY_ESCAPE])	Game->game_state = GAME_EXIT;

	if(keys[KEY_KEY_Z])		move(vector3df(0.0f, 0.0f, 1.0f));
	if(keys[KEY_KEY_S])		move(vector3df(0.0f, 0.0f, -1.0f));
	if(keys[KEY_KEY_Q])		move(vector3df(-1.0f, 0.0f, 0.0f));
	if(keys[KEY_KEY_D])		move(vector3df(1.0f, 0.0f, 0.0f));
	if(keys[KEY_SPACE])		move(vector3df(0.0f, 1.0f, 0.0f));
	if(keys[KEY_CONTROL])	move(vector3df(0.0f, -1.0f, 0.0f));
}

amhEventReceiver::amhEventReceiver(IrrlichtDevice* d, amhGame* g):
		mouseSpeed(3.0f)
{	
	device = d;
	Game = g;
	smgr = device->getSceneManager();
	cursorControl = device->getCursorControl();
	for(int i=0; i < KEY_KEY_CODES_COUNT; i++) 
		keys[i] = false;
	
	centerPos.X = device->getVideoDriver()->getViewPort().getWidth()/2;
	centerPos.Y = device->getVideoDriver()->getViewPort().getHeight()/2;

}

amhEventReceiver::~amhEventReceiver(void)
{
}
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Problem is certainly not in transformation code, as you see, cube in example on page 2 is controlled entirely with key commands and it works. So I suggest problem lies somewhere in your event handling code. Unfortunately I do not have time to test your code since I am currently up to my neck in work.

Bye the way I noticed you excluded offset from camera update function ...your camera is in center of mesh?
acropole
Posts: 17
Joined: Tue Feb 08, 2005 2:59 am
Contact:

Post by acropole »

Yes it is. If I add offset it don't resolve the problem.

It works better now, I change things like this :

Adding an empty node, child of the ship, wich is used as camera's target.

Code: Select all

					target = smgr->addSceneNode("empty", node);
					target->setPosition(vector3df(0.0f,0.0f,100.0f));
and using it in the update camera function, Not necessary to set the position (the camera is child of the node)

Code: Select all

matrix4 m; 
    m.setRotationDegrees(node->getRotation());
	vector3df upv = vector3df (0.0f, 1.0f, 0.0f); 
    m.transformVect(upv); 
    camera->setUpVector(upv);
	camera->setTarget(target->getAbsolutePosition());
problem : it shake a bit
Repgahroll
Posts: 88
Joined: Tue Jul 29, 2008 11:48 am

Post by Repgahroll »

Thanks Arras! Very useful! :D :D

But i wonder if its possible to use this example to roll a FPS camera??? I could not get it working...

Someone could help me here? I just want to make the thing 'recognize' the FPS camera coordinates.... (maybe the problem is that the fps camera doesnt affect the node, dunno)

Thanks in advance! :D

Arras, thank you very much! :D

Sorry my englishiz
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

I don't know if you can affect FPS camera like this since it handles its rotation and position differently. You have to control it by adjusting target vector and up vector.

You may look at my MCameraFPS and MCameraOrbit. You can find it in MCamera.h here: http://www.spintz.com/arras/Files/ShTlT ... 042008.zip
fabietto
Posts: 93
Joined: Wed Sep 24, 2008 4:38 pm
Location: Plymouth, UK
Contact:

Post by fabietto »

I'd like to thanks Arras for the great work he has done! I'm writing a kind of flight simulator and this code is extremely helpful to me.

I'm actually playing with these functions and I'd like to ask you a (maybe) stupid question. When I move a node it looks like I can't actually see the movement, but I just get the node in its final position. If I want to see the node moving smoothly from the starting point to the final one, should I use a fly straight animator as suggested for example in this topic (http://irrlicht.sourceforge.net/phpBB2/ ... e+movement)?

Many thanks,
Fabio
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Thanks fabietto.
I think you can use fly straight animator given you finished rotating your node towards end point. Otherwise it will look strange.

But you can move your node using move() function I provided, just set your speed so it looks smooth enough.

You can look at my SpaceFlight demo. These functions were taken strait from it.
cr33
Posts: 22
Joined: Fri Mar 27, 2009 3:37 pm

Post by cr33 »

old thread is old, but anyway.

Thank you all for such a deligthful piece of code. :)

However, it seems nobody has noticed that left/ right key bindings are swapped :P

should be:

Code: Select all

// direction control
        if(keys[irr::KEY_LEFT])
        {
            turn(node1, -0.1);
        }
        if(keys[irr::KEY_RIGHT])
        {
            turn(node1, 0.1);
        }
arras
Posts: 1622
Joined: Mon Apr 05, 2004 8:35 am
Location: Slovakia
Contact:

Post by arras »

Thanks, ...example code corrected :)
AW111
Posts: 82
Joined: Fri Jul 16, 2010 4:49 pm

Post by AW111 »

Arras mentioned that this code suffers from the dreaded 'gimbal lock' problem. Is there a version of it, or another freely available bit of code somewhere, that avoids this problem?
random
Posts: 158
Joined: Wed Aug 11, 2010 6:01 am

Post by random »

i had some problems with Gimbal Lock

As far as i know there are 3 ways to avoide a Gimbal Lock.

1) you can use a parented node to rotate X or Y axis but that might also result former or lader in a Gimbal Lock.

2) you can change the order but also this gives you no guarantee to avoid a gimbal lock

3) but most people use quaternions to avoid a gimbal lock this should avoid a gimbal lock.
Post Reply