(C ++ и OpenGL) Я пытаюсь повернуть группу вершин (которые будут имитировать квадрат) в пакетном рендерере, но он не работает на 100% :( - PullRequest
2 голосов
/ 01 августа 2020

Я пытаюсь повернуть объект или группу из 4 вершин, которые находятся внутри пакетного рендеринга (это динамический c, поэтому он может обновлять свои вершины и индексы в любое время).

В настоящее время я использую метод под названием «Матрица Родригеса», который я научился использовать благодаря этому сообщению на StackExchange

И он работает очень хорошо, но проблема в том, что центр всех объектов в пакете (0, 0, 0) вместо их собственной позиции. И я не могу найти решение в Интернете, поэтому я впервые пытаюсь задать здесь вопрос!

(Также я использую библиотеку под названием GLM для преобразования объекта)

Итак, вот код, метод UpdateObject вызывается пакетом в a для l oop (потому что там есть группа объектов), поэтому я не думаю, что необходимо отображать всю систему, но да, «Object. cpp», который хранит всю информацию об объектах (содержащих матричную функцию Родригеса).

Object::Object(glm::vec3 pos, glm::vec3 rot, glm::vec3 sca)
        {
            position = pos;
            scale = sca;
            rotation = rot;
        }

        glm::mat3 rodriguesMatrix(const double degrees, const glm::vec3& axis) {
            glm::mat3 v = glm::mat3(
                axis.x * axis.x, axis.x * axis.y, axis.x * axis.z,
                axis.x * axis.y, axis.y * axis.y, axis.y * axis.z,
                axis.x * axis.z, axis.y * axis.z, axis.z * axis.z
            );

            glm::mat3 v2 = glm::mat3(
                0, -axis.z, axis.y,
                axis.z, 0, -axis.x,
                -axis.y, axis.x, 0
            );
            glm::mat3 cosMat(1.0f * cos(degrees * M_PI));
            v *= (1 - cos(degrees * M_PI));
            v2 *= sin(degrees * M_PI);

            glm::mat3 rotation = cosMat + v + v2;

            return rotation;
        }

        Vertex* Object::UpdateObject(Vertex* target)
        {
            glm::mat3 rotationMatrix;
            rotationMatrix = rodriguesMatrix(glm::radians(rotation.x), glm::vec3(1.f, 0.f, 0.f));
            rotationMatrix = rodriguesMatrix(glm::radians(rotation.y), glm::vec3(0.f, 1.f, 0.f));
            rotationMatrix = rodriguesMatrix(glm::radians(rotation.z), glm::vec3(0.f, 0.f, 1.f));


            float size = 1.0f;
            target->position = rotationMatrix * glm::vec3(position.x - 0.5f * scale.x, position.y + 0.5f * scale.y, position.z);
            target->color = glm::vec3(1.0f, 0.2f, 0.2f);
            target->texcoord = glm::vec2(0.0f, 1.0f);
            target++;

            target->position = rotationMatrix * glm::vec3(position.x - 0.5f * scale.x, position.y - 0.5f * scale.y, position.z);
            target->color = glm::vec3(0.2f, 1.0f, 0.2f);
            target->texcoord = glm::vec2(0.0f, 0.0f);
            target++;

            target->position = rotationMatrix * glm::vec3(position.x + 0.5f * scale.x, position.y - 0.5f * scale.y, position.z);
            target->color = glm::vec3(0.2f, 0.2f, 1.0f);
            target->texcoord = glm::vec2(1.0f, 0.0f);
            target++;

            target->position = rotationMatrix * glm::vec3(position.x + 0.5f * scale.x, position.y + 0.5f * scale.y, position.z);
            target->color = glm::vec3(1.0f, 1.0f, 0.2f);
            target->texcoord = glm::vec2(1.0f, 1.0f);
            target++;

            return target;
        }

Вершина - это структура из 2 «Vector3», одна для позиции , другой для цвета и "Vector2" для координат текстуры.

Вот в чем проблема, если кто-то может мне помочь или дать мне ответ, это будет здорово: 'D

С уважением. Начо: D

1 Ответ

3 голосов
/ 01 августа 2020

Это простой пример того, как повернуть прямоугольник вокруг точки с помощью матриц смещения и поворота. Надеюсь, это вам поможет:

#include <iostream>
#include <glm/glm.hpp>
#include <glm/ext.hpp>

void rotateRectangleAroundSomePoint(glm::vec3 vertices[4], float angle, glm::vec3 rotationCenter, glm::vec3 axis)
{
    const glm::mat4 translationMatrix = glm::translate(glm::identity<glm::mat4>(), -rotationCenter);
    const glm::mat4 rotationMatrix = glm::rotate(glm::identity<glm::mat4>(), angle, axis);
    const glm::mat4 reverseTranslationMatrix = glm::translate(glm::identity<glm::mat4>(), rotationCenter);

    for (size_t i = 0; i < 4; i++) {

        vertices[i] = glm::vec3(
                    reverseTranslationMatrix * rotationMatrix * translationMatrix * glm::vec4(vertices[i], 1.0f));
    }
}

int main()
{

    glm::vec3 rectangleVertices[4] =
    {
        glm::vec3(1.0f, 1.0f, 0.0f),
        glm::vec3(3.0f, 1.0f, 0.0f),
        glm::vec3(3.0f, 2.0f, 0.0f),
        glm::vec3(1.0f, 2.0f, 0.0f),
    };

    rotateRectangleAroundSomePoint(rectangleVertices,
                                   glm::radians(90.0f),
                                   glm::vec3(2.0f, 1.5f, 0.0),
                                   glm::vec3(0.0f, 0.0f ,1.0f));

    for (size_t i = 0; i < 4; i++) {
        std::cout
                << rectangleVertices[i].x << " , "
                << rectangleVertices[i].y << " , "
                << rectangleVertices[i].z << std::endl;
    }

    return 0;
}
...