Инструмент трансформации
This commit is contained in:
parent
329bea7124
commit
5981f9011f
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef TRS_H
|
||||||
|
#define TRS_H
|
||||||
|
|
||||||
|
#define T_SENSITIVITY 0.001f
|
||||||
|
|
||||||
|
#include "Scene.h"
|
||||||
|
|
||||||
|
// Интерфейс инструмента
|
||||||
|
class TRS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void render(GLuint64 selectedID, ShaderProgram &shaderProgram, UBO &material_buffer); // Рендер инструмента нужного типа для выбранного объекта
|
||||||
|
virtual void process(GLuint64 selectedID, GLuint etc, const glm::vec4& dpos) = 0; // Взаимодействие с инструментом
|
||||||
|
protected:
|
||||||
|
void init_etc(); // Инициализирует дополнительную информацию модели
|
||||||
|
Scene tool; // Модель
|
||||||
|
};
|
||||||
|
|
||||||
|
// Инструмент трансформации
|
||||||
|
class Transform : public TRS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Transform();
|
||||||
|
virtual void process(GLuint64 selectedID, GLuint etc, const glm::vec4& dpos); // Взаимодействие с инструментом
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TRS_H
|
|
@ -0,0 +1,38 @@
|
||||||
|
#version 420 core
|
||||||
|
|
||||||
|
layout(std140, binding = 1) uniform Material
|
||||||
|
{
|
||||||
|
vec3 ka;
|
||||||
|
vec3 kd;
|
||||||
|
vec3 ks;
|
||||||
|
float p;
|
||||||
|
bool normalmapped;
|
||||||
|
bool parallaxmapped;
|
||||||
|
bool displacementmapped;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (location = 1) out vec3 gNormal;
|
||||||
|
layout (location = 3) out vec4 gAmbientSpecular;
|
||||||
|
layout (location = 4) out uvec3 gID;
|
||||||
|
|
||||||
|
in vec3 vertex; // Позиция вершины в пространстве
|
||||||
|
in vec3 N; // Нормаль трансформированная
|
||||||
|
in vec2 texCoord; // Текстурные координаты
|
||||||
|
in vec3 T; // Касательный вектор
|
||||||
|
in vec3 B; // Бикасательный вектор
|
||||||
|
in vec3 view; // Вектор от поверхности к камере
|
||||||
|
|
||||||
|
uniform float parallax_heightScale = 0.1;
|
||||||
|
|
||||||
|
uniform uvec3 ID = uvec3(0);
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gNormal = vec3(0);
|
||||||
|
// Сохранение фоновой составляющей
|
||||||
|
gAmbientSpecular.rgb = ka;
|
||||||
|
// Сохранение идентификатора объекта
|
||||||
|
gID = ID;
|
||||||
|
|
||||||
|
gl_FragDepth = 0.01 * gl_FragCoord.z;
|
||||||
|
}
|
|
@ -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 "Scene.h"
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Lights.h"
|
#include "Lights.h"
|
||||||
|
#include "TRS.h"
|
||||||
|
|
||||||
#define WINDOW_CAPTION "OPENGL notes on rekovalev.site"
|
#define WINDOW_CAPTION "OPENGL notes on rekovalev.site"
|
||||||
|
|
||||||
|
@ -154,6 +155,7 @@ int main(void)
|
||||||
scene.root.e_position().z = 1;
|
scene.root.e_position().z = 1;
|
||||||
scene.models.begin()->material.kd = {0.5,0.5,0.5};
|
scene.models.begin()->material.kd = {0.5,0.5,0.5};
|
||||||
scene.models.begin()->material.ka = {0.05,0.05,0.05};
|
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);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
@ -433,6 +435,16 @@ int main(void)
|
||||||
|
|
||||||
ID selected; // Выбранная модель
|
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))
|
while(!glfwWindowShouldClose(window))
|
||||||
{
|
{
|
||||||
|
@ -454,6 +466,11 @@ int main(void)
|
||||||
scene.render(gShader, material_data);
|
scene.render(gShader, material_data);
|
||||||
rectangle.render(gShader, material_data);
|
rectangle.render(gShader, material_data);
|
||||||
|
|
||||||
|
// Используем шейдер для инструментов
|
||||||
|
toolsShader.use();
|
||||||
|
// Рендерим инструменты для выбранного объекта
|
||||||
|
transform.render(selected.value, toolsShader, material_data);
|
||||||
|
|
||||||
// Выбор объекта
|
// Выбор объекта
|
||||||
if (mouse.left == 0100000)
|
if (mouse.left == 0100000)
|
||||||
{
|
{
|
||||||
|
@ -578,6 +595,11 @@ int main(void)
|
||||||
&& mouse.x != mouse.prev_x
|
&& mouse.x != mouse.prev_x
|
||||||
&& mouse.y != mouse.prev_y)
|
&& mouse.y != mouse.prev_y)
|
||||||
Camera::current().rotate(glm::vec2(mouse.x - mouse.prev_x, mouse.prev_y - mouse.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;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue