Page 1 of 2

(C++) Sin / Cos, directions and all that trig stuff

Posted: Wed Feb 01, 2006 7:18 am
by Nick_Japan
Hey all, like the new forum!

This is my code for making a node move 'forwards' in the direction it's facing. If you're bored of having to draw a load of triangles and SOH/CAH/TOA every time, here is the maths you want:

Code: Select all

    vector3df pos = node->getPosition();
    vector3df rot = node->getRotation();

    if(movingforwards)
    {
        f32 roty_rad = rot.Y * PI / 180; // convert to radians
        pos.Z += PLAYER_SPEED * cos(roty_rad);
        pos.X += PLAYER_SPEED * sin(roty_rad);
    }
    if(movingbackwards)
    {
        f32 roty_rad = rot.Y * PI / 180; // convert to radians
        pos.Z -= PLAYER_SPEED * cos(roty_rad);
        pos.X -= PLAYER_SPEED * sin(roty_rad);
    }
    if(strafingleft)
    {
        f32 roty_rad = rot.Y;
        roty_rad -= 90;
        roty_rad *= PI / 180;
        pos.Z += PLAYER_SPEED * cos(roty_rad);
        pos.X += PLAYER_SPEED * sin(roty_rad);
    }
    if(strafingright)
    {
        f32 roty_rad = rot.Y;
        roty_rad += 90;
        roty_rad *= PI / 180;
        pos.Z += PLAYER_SPEED * cos(roty_rad);
        pos.X += PLAYER_SPEED * sin(roty_rad);
    }
    if(turningleft)
    {
        rot.Y -= PLAYER_ROTATE;
    }
    if(turningright)
    {
        rot.Y += PLAYER_ROTATE;
    }
    node->setPosition(pos);
    node->setRotation(rot);
notes:
PLAYER_ROTATE and PLAYER_SPEED are just scale factors to adjust how fast the player can move and turn.
The sin/cos functions in math.h take the angle argument in radians, so we need to convert the y rotation value.
I've implemented strafing by simply adding or subtracting 90' to the angle and using the same code as moving forwards.

Posted: Wed Feb 01, 2006 3:38 pm
by majc
vector3df pos = node->getPosition();
vector3df rot = node->getRotation();

dont return any value, why?

Posted: Wed Feb 01, 2006 7:15 pm
by Eigen
Are you sure 'node' is the pointer of your object you're trying to move?


P.S - my first post here. Hey all! :)

-Eigen

Posted: Thu Feb 02, 2006 8:02 am
by Nick_Japan
Ah yes - as Eigen says, 'node' here is the node that's being moved forwards, so obviously I'm assuming you've initialised it properly first and everything. It's not intended for copy-and-paste, just to show how it's calculated and to stop everyone having to work it out themselves.

Posted: Thu Feb 02, 2006 11:52 am
by Spintz
FYI, I find all the trigonometry to be too much for this kind of implementation. IMO, it's better to keep track of Forward, Up and Right vectors. I don't have the code with me, I'm at work, but I can post it later, it only uses 3 dotProducts each frame, as opposed to 4 cosines and 4 sines.

Posted: Wed Feb 08, 2006 5:52 pm
by Quall
so, hows about a code snip-it for it? :P

Posted: Mon Feb 13, 2006 3:23 pm
by Spintz
Sorry, I forgot about this, here's code to calculate the vectors based on the camera target/position, for an FPS for example. The forward vector only requires a vector subtraction and a normalize. The right vector only requires a vector crossProduct( the WORLDUPVECTOR is ( 0, 1, 0 ) ) and a normalize. The up vector also only requires a single vector crossProduct and a normalize. So 1 vector subtraction, 2 vector crossProducts and 3 normalizes.

Here's the code -

Code: Select all

// Compute new forward vector
forwardVector = Camera->GetTarget() - Camera->GetPosition();
// Set the Y to 0 so the vectors are calculated on the XZ plane
forwardVector.Y = 0.0f;
forwardVector.normalize();
	
// Compute new right vector
rightVector = WORLDUPVECTOR.crossProduct ( m_forwardVector );
rightVector.normalize();
	
// Compute new up vector
upVector = m_forwardVector.crossProduct( rightVector );
upVector.normalize();

Posted: Sun Aug 06, 2006 1:04 pm
by RapchikProgrammer
Hey spintz and nick_japan! I cant seem to get your code working properly! Can you guys just make a small example of how to control a camera using dis, den it wud be really helpful!

Posted: Sun Aug 06, 2006 4:20 pm
by RapchikProgrammer
I finally found this code to move the camera forward and backward movement but if someone could help me on strafing it wud be really helpful!

Code: Select all

f32 speed = 30.0f;
vector3df mPos = cam->getPosition();
vector3df mView = cam->getTarget();
vector3df vVector = mView - mPos; // Get the view vector

mPos.X += vVector.X * speed;
mPos.Y += vVector.Y * speed;
mPos.Z += vVector.Z * speed;
		
cam->setPosition(mPos);

Posted: Mon Aug 07, 2006 1:39 pm
by TheGameMaker
just multiply the rotationmatrix of the node by the fector in unit coordinates, means, if you want to move 1 to side vector3df(1,0,0)
just multiply it with matrix4(getAbsoluteTransformation ())
simpel uh??

Posted: Mon Aug 07, 2006 3:36 pm
by Zeuss
Um, Surely the best way is to take the 3 rows out of the matrix.

1st Row = Forwards Vector
2nd Row = Up Vector
3rd Row = Right Direction Vector

code snippet:

Code: Select all

	matrix4 Mat = cam->getRelativeTransformation();

	core::vector3df Forwards	(Mat.M[0], Mat.M[1], Mat.M[2] );
	core::vector3df Up			(Mat.M[4], Mat.M[5], Mat.M[6] );
	core::vector3df Right		(Mat.M[8], Mat.M[9], Mat.M[10] );

I know this works, as this if the method i use for the camera in 3XTR3M3. Although its using a nodes position and direction. But same principles apply. Far simpler and CPU friendly compared to the trigonometry way.

Posted: Tue Aug 08, 2006 6:25 pm
by TheGameMaker
that works?? I never knew this.. thx. but by multiply a vector with this matrix you can move an object in Modell coordinate space.

Posted: Wed Aug 09, 2006 3:08 am
by Zeuss
That will give you direction vectors to move along, relating to the objects rotation. (the last row, stores the objects position).

Learning about how matrices work is very helpful.

Posted: Wed Aug 09, 2006 9:28 am
by TheGameMaker
yes it would be, indeed.... but I like my move(vecAbsoulte,vecRelativ) more.. its really helpfull to have functions like this even in times of oop.

Posted: Wed Aug 09, 2006 12:10 pm
by RapchikProgrammer
Thanx for the replies guys! But i still dont understand how to move the camera even if i have the forward vector, the right vector and the up vector! I mean when i press w its should move forward but from the method of zeuss we seem to get only the current vectors what to do with them to get the method to work? Im sorry for such a questin but i dont know a thing about the camera vectors and matrices!