jediknightcode
jediknightcode

Reputation: 383

Problem when trying to rotate a 2D shape in a 3D space

i'm working on a batch renderer and i'm having trouble implementing a rotation feature for 2D shapes like a rectangle or a triangle. I'm using a Vertex* (struct Vertex code below) to store the position and color values, which works pretty well, until i got to rotations.

struct Vertex
{
    glm::vec3 position;
    glm::vec4 color;
};

I tried to make a mat4 and use the corresponding rotation function accordingly, which worked well when i set the model view projection in the shader, but converting the data to a Vertex wasn't working and very laggy. Therefore i thought i use some math that i found online, but my squares that i drew were streched to rectangles sometimes and the positions were off. I put in alot of hours now and tried different stuff, but nothing worked. That's why i hope someone can maybe find an obvious bug in my code or direct me to a good source where i can read about this topic (the stuff i found was either irrelevant for my purposes or hard to understand).

Here is my summarized code, i tried to keep it as short as possible:

void rotateX(float angle) 
{
    yr = yr * cos(angle) - zr * sin(angle);
    zr = zr * cos(angle) + yr * sin(angle);
}

void rotateY(float angle)
{
    xr = xr * cos(angle) - zr * sin(angle);
    zr = zr * cos(angle) + xr * sin(angle);
}

void rotateZ(float angle)
{
    xr = xr * cos(angle) - yr * sin(angle);
    yr = yr * cos(angle) + xr * sin(angle);
}

std::array<Vertex, 4> createQuad(glm::vec3 pos, glm::vec3 rotation, glm::vec4 rgba)
{
    float xr = 1.0f;
    float yr = 1.0f;
    float zr = 1.0f;

    rotateX(rotation.x);
    rotateY(rotation.y);
    rotateZ(rotation.z);

    Vertex v0;
    v0.position = glm::vec3(pos.x,      pos.y + yr, pos.z);
    v0.color = rgba;

    Vertex v1;
    v1.position = glm::vec3(pos.x + xr, pos.y + yr, pos.z);
    v1.color = rgba;

    Vertex v2;
    v2.position = glm::vec3(pos.x + xr, pos.y, pos.z + zr);
    v2.color = rgba;

    Vertex v3;
    v3.position = glm::vec3(pos.x,      pos.y, pos.z + zr);
    v3.color = rgba;

    return { v0, v1, v2, v3 };
}

Other notes:

  1. When i remove the rotate()'s and the '+ yr' the code works fine. I'm not 100% sure about the '+ yr', but i don't know how to rotate around the y-axis then.
  2. Accessing the elements of the mat4 with '[][]' wasn't giving me the right values and it was REALLY laggy for some reason. That's why i'm trying to avoid that if possible and go with raw math.

I'm going to bed for now, it's really late and i have a headache... hopefully my question wasn't too nooby or stupid, in that case i'm sorry for bothering you. Thanks in advance for any help!

Upvotes: 0

Views: 222

Answers (1)

Beta
Beta

Reputation: 99094

First, change your rotate functions to accept a vector as an argument, rather than apply the rotations to globals (or whatever those are).

Then instead of one vector:

r = {1, 1, 1}

use two:

r = {1, 0, 0}
s = {0, 1, 0}

Rotate them both (using the same angle arguments), then construct the square. (I don't know the syntax of a glm::vec3, but this is simple vector addition):

Vertex v0 = pos;

Vertex v1 = pos + r;

Vertex v2 = pos + r + s;

Vertex v3 = pos + s;

Upvotes: 1

Related Questions