Align node to terrain

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
JhimBhoy
Posts: 5
Joined: Sun Mar 23, 2008 5:41 pm

Align node to terrain

Post by JhimBhoy »

Hello everyone,

Im trying to align a node to the terrain so it looks like a fighter plane at very low level following the curves and banks of the terrain.

I'm totally new to Irrlicht and 3D maths so sorry if this is a blindingly stupid question. I've searched the forums for the answer and I thought arras 'free flight' functions were the answer.

Code: Select all

Removed old code
The weird thing is it works for short distances - I'm thinking perhaps there is a limit to how much you can rotate at one time. I've honestly no idea :oops:

Is there a way to align the node to the terrain and I'm just going about it the wrong way?

Thanks in advance :)
JhimBhoy
Posts: 5
Joined: Sun Mar 23, 2008 5:41 pm

Post by JhimBhoy »

Ok.

I've got yaw and roll to work by using an empty parent node to control the position and yaw and the main player node to control roll.

I then added a grandparent empty node to control pitch.

This doesn't work unfortunately.

Here's the code:

Code: Select all

	
        // set up previous rotation state
	float old_yaw=0, old_pitch=0, old_roll=0;

	while(device->run())
	if (device->isWindowActive())
	{
		if (quit)
		{
			device->closeDevice();
		}
		
		// Get delta time
		irr::u32 now = timer->getTime();
		delta_time = (now - then) / 1000.f;
		then = now; 

		get_input();

		player1.x+=sin(player1.dir*core::DEGTORAD)*(player1.speed*delta_time);
		player1.z+=cos(player1.dir*core::DEGTORAD)*(player1.speed*delta_time);

		// position fighter
		float yaw=player1.dir;
		float fighter_z=player1.z;
		float fighter_x=player1.x;
		float fighter_h=terrain->getHeight(fighter_x,fighter_z);
		fighter_grandparent->setPosition(core::vector3df(player1.x,fighter_h+80,player1.z));
		fighter->setPosition(core::vector3df(0,0,0));

		// get heights at wing tips
		float l = 80.0f; // length of ship/2
		float w = 40.0f; // width of ship/2
		float bx_yaw=yaw+90;
		if (bx_yaw>359) bx_yaw-=360;
		float bx1_x=fighter_x+sin((bx_yaw)*core::DEGTORAD)*w;
		float bx1_z=fighter_z+cos((bx_yaw)*core::DEGTORAD)*w;
		float bx2_x=fighter_x+sin((bx_yaw)*core::DEGTORAD)*-w;
		float bx2_z=fighter_z+cos((bx_yaw)*core::DEGTORAD)*-w;
		float z1 = terrain->getHeight(bx1_x,bx1_z);
		float z2 = terrain->getHeight(bx2_x,bx2_z);

		// get heights at nose/tail
		float bx3_x=fighter_x+sin((yaw)*core::DEGTORAD)*l;
		float bx3_z=fighter_z+cos((yaw)*core::DEGTORAD)*l;
		float bx4_x=fighter_x+sin((yaw)*core::DEGTORAD)*-l;
		float bx4_z=fighter_z+cos((yaw)*core::DEGTORAD)*-l;
		float x1 = terrain->getHeight(bx3_x,bx3_z);
		float x2 = terrain->getHeight(bx4_x,bx4_z);	
		
		// calc roll and pitch values
		float roll = atan(z1/40-z2/40)*core::RADTODEG; // the division is to compensate for scaling
		float pitch = atan(x2/40-x1/40)*core::RADTODEG;

		// get relative rotations
		float yaw_offset=yaw-old_yaw;
		float pitch_offset=pitch-old_pitch;
		float roll_offset=roll-old_roll;
		
		turn_ship(fighter_parent,yaw_offset);
		roll_ship(fighter,roll_offset);		
		pitch_ship(fighter_grandparent,pitch_offset);
	
		old_yaw=yaw;
		old_roll=roll;
		old_pitch=pitch;
		
		// position camera
		float cam_x=player1.x+(sin(player1.dir*core::DEGTORAD)*-600);
		float cam_z=player1.z+(cos(player1.dir*core::DEGTORAD)*-600);
		float cam_y=terrain->getHeight(cam_x,cam_z);
		
		float cam_diff=fighter_h-cam_y;
		float cam_target_x=sin(player1.dir*core::DEGTORAD)*(450+cam_diff);
		float cam_target_z=cos(player1.dir*core::DEGTORAD)*(450+cam_diff);
		camera->setPosition(core::vector3df(cam_x,cam_y+400,cam_z));
		camera->setTarget(core::vector3df(player1.x+(cam_target_x),cam_y+50,player1.z+(cam_target_z)));
		camera->updateAbsolutePosition();

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

		smgr->drawAll();
		env->drawAll();

		driver->endScene();

		// display frames per second in window title
		int fps = driver->getFPS();
		if (lastFPS != fps)
		{
			core::stringw str = L"Advanced Tactical Fighter - Demo [";
			str += driver->getName();
			str += "] FPS:";
			str += fps;
			str += "   ";

			device->setWindowCaption(str.c_str());
			lastFPS = fps;
		}
	}

	device->drop();
	
	return 0;
}

