Jump to content

Object Rotation


SpiderPig
 Share

Go to solution Solved by Josh,

Recommended Posts

Getting the rotation of an object doesn't seem to go past 90 degrees on any one axis.  E.g. I turn the box along the x axis but it only just gets to 90 degrees then starts counting down again and the y and z axis flip to 180 at around 45 degrees as it counts down on the x.  This probably has something to do with quaternions but I do not know for sure.

RotationError.thumb.png.cbb35237e07f574d5d007da33c2acfa9.png

#include "Engine.h"
using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    auto displays = GetDisplays();
    auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, displays[0]);
    auto world = CreateWorld();
    auto framebuffer = CreateFramebuffer(window);

    auto camera = CreateCamera(world);
    camera->SetClearColor(0.0f, 0.0f, 1.0f);
    camera->SetFov(70);
    camera->SetRange(0.01f, 1000.0f);
    camera->SetPosition(0, 1, -3);

    auto light = CreateDirectionalLight(world);
    light->SetColor(5.0f);
    light->SetRotation(35, 45, 0);

    auto font = LoadFont("Fonts/arial.ttf");
    auto ui = CreateInterface(world, font, framebuffer->size);
    ui->SetRenderLayers(2);
    ui->root->SetColor(0, 0, 0, 0);

    auto ui_cam = CreateCamera(world, PROJECTION_ORTHOGRAPHIC);
    ui_cam->SetPosition(framebuffer->size.x / 2, framebuffer->size.y / 2, 0);
    ui_cam->SetRenderLayers(2);
    ui_cam->SetClearMode(CLEAR_DEPTH);

    auto label = CreateLabel("", 10, 10, 200, 30, ui->root);

    auto box = CreateBox(world);

    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        box->Turn(0.25f, 0.0f, 0.0f);

        auto local = box->GetRotation();
        auto global = box->GetRotation(true);
        label->SetText("Local : " + String(local.x) + ", " + String(local.y) + ", " + String(local.z) + "\n"
            "Global : " + String(global.x) + ", " + String(global.y) + ", " + String(global.z));

        world->Update();
        world->Render(framebuffer, false);
    }
    return 0;
}

 

Link to comment
Share on other sites

  • Solution

Yes, you answered your own question.

Euler angles are easy for humans to understand, but they cannot accurately describe all rotations. When the pitch approaches 90 degrees, there is no way to describe the roll accurately, because at that angle the pitch and roll are the same. This is called Gimbal lock:

Gimbal_Lock_Plane.gif

This has even caused problems in space missions. I can't find the exact clip, but they talk about this in the movie "Apollo 13".

Quaternions are an exact description, but you need a degree in mathematics to understand them. In fact there is an entire book I hope to some day read named simply "Visualizing Quaternions":
https://www.elsevier.com/books/visualizing-quaternions/hanson/978-0-12-088400-1

Each entity stores its rotation in both Euler and quaternion form, and these are kept in sync whenever rotation changes. The Turn method uses quaternions to accurately turn the entity, and then fills in the entity's Euler rotation value by converting it from the resulting quaternion.

So everything is correct.

  • Thanks 1

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Okay thanks.  I need to read that book too.  I don't know enough about them.  

3 hours ago, Josh said:

Each entity stores its rotation in both Euler and quaternion form, and these are kept in sync whenever rotation changes. The Turn method uses quaternions to accurately turn the entity, and then fills in the entity's Euler rotation value by converting it from the resulting quaternion.

 I want to rotate an object back and forth on the x axis between 0 and 90 degrees.  I thought GetRotation() should return Euler angles?

Link to comment
Share on other sites

If you are only rotating on one axis you can use SetRotation instead of Turn and the Euler angles you set won't be modified. Or you can just store the pitch in a variable, and increment that and call SetRotation every frame using that variable for the pitch.

  • Thanks 1

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...