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

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Nick_Japan
Posts: 98
Joined: Mon Dec 13, 2004 11:47 am
Location: Japan

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

Post 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.
majc
Posts: 6
Joined: Wed Sep 14, 2005 7:04 pm

Post by majc »

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

dont return any value, why?
Eigen
Competition winner
Posts: 375
Joined: Fri Jan 27, 2006 2:01 pm
Location: Estonia
Contact:

Post 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
Nick_Japan
Posts: 98
Joined: Mon Dec 13, 2004 11:47 am
Location: Japan

Post 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.
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post 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.
Image
Quall
Posts: 154
Joined: Mon Mar 07, 2005 10:16 pm

Post by Quall »

so, hows about a code snip-it for it? :P
Spintz
Posts: 1688
Joined: Thu Nov 04, 2004 3:25 pm

Post 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();
Image
RapchikProgrammer
Posts: 279
Joined: Fri Dec 24, 2004 6:37 pm

Post 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!
RapchikProgrammer
Posts: 279
Joined: Fri Dec 24, 2004 6:37 pm

Post 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);
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post 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??
Zeuss
Posts: 114
Joined: Mon Nov 08, 2004 9:02 pm
Location: Canberra - Australia
Contact:

Post 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.
Help make Irrlicht even Better! Create and submit your own Irrlicht Extension
Want a Games Education? Try The Academy of Interactive Entertainment
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post 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.
Zeuss
Posts: 114
Joined: Mon Nov 08, 2004 9:02 pm
Location: Canberra - Australia
Contact:

Post 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.
Help make Irrlicht even Better! Create and submit your own Irrlicht Extension
Want a Games Education? Try The Academy of Interactive Entertainment
TheGameMaker
Posts: 275
Joined: Fri May 12, 2006 6:37 pm
Location: Germany

Post 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.
RapchikProgrammer
Posts: 279
Joined: Fri Dec 24, 2004 6:37 pm

Post 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!
Post Reply