Инструмент трансформации
This commit is contained in:
81
src/TRS.cpp
Normal file
81
src/TRS.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "TRS.h"
|
||||
|
||||
// Инициализирует дополнительную информацию модели
|
||||
void TRS::init_etc()
|
||||
{
|
||||
int value = 1;
|
||||
for (auto it = tool.models.begin(); it != tool.models.end(); ++it)
|
||||
it->id.etc = value++;
|
||||
}
|
||||
|
||||
// Рендер инструмента нужного типа для выбранного объекта
|
||||
void TRS::render(GLuint64 selectedID, ShaderProgram &shaderProgram, UBO &material_buffer)
|
||||
{
|
||||
// Если есть выбранная модель - рендерим инструмент для неё
|
||||
if (selectedID)
|
||||
{
|
||||
// Указатель на объект
|
||||
Node* selectedObject = (Node*) selectedID;
|
||||
|
||||
// Смещение выбранного объекта в глобальных координатах из его матрицы трансформации (включая родительские)
|
||||
tool.root.e_position() = glm::vec3(selectedObject->getTransformMatrix()[3]);
|
||||
|
||||
// Замена идентификатора инструмента идентификатором выбранного объекта
|
||||
tool.set_group_id(selectedID); // без замены доп. информации
|
||||
|
||||
// Рендер инструмента
|
||||
tool.render(shaderProgram, material_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
Transform::Transform()
|
||||
{
|
||||
tool = loadOBJtoScene("../resources/models/tools/transform.obj", "../resources/models/tools/", "../resources/textures/");
|
||||
|
||||
// Масштабирование
|
||||
tool.root.e_scale() = glm::vec3(0.3);
|
||||
|
||||
// Инициализация дополнительной информации
|
||||
init_etc();
|
||||
}
|
||||
|
||||
// Взаимодействие с инструментом
|
||||
void Transform::process(GLuint64 selectedID, GLuint etc, const glm::vec4& dpos)
|
||||
{
|
||||
// Если взаимодействие с осями инструмента
|
||||
if (etc > 0)
|
||||
// Если есть выбранная модель - рендерим инструмент для неё
|
||||
if (selectedID)
|
||||
{
|
||||
// Указатель на объект
|
||||
Node* selectedObject = (Node*) selectedID;
|
||||
|
||||
glm::vec3 dVec(0.0f, 0.0f, 0.0f);
|
||||
|
||||
// Сдвиг с учетом чувствительности для соответствующих осей
|
||||
if (etc & 01)
|
||||
dVec.x = dpos.x * T_SENSITIVITY;
|
||||
if (etc & 02)
|
||||
dVec.y = dpos.y * T_SENSITIVITY;
|
||||
if (etc & 04)
|
||||
dVec.z = dpos.z * T_SENSITIVITY;
|
||||
|
||||
// Если есть родитель - требуется учесть его поворот
|
||||
Node* parent = selectedObject->getParent();
|
||||
if (parent)
|
||||
{
|
||||
// Извлекаем 3x3 подматрицу, отвечающую за вращение и масштаб
|
||||
glm::mat3 rotationMatrix = glm::mat3(parent->getTransformMatrix());
|
||||
|
||||
// Нормализуем столбцы подматрицы, чтобы исключить масштабирование
|
||||
for (int i = 0; i < 3; i++)
|
||||
rotationMatrix[i] = glm::normalize(rotationMatrix[i]);
|
||||
|
||||
// Применим поворот родителя к вектору сдвига
|
||||
dVec = glm::inverse(rotationMatrix) * dVec;
|
||||
}
|
||||
|
||||
// Добавим сдвиг от инструмента к позиции выбранного объекта
|
||||
selectedObject->e_position() += dVec;
|
||||
}
|
||||
}
|
||||
22
src/main.cpp
22
src/main.cpp
@@ -9,6 +9,7 @@
|
||||
#include "Scene.h"
|
||||
#include "Shader.h"
|
||||
#include "Lights.h"
|
||||
#include "TRS.h"
|
||||
|
||||
#define WINDOW_CAPTION "OPENGL notes on rekovalev.site"
|
||||
|
||||
@@ -154,6 +155,7 @@ int main(void)
|
||||
scene.root.e_position().z = 1;
|
||||
scene.models.begin()->material.kd = {0.5,0.5,0.5};
|
||||
scene.models.begin()->material.ka = {0.05,0.05,0.05};
|
||||
scene.set_group_id((GLuint64) &scene);
|
||||
|
||||
// Установка цвета очистки буфера цвета
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
@@ -433,6 +435,16 @@ int main(void)
|
||||
|
||||
ID selected; // Выбранная модель
|
||||
|
||||
// Шейдер для инструментов
|
||||
ShaderProgram toolsShader;
|
||||
// Загрузим шейдеры
|
||||
toolsShader.load(GL_VERTEX_SHADER, "shaders/gshader.vert");
|
||||
toolsShader.load(GL_FRAGMENT_SHADER, "shaders/tools.frag");
|
||||
toolsShader.link();
|
||||
|
||||
// Инструменты
|
||||
Transform transform;
|
||||
|
||||
// Пока не произойдет событие запроса закрытия окна
|
||||
while(!glfwWindowShouldClose(window))
|
||||
{
|
||||
@@ -454,6 +466,11 @@ int main(void)
|
||||
scene.render(gShader, material_data);
|
||||
rectangle.render(gShader, material_data);
|
||||
|
||||
// Используем шейдер для инструментов
|
||||
toolsShader.use();
|
||||
// Рендерим инструменты для выбранного объекта
|
||||
transform.render(selected.value, toolsShader, material_data);
|
||||
|
||||
// Выбор объекта
|
||||
if (mouse.left == 0100000)
|
||||
{
|
||||
@@ -578,6 +595,11 @@ int main(void)
|
||||
&& mouse.x != mouse.prev_x
|
||||
&& mouse.y != mouse.prev_y)
|
||||
Camera::current().rotate(glm::vec2(mouse.x - mouse.prev_x, mouse.prev_y - mouse.y));
|
||||
|
||||
// Взаимодействие с инструментом при зажатой левой кнопке
|
||||
if (mouse.left > 0100000)
|
||||
if (selected.etc)
|
||||
transform.process(selected.value, selected.etc, glm::transpose(Camera::current().getVP()) * glm::vec4(mouse.x - mouse.prev_x, mouse.prev_y - mouse.y, 0, 1));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user