# HG changeset patch # User Teemu Piippo # Date 1656433915 -10800 # Node ID 38f6fad61badaf917b609b9cacd671c333eb520b # Parent 4241d948af288c9f7397db395ffb95a77f5a7353 Remove dead code diff -r 4241d948af28 -r 38f6fad61bad CMakeLists.txt --- a/CMakeLists.txt Tue Jun 28 19:25:45 2022 +0300 +++ b/CMakeLists.txt Tue Jun 28 19:31:55 2022 +0300 @@ -80,7 +80,6 @@ src/gl/basicshaderprogram.cpp src/gl/compiler.cpp src/gl/partrenderer.cpp -# src/gl/vertexprogram.cpp src/layers/axeslayer.cpp src/layers/edittools.cpp src/layers/gridlayer.cpp @@ -118,7 +117,6 @@ src/gl/common.h src/gl/compiler.h src/gl/partrenderer.h -# src/gl/vertexprogram.h src/layers/axeslayer.h src/layers/edittools.h src/layers/gridlayer.h @@ -145,14 +143,6 @@ shaders/model.vert.glsl ) -set(LOCALE_FILES - locale/fi.ts - locale/sv.ts -) - -set (OTHER_FILES -) - set(CMAKE_AUTOUIC_SEARCH_PATHS src/ui) set(QRC_FILE resources.qrc) set(CMAKE_CXX_STANDARD 20) diff -r 4241d948af28 -r 38f6fad61bad src/gl/vertexprogram.cpp --- a/src/gl/vertexprogram.cpp Tue Jun 28 19:25:45 2022 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -#include "vertexprogram.h" -#include "document.h" - -static const char vertexShaderSource[] = R"( -#version 330 core -const int FRAGSTYLE_Normal = 0; -const int FRAGSTYLE_Id = 1; -layout (location = 0) in vec3 in_position; -layout (location = 1) in vec3 in_color; -uniform mat4 view; -uniform mat4 projection; -uniform mat4 model; -smooth out vec3 ex_color; - -void main() -{ - gl_Position = projection * view * model * vec4(in_position, 1.0); - ex_color = in_color; -} -)"; - -static const char fragmentShaderSource[] = R"( -#version 330 core - -out vec4 color; -smooth in vec3 ex_color; - -void main(void) -{ - color = vec4(ex_color, 1); -} -)"; - -std::vector sphere(const int d2) -{ - std::vector result; - result.reserve(12 * d2 * d2); - for (int i = 0; i < d2; ++i) - { - const float alpha = i * pi<> / d2; - const float alpha_2 = (i + 1) * pi<> / d2; - for (int j = -d2; j < d2; ++j) - { - const float beta = j * pi<> / d2; - const float beta_2 = (j + 1) * pi<> / d2; - const float x1 = cos(beta) * sin(alpha); - const float x2 = cos(beta) * sin(alpha_2); - const float x3 = cos(beta_2) * sin(alpha_2); - const float x4 = cos(beta_2) * sin(alpha); - const float z1 = sin(beta) * sin(alpha); - const float z2 = sin(beta) * sin(alpha_2); - const float z3 = sin(beta_2) * sin(alpha_2); - const float z4 = sin(beta_2) * sin(alpha); - const float y1 = cos(alpha); - const float y2 = cos(alpha_2); - result.push_back({x1, y1, z1}); - result.push_back({x2, y2, z2}); - result.push_back({x3, y2, z3}); - result.push_back({x1, y1, z1}); - result.push_back({x3, y2, z3}); - result.push_back({x4, y1, z4}); - } - } - return result; -} - -VertexProgram::VertexProgram(QObject *parent) : - AbstractBasicShaderProgram{parent} -{ -} - -const char *VertexProgram::vertexShaderSource() const -{ - return ::vertexShaderSource; -} - -const char *VertexProgram::fragmentShaderSource() const -{ - return ::fragmentShaderSource; -} - -const void *VertexProgram::vertexData() const -{ - return this->data.data(); -} - -int VertexProgram::vertexSize() const -{ - return sizeof(Vertex); -} - -int VertexProgram::vertexCount() const -{ - return this->data.size(); -} - -void VertexProgram::setupVertexArrays() -{ - for (int i : {0, 1}) - { - this->program->enableAttributeArray(i); - } - const int stride = this->vertexSize(); - this->program->setAttributeBuffer(0, GL_FLOAT, offsetof(Vertex, position), 3, stride); - this->program->setAttributeBuffer(1, GL_FLOAT, offsetof(Vertex, color), 3, stride); -} - -GLenum VertexProgram::drawMode() const -{ - return GL_TRIANGLES; -} - -QOpenGLBuffer::UsagePattern VertexProgram::usagePattern() const -{ - return QOpenGLBuffer::DynamicDraw; -} - -void VertexProgram::setFragmentStyle(const FragmentStyle newFragmentStyle) -{ - this->fragmentStyle = newFragmentStyle; -} - -void VertexProgram::build(const VertexMap* vertexMap) -{ - constexpr glm::vec3 color = {0.0, 1.0, 1.0}; - this->data.clear(); - const std::vector sphere = ::sphere(8 / 2); - vertexMap->apply([&](const glm::vec3&, const VertexMap::VertexInfo& info) - { - reserveMore(this->data, sphere.size()); - for (const glm::vec3& point : sphere) - { - const glm::vec3 transformed = glm::scale(info.transform, glm::vec3{0.5, 0.5, 0.5}) * glm::vec4{point, 1}; - this->data.push_back({transformed, color}); - } - }); - this->buffer.bind(); - this->buffer.allocate(this->vertexData(), this->vertexCount() * this->vertexSize()); - this->buffer.release(); -} diff -r 4241d948af28 -r 38f6fad61bad src/gl/vertexprogram.h --- a/src/gl/vertexprogram.h Tue Jun 28 19:25:45 2022 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -#ifndef VERTEXPROGRAM_H -#define VERTEXPROGRAM_H -#include "basicshaderprogram.h" -class VertexMap; - -class VertexProgram : public AbstractBasicShaderProgram -{ -public: - enum FragmentStyle - { - Normal, - Id - }; - struct Vertex - { - glm::vec3 position; - glm::vec3 color; - }; - VertexProgram(QObject* parent = nullptr); - void build(const VertexMap* document); -protected: - const char* vertexShaderSource() const override; - const char* fragmentShaderSource() const override; - const void* vertexData() const override; - int vertexSize() const override; - int vertexCount() const override; - void setupVertexArrays() override; - GLenum drawMode() const override; - QOpenGLBuffer::UsagePattern usagePattern() const override; - void setFragmentStyle(FragmentStyle newFragmentStyle); -private: - std::vector data; - FragmentStyle fragmentStyle = Normal; -}; - -#endif // VERTEXPROGRAM_H diff -r 4241d948af28 -r 38f6fad61bad src/main.cpp --- a/src/main.cpp Tue Jun 28 19:25:45 2022 +0300 +++ b/src/main.cpp Tue Jun 28 19:31:55 2022 +0300 @@ -145,36 +145,6 @@ QObject::tr("LDraw models (*.ldr *.dat)")); } -#if 0 -static const QString localeCode(const QString& locale) -{ - if (locale == "system") { - return QLocale::system().name(); - } - else { - return locale; - } -} - -/** - * @brief Changes the application language to the specified language - */ -static void changeLanguage(const QString& locale, QTranslator* translator) -{ - if (not locale.isEmpty()) { - const QString localeCode = ::localeCode(locale); - QLocale::setDefault(QLocale{localeCode}); - qApp->removeTranslator(translator); - const QString path = LOCALE_DIR.filePath(localeCode + ".qm"); - const bool loadSuccessful = translator->load(path); - if (loadSuccessful) - { - qApp->installTranslator(translator); - } - } -} -#endif - static ModelData* findModelData(const DocumentManager* documents, ModelId modelId) { return documents->findPayload(modelId); @@ -495,7 +465,6 @@ const auto restoreSettings = [&]{ recentlyOpenedFiles = setting(); renderPreferences = loadRenderPreferences(); - //changeLanguage(setting(), &translator); libraries.restoreFromSettings(); updateRecentlyOpenedDocumentsMenu(); colorTable = loadColors(&libraries); diff -r 4241d948af28 -r 38f6fad61bad src/settings.h --- a/src/settings.h Tue Jun 28 19:25:45 2022 +0300 +++ b/src/settings.h Tue Jun 28 19:31:55 2022 +0300 @@ -27,7 +27,6 @@ Q_DECLARE_METATYPE(QMdiArea::ViewMode) // Rendering options -//SETTING(Locale, QString{"system"}) SETTING(BackgroundColor, (QColor{48, 48, 48})) SETTING(MainColor, (QColor{255, 255, 64})) SETTING(SelectedColor, (QColor{32, 32, 224})) diff -r 4241d948af28 -r 38f6fad61bad src/settingseditor/settingseditor.cpp --- a/src/settingseditor/settingseditor.cpp Tue Jun 28 19:25:45 2022 +0300 +++ b/src/settingseditor/settingseditor.cpp Tue Jun 28 19:31:55 2022 +0300 @@ -22,7 +22,6 @@ this->ui.keyboardShortcutsView->setModel(new KeyboardShortcutsEditor{parent, this}); this->ui.viewModeButtonGroup->setId(this->ui.viewModeTabs, int{QMdiArea::TabbedView}); this->ui.viewModeButtonGroup->setId(this->ui.viewModeSubWindows, int{QMdiArea::SubWindowView}); - this->loadLocales(); this->loadSettings(); this->setWindowTitle(tr("Settings")); this->setWindowIcon(QIcon{":/icons/settings-outline.png"}); @@ -46,7 +45,6 @@ void SettingsEditor::saveSettings() { - //setSetting(this->ui.language->currentData().toString()); setSetting(this->ui.mainColorButton->color()); setSetting(this->ui.backgroundColorButton->color()); setSetting(this->ui.selectedColorButton->color()); @@ -61,34 +59,9 @@ Q_EMIT this->settingsChanged(); } -void SettingsEditor::loadLocales() -{ - /* - this->ui.language->clear(); - QDir dir{":/locale"}; - // Collect translation files in built-in resources - QVector localeCodes = {"en"}; // English is the default locale - for (const QFileInfo& file : dir.entryInfoList(QDir::Files)) - { - localeCodes.append(file.baseName()); - } - std::sort(localeCodes.begin(), localeCodes.end()); - this->ui.language->addItem(tr("System language"), "system"); - for (const QString& localeCode : localeCodes) - { - const QLocale locale{localeCode}; - const QString languageName = QLocale::languageToString(locale.language()); - const QIcon flag{":/flags/" + localeCode + ".png"}; - this->ui.language->addItem(languageName, localeCode); - this->ui.language->setItemIcon(this->ui.language->count() - 1, flag); - } - */ -} - void SettingsEditor::loadSettings() { this->libraries.restoreFromSettings(); - //this->setCurrentLanguage(setting()); this->ui.mainColorButton->setColor(setting()); this->ui.backgroundColorButton->setColor(setting()); this->ui.selectedColorButton->setColor(setting()); @@ -100,17 +73,3 @@ viewModeButton->setChecked(true); } } - -void SettingsEditor::setCurrentLanguage(const QString& localeCode) -{ - /* - for (int i = 0; i < this->ui.language->count(); i += 1) - { - if (this->ui.language->itemData(i) == localeCode) - { - this->ui.language->setCurrentIndex(i); - break; - } - } - */ -} diff -r 4241d948af28 -r 38f6fad61bad src/settingseditor/settingseditor.h --- a/src/settingseditor/settingseditor.h Tue Jun 28 19:25:45 2022 +0300 +++ b/src/settingseditor/settingseditor.h Tue Jun 28 19:31:55 2022 +0300 @@ -21,6 +21,4 @@ LibrariesModel libraries; LibrariesEditor librariesEditor; const uiutilities::KeySequenceMap defaultKeyboardShortcuts; - void loadLocales(); - void setCurrentLanguage(const QString& localeCode); }; diff -r 4241d948af28 -r 38f6fad61bad src/ui/canvas.cpp --- a/src/ui/canvas.cpp Tue Jun 28 19:25:45 2022 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,431 +0,0 @@ -#include -#include -#include "document.h" -#include "canvas.h" - -Canvas::Canvas( - Model* model, - EditTools *document, - DocumentManager* documents, - const ColorTable& colorTable, - QWidget* parent) : - PartRenderer{model, documents, colorTable, parent}, - document{document} -{ - this->setMouseTracking(true); -} - -/** - * @brief Handles a change of selection - * @param selectedIds IDs of objects to select - * @param deselectedIds IDs of objects to deselect. - */ -void Canvas::handleSelectionChange(const QSet &selectedIds, const QSet &deselectedIds) -{ - Q_ASSERT(not selectedIds.contains({0})); - this->selection.subtract(deselectedIds); - this->selection.unite(selectedIds); - gl::setModelShaderSelectedObjects(&this->shaders, this->selection); - this->update(); -} - -/** - * @brief Updates vertex rendering - * @param document Document to get vertices from - */ -void Canvas::rebuildVertices(VertexMap* vertexMap) -{ - if (this->vertexProgram.has_value()) - { - this->vertexProgram->build(vertexMap); - this->update(); - } -} - -void Canvas::mouseMoveEvent(QMouseEvent* event) -{ - const ModelId id = this->pick(event->pos()); - this->highlighted = id; - this->totalMouseMove += (event->pos() - this->lastMousePosition).manhattanLength(); - this->worldPosition = this->screenToModelCoordinates(event->pos(), this->gridPlane); - if (this->worldPosition.has_value()) - { - /* - * Snap the position to grid. This procedure is basically the "change of basis" and almost follows the - * Aโปยน ร— M ร— A formula which is used to perform a transformation in some other coordinate system, except - * we actually use the inverted matrix first and the regular one last to perform the transformation of - * grid coordinates in our XY coordinate system. Also, we're rounding the coordinates which is obviously - * not a linear transformation, but fits the pattern anyway. - */ - // First transform the coordinates to the XY plane... - this->worldPosition = glm::inverse(this->gridMatrix) * glm::vec4{*this->worldPosition, 1}; - // Then round the coordinates to integer precision... - this->worldPosition = glm::round(*this->worldPosition); - // And finally transform it back to grid coordinates by transforming it with the - // grid matrix. - this->worldPosition = this->gridMatrix * glm::vec4{*this->worldPosition, 1}; - } - Q_EMIT this->mouseMove(event); - PartRenderer::mouseMoveEvent(event); - this->update(); -} - -void Canvas::mousePressEvent(QMouseEvent* event) -{ - this->totalMouseMove = 0; - this->lastMousePosition = event->pos(); - PartRenderer::mousePressEvent(event); -} - -void Canvas::mouseReleaseEvent(QMouseEvent* event) -{ - if (this->totalMouseMove < (2.0 / sqrt(2)) * 5.0) - { - Q_EMIT this->mouseClick(event); - } - PartRenderer::mouseReleaseEvent(event); - this->update(); -} - -void Canvas::initializeGL() -{ - // We first create the grid program and connect everything and only then call the part renderer's initialization - // functions so that when initialization sets up, the signals also set up the matrices on our side. - this->gridProgram.emplace(this); - this->gridProgram->initialize(); - this->axesProgram.emplace(this); - this->axesProgram->initialize(); - this->vertexProgram.emplace(this); - this->vertexProgram->initialize(); - for (AbstractBasicShaderProgram* program : { - static_cast(&*this->gridProgram), - static_cast(&*this->axesProgram), - static_cast(&*this->vertexProgram), - }) - { - connect(this, &PartRenderer::projectionMatrixChanged, - program, &AbstractBasicShaderProgram::setProjectionMatrix); - connect(this, &PartRenderer::modelMatrixChanged, - program, &AbstractBasicShaderProgram::setModelMatrix); - connect(this, &PartRenderer::viewMatrixChanged, - program, &AbstractBasicShaderProgram::setViewMatrix); - } - connect(this, &PartRenderer::renderPreferencesChanged, this, &Canvas::updateCanvasRenderPreferences); - PartRenderer::initializeGL(); - // Set up XZ grid matrix - this->setGridMatrix({{1, 0, 0, 0}, {0, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 1}}); - this->updateCanvasRenderPreferences(); -} - -static const struct -{ - const QBrush pointBrush = {Qt::white}; - const QPen polygonPen = {QBrush{Qt::black}, 2.0, Qt::DashLine}; - const QPen badPolygonPen = {QBrush{Qt::red}, 2.0, Qt::DashLine}; - const QPen pointPen = {QBrush{Qt::black}, 2.0}; - const QBrush greenPolygonBrush = {QColor{64, 255, 128, 192}}; - const QBrush redPolygonBrush = {QColor{255, 96, 96, 192}}; -} pens; - -static void renderDrawState( - QPainter* painter, - Canvas* canvas, - DrawState* drawState); - -void Canvas::paintGL() -{ - PartRenderer::paintGL(); - if (this->renderPreferences.style != gl::RenderStyle::PickScene) - { - // Render axes - if (this->renderPreferences.drawAxes) - { - glLineWidth(5); - glEnable(GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - this->axesProgram->draw(); - glDisable(GL_LINE_SMOOTH); - } - // Render vertices - { - glCullFace(GL_FRONT); - this->vertexProgram->draw(); - } - // Render grid - { - glLineWidth(1); - glEnable(GL_BLEND); - glLineStipple(1, 0x8888); - glEnable(GL_LINE_STIPPLE); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - this->gridProgram->draw(); - glDisable(GL_BLEND); - glDisable(GL_LINE_STIPPLE); - } - if (this->worldPosition.has_value()) - { - QPainter painter{this}; - painter.setRenderHint(QPainter::Antialiasing); - painter.setPen(this->isDark ? Qt::white : Qt::black); - painter.setBrush(Qt::green); - const QPointF pos = this->modelToScreenCoordinates(*this->worldPosition); - painter.drawEllipse(pos, 5, 5); - painter.drawText(pos + QPointF{5, 5}, vectorToString(*this->worldPosition)); - } - QPainter painter{this}; - painter.setRenderHint(QPainter::Antialiasing); - if (this->renderPreferences.drawAxes) - { - this->renderAxesLabels(painter); - } - if (this->drawState != nullptr) { - renderDrawState(&painter, this, this->drawState); - } - } -} - -static void renderDrawState( - QPainter* painter, - Canvas* canvas, - DrawState* drawState) -{ - switch(drawState->mode) - { - case SelectMode: - break; - case DrawMode: - { - painter->setPen(drawState->isconcave ? ::pens.badPolygonPen : ::pens.polygonPen); - if (drawState->previewPolygon.size() > 2 and not drawState->isconcave) - { - if (canvas->worldPolygonWinding(drawState->previewPolygon) == Winding::Clockwise) - { - painter->setBrush(::pens.greenPolygonBrush); - } - else - { - painter->setBrush(::pens.redPolygonBrush); - } - canvas->drawWorldPolygon(painter, drawState->previewPolygon); - } - else - { - canvas->drawWorldPolyline(painter, drawState->previewPolygon); - } - painter->setBrush(::pens.pointBrush); - painter->setPen(::pens.pointPen); - for (const glm::vec3& point : drawState->polygon) - { - canvas->drawWorldPoint(painter, point); - } - canvas->drawWorldPoint(painter, drawState->previewPoint); - } - break; - } -} - -/** - * @brief Renders labels such as +x at the ends of axes at the screen - * @param painter - */ -void Canvas::renderAxesLabels(QPainter& painter) -{ - QFont font; - //font.setStyle(QFont::StyleItalic); - painter.setFont(font); - QFontMetrics fontMetrics{font}; - const auto renderText = [&](const QString& text, const PointOnRectagle& intersection) - { - QPointF position = toQPointF(intersection.position); - const RectangleSide side = intersection.side; - switch (side) - { - case RectangleSide::Top: - position += QPointF{0, static_cast(fontMetrics.ascent())}; - break; - case RectangleSide::Left: - break; - case RectangleSide::Bottom: - position += QPointF{0, static_cast(-fontMetrics.descent())}; - break; - case RectangleSide::Right: - position += QPointF{static_cast(-fontMetrics.horizontalAdvance(text)), 0}; - break; - } - painter.drawText(position, text); - }; - const QRectF box {QPointF{0, 0}, sizeToSizeF(this->size())}; - const QPointF p1 = this->modelToScreenCoordinates(glm::vec3{0, 0, 0}); - static const struct - { - QString text; - glm::vec3 direction; - } directions[] = - { - {"+๐‘ฅ", {1, 0, 0}}, - {"-๐‘ฅ", {-1, 0, 0}}, - {"+๐‘ฆ", {0, 1, 0}}, - {"-๐‘ฆ", {0, -1, 0}}, - {"+๐‘ง", {0, 0, 1}}, - {"-๐‘ง", {0, 0, -1}}, - }; - for (const auto& axis : directions) - { - const QPointF x_p = this->modelToScreenCoordinates(axis.direction); - const auto intersection = rayRectangleIntersection( - rayFromPoints(toVec2(p1), toVec2(x_p)), - box); - if (intersection.has_value()) - { - renderText(axis.text, *intersection); - } - } -} - -/** - * @brief Draws a polyline to where the specified vector of 3D points would appear on the screen. - * @param painter Painter to use to draw with - * @param points 3D points to render - */ -void Canvas::drawWorldPolyline(QPainter *painter, const std::vector &points) -{ - painter->drawPolyline(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); -} - -/** - * @brief Draws a polygon to where the specified vector of 3D points would appear on the screen. - * @param painter Painter to use to draw with - * @param points 3D points to render - */ -void Canvas::drawWorldPolygon(QPainter* painter, const std::vector &points) -{ - painter->drawPolygon(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); -} - -Winding Canvas::worldPolygonWinding(const std::vector &points) const -{ - return winding(QPolygonF{this->convertWorldPointsToScreenPoints(points)}); -} - -/** - * @brief Gets the current position of the cursor in the model - * @return 3D vector - */ -const std::optional& Canvas::getWorldPosition() const -{ - return this->worldPosition; -} - -/** - * @brief Adjusts the grid to be so that it is perpendicular to the camera. - */ -void adjustGridToView(Canvas* canvas) -{ - const glm::vec3 cameraDirection = canvas->cameraVector(); - const glm::mat4& grid = canvas->getGridMatrix(); - const glm::vec3 vector_x = glm::normalize(grid * glm::vec4{1, 0, 0, 1}); - const glm::vec3 vector_y = glm::normalize(grid * glm::vec4{0, 1, 0, 1}); - const float angle_x = std::abs(glm::dot(vector_x, cameraDirection)); - const float angle_y = std::abs(glm::dot(vector_y, cameraDirection)); - canvas->setGridMatrix(glm::rotate( - grid, - pi<> * 0.5f, - (angle_x < angle_y) ? glm::vec3{1, 0, 0} : glm::vec3{0, 1, 0} - )); - canvas->update(); -} - -/** - * @returns the ids of the currently selected objects - */ -const QSet Canvas::selectedObjects() const -{ - return this->selection; -} - -const glm::mat4 &Canvas::getGridMatrix() const -{ - return this->gridMatrix; -} - -/** - * @brief Paints a circle at where @c worldPoint is located on the screen. - * @param painter Painter to use to render - * @param worldPoint Point to render - */ -void Canvas::drawWorldPoint(QPainter* painter, const glm::vec3& worldPoint) const -{ - const QPointF center = this->modelToScreenCoordinates(worldPoint); - painter->drawEllipse(inscribe(CircleF{center, 5})); -} - -/** - * @brief Changes the grid matrix to the one specified. Updates relevant member variables. - * @param newMatrix New matrix to use - */ -void Canvas::setGridMatrix(const glm::mat4& newMatrix) -{ - this->gridMatrix = newMatrix; - const Triangle triangle { - this->gridMatrix * glm::vec4{0, 0, 0, 1}, - this->gridMatrix * glm::vec4{1, 0, 0, 1}, - this->gridMatrix * glm::vec4{0, 1, 0, 1}, - }; - this->gridPlane = planeFromTriangle(triangle); - this->gridProgram->setGridMatrix(this->gridMatrix); - this->update(); -} - -/** - * @brief Gets the current camera vector, i.e. the vector from the camera to the grid origin. - * @return vector - */ -glm::vec3 Canvas::cameraVector() const -{ - // Find out where the grid is projected on the screen - const QPointF gridOrigin2d = this->modelToScreenCoordinates(this->gridPlane.anchor); - // Find out which direction the camera is looking at the grid origin in 3d - return glm::normalize(this->cameraLine(gridOrigin2d).direction); -} - -/** - * @brief Calculates whether the screen is perpendicular to the current grid - * @return bool - */ -bool Canvas::isGridPerpendicularToScreen(float threshold) const -{ - const glm::vec3 cameraDirection = this->cameraVector(); - // Compute the dot product. The parameters given are: - // - the normal of the grid plane, which is the vector from the grid origin perpendicular to the grid - // - the direction of the camera looking at the grid, which is the inverse of the vector from the grid - // origin towards the camera - // If the dot product between these two vectors is 0, the grid normal is perpendicular to the camera vector - // and the grid is perpendicular to the screen. - const float dot = glm::dot(glm::normalize(this->gridPlane.normal), glm::normalize(cameraDirection)); - return std::abs(dot) < threshold; -} - -QVector Canvas::convertWorldPointsToScreenPoints(const std::vector &worldPoints) const -{ - QVector points2d; - points2d.reserve(worldPoints.size()); - for (const glm::vec3& point : worldPoints) - { - points2d.push_back(this->modelToScreenCoordinates(point)); - } - return points2d; -} - -void Canvas::updateCanvasRenderPreferences() -{ - this->isDark = luma(this->renderPreferences.backgroundColor) < 0.25; - if (this->gridProgram.has_value()) - { - this->gridProgram->setGridColor(this->isDark ? Qt::white : Qt::black); - } -} - -void Canvas::setOverpaintCallback(Canvas::OverpaintCallback fn) -{ - this->overpaintCallback = fn; -} diff -r 4241d948af28 -r 38f6fad61bad src/ui/canvas.h --- a/src/ui/canvas.h Tue Jun 28 19:25:45 2022 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -#pragma once -#include -#include -#include -#include "gl/partrenderer.h" -#include "gl/gridprogram.h" -#include "gl/axesprogram.h" -#include "gl/vertexprogram.h" - -class EditTools; - -class Canvas : public PartRenderer -{ - Q_OBJECT -public: - using OverpaintCallback = std::function; - Canvas( - Model* model, - EditTools* document, - DocumentManager* documents, - const ColorTable& colorTable, - QWidget* parent = nullptr); - void setOverpaintCallback(OverpaintCallback fn); - void drawWorldPoint(QPainter* painter, const glm::vec3& worldPoint) const; - void drawWorldPolyline(QPainter* painter, const std::vector& points); - void drawWorldPolygon(QPainter* painter, const std::vector& points); - Winding worldPolygonWinding(const std::vector& points) const; - const std::optional& getWorldPosition() const; - const QSet selectedObjects() const; - const glm::mat4& getGridMatrix() const; - void closeShape(); - glm::vec3 cameraVector() const; - std::optional worldPosition; - DrawState* drawState = nullptr; -public Q_SLOTS: - void handleSelectionChange(const QSet& selectedIds, const QSet& deselectedIds); - void rebuildVertices(VertexMap* vertexMap); - void setGridMatrix(const glm::mat4 &newMatrix); -protected: - void mouseMoveEvent(QMouseEvent* event) override; - void mousePressEvent(QMouseEvent* event) override; - void mouseReleaseEvent(QMouseEvent* event) override; - void initializeGL() override; - void paintGL() override; -Q_SIGNALS: - void newStatusText(const QString& newStatusText); - void mouseClick(QMouseEvent* event); - void mouseMove(QMouseEvent* event); -private: - bool isGridPerpendicularToScreen(float threshold) const; - QVector convertWorldPointsToScreenPoints(const std::vector& worldPoints) const; - Q_SLOT void updateCanvasRenderPreferences(); - void renderAxesLabels(QPainter& painter); - std::optional gridProgram; - std::optional axesProgram; - std::optional vertexProgram; - glm::mat4 gridMatrix; - Plane gridPlane; - int totalMouseMove = 0; - bool isDark = true; - QSet selection; - OverpaintCallback overpaintCallback = nullptr; - EditTools* document; -}; - -void adjustGridToView(Canvas* canvas);