#include "TRS.h" #include // Инициализирует дополнительную информацию модели 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; } } Rotate::Rotate() { tool = loadOBJtoScene("../resources/models/tools/rotate.obj", "../resources/models/tools/", "../resources/textures/"); // Масштабирование tool.root.e_scale() = glm::vec3(0.3); int value = 1; for (auto it = tool.models.begin(); it != tool.models.end(); ++it) { it->id.etc = value; value *= 2; } } // Взаимодействие с инструментом void Rotate::process(GLuint64 selectedID, GLuint etc, const glm::vec4& drot) { // Если взаимодействие с осями инструмента if (etc > 0) // Если есть выбранная модель - рендерим инструмент для неё if (selectedID) { // Указатель на объект Node* selectedObject = (Node*) selectedID; glm::quat &selectedRot = selectedObject->e_rotation(); // Матрица родительского поворота glm::mat3 parentRotation(1); // Учет родительского поворота для вращения Node* parent = selectedObject->getParent(); if (parent) { // Извлекаем 3x3 подматрицу, отвечающую за вращение и масштаб parentRotation = glm::mat3(parent->getTransformMatrix()); // Нормализуем столбцы подматрицы, чтобы исключить масштабирование for (int i = 0; i < 3; i++) parentRotation[i] = glm::normalize(parentRotation[i]); } // Поворот по осям if (etc & 01) selectedRot = glm::angleAxis(drot.y * R_SENSITIVITY, parentRotation * glm::vec3(1.0f, 0.0f, 0.0f)) * selectedRot; if (etc & 02) selectedRot = glm::angleAxis(drot.x * R_SENSITIVITY, parentRotation * glm::vec3(0.0f, 1.0f, 0.0f)) * selectedRot; if (etc & 04) selectedRot = glm::angleAxis(drot.z * R_SENSITIVITY, parentRotation * glm::vec3(0.0f, 0.0f, 1.0f)) * selectedRot; } } Scale::Scale() { tool = loadOBJtoScene("../resources/models/tools/scale.obj", "../resources/models/tools/", "../resources/textures/"); // Масштабирование tool.root.e_scale() = glm::vec3(0.3); // Инициализация дополнительной информации init_etc(); } // Взаимодействие с инструментом void Scale::process(GLuint64 selectedID, GLuint etc, const glm::vec4& dscale) { // Если взаимодействие с осями инструмента if (etc > 0) // Если есть выбранная модель - рендерим инструмент для неё if (selectedID) { // Указатель на объект Node* selectedObject = (Node*) selectedID; // Для хранения результата glm::vec3 dVec(0); // Масштабирование с учетом чувствительности для соответствующих осей if (etc & 01) dVec.x = dscale.x * S_SENSITIVITY; if (etc & 02) dVec.y = dscale.y * S_SENSITIVITY; if (etc & 04) dVec.z = dscale.z * S_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_scale() += dVec; } }