7
\$\begingroup\$

I have a vector that describes change in movement, and I have a 3d-vector, m_rot, that describes a rotation given to an object. I want to calculate a direction vector using both this data. How to achieve that?

I tried to multiply the components of a direction vector onto sin and cos of m_rot values, but that gave me nothing.

direction.x = direction.x * ::cosf(m_rot.x);  
direction.y = direction.y * ::sinf(m_rot.y);   
this->camera_world_pos += direction;

But after that my camera still walks into a simple directions, and not a direction that it looks at.

\$\endgroup\$

1 Answer 1

9
\$\begingroup\$

It sounds like what you're looking for is either a transformation matrix, or a quaternion.

Transformation Matrix

I will just run down how to do this using a transformation matrix, since its probably the easier of the two to understand. A transformation matrix in 3D is a 4x4 matrix defined as follows:

H = [xx, yx, zx, tx;
     xy, yy, zy, ty;
     xz, yz, zz, tz;
      0,  0,  0,  1];

Basically, it defines a coordinate frame with respect to another coordinate frame. In the transformation matrix, the column vector [xx, xy, xz] represents the x-axis of the coordinate frame, [yx, yy, yz] is the y-axis, and [zx, zy, zz] is the z-axis. The vector [tx, ty, tz] is the origin of the coordinate frame.

View Matrix

What you want to do is assign a transformation matrix H_camera to your character or camera. You will want to set it up such that the z axis of the transformation represents the direction the camera is looking. The y axis represents the "up" direction of the camera, and the x axis is the "left" direction, given by y x z. The vector [tx, ty, tz] will be the position of the camera in the world. In other words, it will look like this:

H_camera = [   |                |               |                 |
              left_vector ... up_vector ... forward_vector ... translation
               |                |               |                 |
               0                0               0                 1      ];

Say you want the character to move forward along the direction of the camera. Well, that's easy. You just extract forward_vector from H_camera and set that as the player's velocity. Similarly, you can add scalings of up_vector and left_vector to move the player up and to the left relative to his viewpoint.

Changing the View Matrix

Now, to make the camera move around, you just have to change the translation vector. To rotate the camera, you can do one of several things. You can either:

  1. Multiply the view matrix by a rotation matrix: Create a rotation matrix around the X, Y, or Z axis and multiply the view matrix with it. Pre-multiplying a view matrix by a rotation matrix means "rotate in the global coordinate frame", post-multiplying a view matrix by a rotation matrix means "rotate in the local coordinate frame". A rotation matrix is a special kind of transformation matrix that has no translation, only rotation. For instance, a rotation around the Z axis looks like this:

    R_z = [cos(t), -sin(t), 0, 0; sin(t), cos(t), 0, 0; 0, 0, 0, 1];

Or

  1. Construct the view matrix by having it "look" at a point in space: Another useful tool to have is to be able to construct the view matrix by looking at a point in space. Given an origin of the camera t_camera, a point to look at t_look, and an up vector up, we can say:

    forward_camera = (t_look - t_camera).normalized();

    left_camera = up.cross(forward_camera).normalized();

    up_camera = forward_camera.cross(left_camera).normalized();

    translation_camera = t_look;

\$\endgroup\$
2
  • \$\begingroup\$ Considering "look at camera": what is an up vector and why does it needed? What if I want to move down? \$\endgroup\$
    – PaulD
    Dec 25, 2014 at 9:27
  • \$\begingroup\$ Take your hand and raise it above your head. From your viewpoint, that direction is "up". Suppose you were upside-down, but still looking in the same direction. Then your "up" vector is now pointing in the opposite direction! The up vector is used to disambiguate between these cases. If you want the player to be right-side up, your up vector should point away from the ground. To move down, simply move along -1 * up_vector \$\endgroup\$
    – mklingen
    Dec 26, 2014 at 14:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .