Page 4 of 5

Posted: Sat Mar 29, 2008 3:49 pm
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).

Posted: Sat Mar 29, 2008 10:39 pm
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

Posted: Sun May 18, 2008 7:13 pm
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!!

Posted: Mon May 19, 2008 3:09 pm
by arras
Glad it still helps somebody :wink:

Posted: Wed Jun 25, 2008 12:43 pm
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)
{
}

Posted: Thu Jun 26, 2008 8:13 am
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?

Posted: Thu Jun 26, 2008 8:27 am
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

Posted: Sun Aug 03, 2008 7:20 pm
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

Posted: Wed Aug 06, 2008 9:10 am
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

Posted: Tue Nov 04, 2008 3:41 pm
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

Posted: Mon Nov 10, 2008 10:17 pm
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.

Posted: Sun Jun 14, 2009 6:05 pm
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);
        }

Posted: Sun Jun 14, 2009 6:23 pm
by arras
Thanks, ...example code corrected :)

Posted: Tue Jan 11, 2011 9:06 pm
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?

Posted: Sat Feb 19, 2011 3:24 am
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.