// Act on input
bool get_input()
{
		if (keys[irr::KEY_KEY_W] || keys[irr::KEY_UP])
		{
			player1.speed+=400*delta_time;
			if (player1.speed>1000) player1.speed=1000;
		}
		if (keys[irr::KEY_KEY_S] || keys[irr::KEY_DOWN])
		{
			player1.speed-=400*delta_time;
			if (player1.speed<-1000) player1.speed=-1000;
		}
		if (keys[irr::KEY_KEY_A] || keys[irr::KEY_LEFT])
		{
			player1.dir-=player1.turn_rate*delta_time;
			if (player1.dir<0) player1.dir+=360;
		}
		if (keys[irr::KEY_KEY_D] || keys[irr::KEY_RIGHT])
		{
			player1.dir+=player1.turn_rate*delta_time;
			if (player1.dir>359) player1.dir-=360;
		}

		return false;
}

void init_player()
{
	player1.x=2942;
	player1.y=0;
	player1.z=4143;
	player1.dir=0;
	player1.speed=0;
	player1.turn_rate=30;
}
//--- rotate node relative to its current rotation -used in turn,pitch,roll ---
void rotate(irr::scene::ISceneNode *node, irr::core::vector3df rot)
{
	irr::core::matrix4 m;
    m.setRotationDegrees(node->getRotation());
    irr::core::matrix4 n;
    n.setRotationDegrees(rot);
    m *= n;
    node->setRotation( m.getRotationDegrees() );
    node->updateAbsolutePosition(); 
}

//--- turn ship left or right ---
void turn_ship(irr::scene::ISceneNode *node, irr::f32 rot)
{
    rotate(node, irr::core::vector3df(0.0f, rot, 0.0f) );
}

//--- pitch ship up or down ---
void pitch_ship(irr::scene::ISceneNode *node, irr::f32 rot)
{
    rotate(node, irr::core::vector3df(rot, 0.0f, 0.0f) );
}

//--- roll ship left or right ---
void roll_ship(irr::scene::ISceneNode *node, irr::f32 rot)
{
    rotate(node, irr::core::vector3df(0.0f, 0.0f, rot) );
}
Anyone any ideas? I think I need to use quaternions but my 3D math is rubbish and I've barely understood 3D vectors.

This is probably really obvious and I just need a pointer in the right direction.

Here is a video of it running with yaw and roll:
http://www.youtube.com/watch?v=5EFzUC5PcpE
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Post by sudi »

i digged out some old solution i gave to someone.

http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=29529

that topic should help all relevant code is inside that topic.
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
JhimBhoy
Posts: 5
Joined: Sun Mar 23, 2008 5:41 pm

Post by JhimBhoy »

I'll give this a go.

Thank you Sudi :)
Post Reply