Sun, 09 Apr 2023 00:56:49 +0300
Hopefully fixed all problems with determining polygon winding
#pragma once #include "src/basics.h" #include "src/documentmanager.h" #include "src/types/boundingbox.h" #include "src/gl/common.h" #include "src/gl/compiler.h" #include <QOpenGLWidget> class PartRenderer final : public QOpenGLWidget { Q_OBJECT QTextDocument* const model; DocumentManager* const documents; const ColorTable& colorTable; BoundingBox boundingBox; gl::ModelShaders shaders; ModelId highlighted = {0}; glm::mat4 projectionMatrix; glm::mat4 viewMatrix; glm::mat4 modelMatrix; glm::vec4 viewportVector; glm::quat modelQuaternion; QPoint lastMousePosition; int totalMouseMove = 0; gl::RenderPreferences renderPreferences; double zoom = 1.0; bool initialized = false; bool needBuild = true; std::vector<RenderLayer*> activeRenderLayers; std::vector<RenderLayer*> inactiveRenderLayers; std::chrono::time_point<std::chrono::steady_clock> lastClickTime; bool frozen = false; public: PartRenderer( QTextDocument* model, DocumentManager* documents, const ColorTable& colorTable, QWidget* parent = nullptr); ~PartRenderer() override; void setRenderPreferences(const gl::RenderPreferences& newPreferences); ModelId getHighlightedObject() const; void addRenderLayer(RenderLayer* layer); void setLayerEnabled(RenderLayer* layer, bool enabled); std::optional<glm::vec3> screenToModelCoordinates(const QPointF& point, const Plane& plane) const; QPointF modelToScreenCoordinates(const glm::vec3& point) const; bool isDark() const; std::int32_t pick(QPoint where); void setSelection(const QSet<std::int32_t>& selectedIds); glm::vec3 cameraVector(const QPointF& point) const; Line<3> cameraLine(const QPointF& point) const; Q_SIGNALS: void projectionMatrixChanged(const glm::mat4& newMatrix); void modelMatrixChanged(const glm::mat4& newMatrix); void viewMatrixChanged(const glm::mat4& newMatrix); void renderPreferencesChanged(); void message(const Message& message); private: void initializeGL() override; void resizeGL(int width, int height) override; void paintGL() override; void mouseMoveEvent(QMouseEvent* event) override; void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; void keyReleaseEvent(QKeyEvent* event) override; void wheelEvent(QWheelEvent* event) override; glm::vec3 unproject(const glm::vec3& win) const; void setFragmentStyle(gl::FragmentStyle fragStyle); void renderScene(); void updateViewMatrix(); void updateModelMatrix(); Q_SLOT void build(); void renderVao(const gl::ArrayClass arrayClass); void checkForGLErrors(); }; inline QVector<QPointF> convertWorldPointsToScreenPoints( const std::vector<glm::vec3> &worldPoints, const PartRenderer* renderer) { QVector<QPointF> points2d; points2d.reserve(static_cast<int>(worldPoints.size())); for (const glm::vec3& point : worldPoints) { points2d.push_back(renderer->modelToScreenCoordinates(point)); } return points2d; } inline Winding worldPolygonWinding( const std::vector<glm::vec3> &points, const PartRenderer* renderer) { return winding(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)}); } inline void drawWorldPoint( QPainter* painter, const glm::vec3& worldPoint, const PartRenderer* renderer) { const QPointF center = renderer->modelToScreenCoordinates(worldPoint); painter->drawEllipse(inscribe(CircleF{center, 5})); } inline void drawWorldPolyline( QPainter *painter, const std::vector<glm::vec3> &points, const PartRenderer* renderer) { painter->drawPolyline(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)}); } inline void drawWorldPolygon( QPainter* painter, const std::vector<glm::vec3> &points, const PartRenderer* renderer) { painter->drawPolygon(QPolygonF{convertWorldPointsToScreenPoints(points, renderer)}); }