Direction Vector To Rotation Matrix

34,906

Solution 1

struct Mat3x3
{
    Vec3 column1;
    Vec3 column2;
    Vec3 column3;

    void makeRotationDir(const Vec3& direction, const Vec3& up = Vec3(0,1,0))
    {
        Vec3 xaxis = Vec3::Cross(up, direction);
        xaxis.normalizeFast();

        Vec3 yaxis = Vec3::Cross(direction, xaxis);
        yaxis.normalizeFast();

        column1.x = xaxis.x;
        column1.y = yaxis.x;
        column1.z = direction.x;

        column2.x = xaxis.y;
        column2.y = yaxis.y;
        column2.z = direction.y;

        column3.x = xaxis.z;
        column3.y = yaxis.z;
        column3.z = direction.z;
    }
}

Solution 2

To do what you want to do in your comment, you also need to know the previous orientation of youe Player. Actually, the best thing to do is to store all the data about position and orientation of your player (and almost anything else in a game) into a 4x4 matrix. This is done by "adding" a fourth column and and fourth row to the 3x3 rotation matrix, and use the extra column to store the information about the player position. The math behind this (homogeneous coordinates) is quite simple and very important in both OpenGL and DirectX. I suggest you this great tutorial http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/ Now, to rotate your player towards your enemy, using GLM, you can do this:

1) In your player and enemy classes, declare a matrix and 3d vector for the position

glm::mat4 matrix;
glm::vec3 position;

2) rotate towards enemy with

player.matrix =  glm::LookAt(
player.position, // position of the player
enemy.position,   // position of the enemy
vec3(0.0f,1.0f,0.0f) );        // the up direction 

3) to rotate the enemy towards the player, do

enemy.matrix =  glm::LookAt(
enemy.position, // position of the player
player.position,   // position of the enemy
vec3(0.0f,1.0f,0.0f) );        // the up direction 

If you want to store everything in the matrix, don't declare the position as a variable but as a function

vec3 position(){
    return vec3(matrix[3][0],matrix[3][1],matrix[3][2])
}

and rotate with

player.matrix =  glm::LookAt(
player.position(), // position of the player
enemy.position(),   // position of the enemy
vec3(0.0f,1.0f,0.0f) );        // the up direction 
Share:
34,906

Related videos on Youtube

UfnCod3r
Author by

UfnCod3r

Crazy Programmer && Alone :((

Updated on February 16, 2020

Comments

  • UfnCod3r
    UfnCod3r about 4 years

    How To Create Rotation matrix From Direction (unit vector)

    My Matrix Is 3x3, Column Major, And Right Hand

    I Know 'column1' is right, 'column2' is up and 'column3' is forward

    But I Can`t Do This.

    //3x3, Right Hand
    struct Mat3x3
    {
        Vec3 column1;
        Vec3 column2;
        Vec3 column3;
    
        void makeRotationDir(const Vec3& direction)
        {
            //:((
        }
    }
    
    • 6502
      6502 over 10 years
      For a rotation matrix you need a direction vector (e.g. an axis) and an angle. Given just a direction what rotation are you talking about?
    • UfnCod3r
      UfnCod3r over 10 years
      i want to do this: Vec3 dirToEnemy = (Enemy.Position - Player.Position).normalize(); Player.Matrix.makeRotationDir(dir); Player.Attack();
    • SigTerm
      SigTerm over 10 years
      @6502: no, for rotation matrix you can also use three vectors (x, y, z)
    • 6502
      6502 over 10 years
      @SigTerm: you are of course free to define a function that given whatever you like (including the name of a pet dog) returns a rotation: it's not illegal and you won't end up in jail. But three real numbers with x^2+y^2+z^2=1 is not enough even from a dimensional point of view (there are more rotations around the origin than points on a unit sphere).
    • SigTerm
      SigTerm over 10 years
      @6502: 3 VECTORS, where each vector has 3 components and defines axis (x, y, z) of local coordinate system within global coordinate system, which will form 3x3 rotation matrix. You could also use euler angles for rotation. OR 3 points. Or quaternions.
    • 6502
      6502 over 10 years
      @SigTerm: three vectors or three points (9 components) are too much for a canonical specification, and it's not what is asked in the question (where a single direction of length 1 is specified). I thought you simply had a typo in the comment.
  • Viktor Sehr
    Viktor Sehr over 9 years
    So if direction corresponds to up no rotation is applied?