[SOLVED}Help with moving a character

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
kohaar
Posts: 61
Joined: Tue Oct 17, 2006 12:15 am
Contact:

[SOLVED}Help with moving a character

Post by kohaar »

Hi. I'm trying to move a character to a specified position, similar to waypoints, but the character seems to move in an entirely different position than the one specified. Can you please look through the code and see if you can give me any pointers.

Most of the code is from this example: http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=12238


Code: Select all

    // Current possition
	float tx0 = node_zombie->getPosition().X;
	float tz0 = node_zombie->getPosition().Z;
	// Moveto position
	float tx1 = movepos.X;
	float tz1 = movepos.Z;
	
	// Rotation of character and heading
	float a = abs(tz1-tz0);
	float b = abs(tx1-tx0);
	float c = sqrt( pow(a,2) + pow(b,2) );
	float rotation = sin(a/c);
	rotation *= (180/PI);
	node_zombie->setRotation(vector3df(0,rotation,0));
	
	// Translation position
    tPos.Z=(float)cos(rotation*(PI/180))*4.1f;
	tPos.X=-(float)sin(rotation*(PI/180))*4.1f;

	// Tryout collision
	dPos = CGameMain::getSceneManager()->getSceneCollisionManager()->getCollisionResultPosition(CCollision::getCollision(), 
	       oldPos, vector3df(10.0f,10.0f,10.0f), tPos, triout, gravity, 0.05f, vector3df(0.0f,-3.0f,0.0f));
  
	// Setposition
	node_zombie->setPosition(dPos);
Last edited by kohaar on Tue Dec 05, 2006 9:16 am, edited 1 time in total.
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

its much simpler to deal with vectors as whole units, rather than breaking them into x,y and z and using trig.

Code: Select all

  // u32 timeSinceLastLoop is the number of ms since the last animation frame
  // f32 speed is in units per ms 
  f32 distance = (f32)timeSinceLastLoop * speed;
  vector3df direction(0,0,1); // the direction your node is facing
  pos = node->getPosition();
  node->getRelativeTransformation().rotateVect(direction);
  pos += direction * distance;
  node->setPosition(pos);
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
kohaar
Posts: 61
Joined: Tue Oct 17, 2006 12:15 am
Contact:

Post by kohaar »

I'm not sure what you mean by dealing with the vector as a whole unit?

If I have a position that I want to move to, and I want to change the direction in comparison to the current position, I need trig, don't I?

Code: Select all

                  Destination

                / |
              /   |
            /     |
          /       |
        /         |
        ---------
  Current pos
Also I need collision detection, since I am moving my character through a b3d terrain.
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

ah, i see. you still don't need to mess about with trig though, the vector class does it all for you.

Code: Select all

// to get the direction
vector3df direction = (destination-pos).normalize();
// to get the angle-
f32 angle = direction.getHorizontalAngle();
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
kohaar
Posts: 61
Joined: Tue Oct 17, 2006 12:15 am
Contact:

Post by kohaar »

Your my hero. It works like a charm! Thanks.

Here is the working code, if anyone should encounter similar problems.

Code: Select all

// Move an object to a destination. vector3df movepos is the destination
void CZombie::move()
{
   vector3df oldPos = node_zombie->getPosition();;
   vector3df tPos;
   triangle3df triout; 
   bool gravity = true;

   if(oldPos.getDistanceFrom(movepos) >= 100)
   {
	  vector3df direction = (movepos-oldPos).normalize();
	  
	  // The minus 90 could be that my character is rotated on import
	  f32 angle = direction.getHorizontalAngle().Y-90;

	  node_zombie->setRotation(vector3df(0,angle,0));
	
	  // Translation position - Movement should be framerate independent. 
      tPos.Z=direction.Z*4.1f;
	  tPos.X=direction.X*4.1f;

	  // Tryout collision - CCollision getcollision is the triangleselector for the environment
	  vector3df dPos = CGameMain::getSceneManager()->getSceneCollisionManager()->getCollisionResultPosition(CCollision::getCollision(), 
	       oldPos, vector3df(10.0f,10.0f,10.0f), tPos, triout, gravity, 0.05f, vector3df(0.0f,-3.0f,0.0f));
  
	  // Setposition
	  node_zombie->setPosition(dPos);

	  waypoint = false;
   }
   else
   {
	   waypoint = true;
   }
}
Nox587
Posts: 12
Joined: Mon Jul 10, 2006 6:42 pm

Post by Nox587 »

Looks like a pretty good solution, curious about one thing though:

Code: Select all

   // Translation position - Movement should be framerate independent.
      tPos.Z=direction.Z*4.1f;
     tPos.X=direction.X*4.1f; 
Your comment says movement should be framerate independent, but you are multiplying by a constant.

If you want 4.1 to be your speed you should multiply it by the frame time.

biplane's first bit of code shows this:

Code: Select all

// u32 timeSinceLastLoop is the number of ms since the last animation frame
  // f32 speed is in units per ms
  f32 distance = (f32)timeSinceLastLoop * speed; 
This thread also has some good information regarding frame rate independant movement:
http://irrlicht.sourceforge.net/phpBB2/ ... .php?t=723
Post Reply