0

I have been trying to figure this out for a while now. i am building a space ship with 6DOF movement. I have implement pitch and yaw, but I can't figure out how to move the ship forward at its current angle. E.g. If the user yaws to right at 25 degrees, then pitchs up at 10 degrees, I would need the ship to then move forward at this new angle.

Note: I default the yaw and pitch at 0.0 degrees in the class constructor.

As an example I have the following code to move the ship right on yaw:

void Player::yawRight(float deltaTime)
{
    this->yaw -= this->rotationAngle * deltaTime;

    if (this->yaw < 0.0f) {
        this->yaw = 360.0f;
    }

    cout << "yawRight: " + to_string(this->yaw) << endl;

    this->yawQuat = glm::angleAxis(glm::radians(this->yaw), glm::vec3(0, 1, 0));
    this->pitchQuat = glm::angleAxis(glm::radians(this->pitch), glm::vec3(0, 0, 1));
    this->rollQuat = glm::angleAxis(glm::radians(this->roll), glm::vec3(1, 0, 0));

    glm::mat4 rotationMatrix = glm::toMat4(glm::normalize(this->yawQuat * this->pitchQuat * this->rollQuat));

    this->model = glm::mat4(1.0f);
    this->model = glm::translate(this->model, this->position) * rotationMatrix;
}

I have three quats (yawQuat, pitchQuat and rollQuat). This current method updates the yaw angle. I multiply the quats, normalize them and convert them to matrix. While the above code works fine for yaw, the following code for accelerate just doesn't:

void Player::accelerate(float deltaTime)
{
    float x = cos(glm::radians(this->yaw)) * cos(glm::radians(this->pitch));
    float y = sin(glm::radians(this->pitch));
    float z = sin(glm::radians(this->yaw)) * cos(glm::radians(this->pitch));

    glm::vec3 front = glm::vec3(x,y,z);
    front = glm::normalize(front);

    glm::mat4 rotationMatrix = glm::toMat4(glm::normalize(this->yawQuat * this->pitchQuat * this->rollQuat));

    this->position += front * 0.01f;

    this->model = glm::mat4(1.0f);
    this->model = glm::translate(this->model, this->position) * rotationMatrix;
}

I am calculating the x,y and z to get the front vector. I then update the position of the model with the front vector multiplied by speed (0.0f in this case). This results in the object moving at the wrong angle. Can someone tell what I am doing wrong here? Thank you.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Aaron Z
  • 258
  • 2
  • 9
  • Imagine the front of your space ship is pointing into x direction (the rear into -x direction). Without any rotation, the velocity vector is `v3 = speed * (1, 0, 0)`. `speed` is the value of velocity, `(1, 0, 0)` is the direction. You may extend it to a homogeneous coordinate for multiplication with `gl::mat4`: `v4 = speed * (1, 0, 0, 0)`. Now, you can multiply your rotation matrix to `v4`: `d4 = rotationMatrix * v4`. To get the translation per frame, you still have to divide `d4` by the duration per frame (the time-step): `d4 = 1.0 / tStep * v4`. – Scheff's Cat Dec 02 '18 at 07:29
  • ... x, y, z of `d4` are now the translation vector of your spaceship. So, you can add x, y, z of `d4` to position of space ship. Btw. I usually store coordinates of objects in a matrix (mat4). This allows to store position and orientation at once. (I care to store nothing else - no scaling, no skew, no projection - to simplify things. So, I can just multiply temporary transformations (model, view, projection) from the left. I can also apply permantent transformations (e.g. due to movement like in your case) to that matrix the same way. (I believe in the latter case from the right...) – Scheff's Cat Dec 02 '18 at 07:35

0 Answers0