Fri, 04 Mar 2022 11:37:50 +0200
Major refactoring
- Model now just stores objects
- Document contains business logic
- Model::EditContext is now ModelEditor, no longer a nested class
#pragma once #include "basics.h" namespace geom { struct Plane { glm::vec3 normal; glm::vec3 anchor; }; template<int N, typename T = float, glm::qualifier Q = glm::defaultp> struct Line { glm::vec<N, T, Q> direction; glm::vec<N, T, Q> anchor; }; template<int N, typename T = float, glm::qualifier Q = glm::defaultp> struct Ray { glm::vec<N, T, Q> direction; glm::vec<N, T, Q> anchor; }; template<int N> struct Polygon { std::array<glm::vec3, N> points; }; template<int N> struct Polygon2D { glm::vec2 points[N]; }; inline const glm::vec3 origin = {0, 0, 0}; inline const Plane XY = {{0, 0, 1}, origin}; inline const Plane XZ = {{0, 1, 0}, origin}; inline const Plane YZ = {{1, 0, 0}, origin}; using Triangle = Polygon<3>; using LineSegment2D = Polygon2D<2>; /** * @brief Computes a line from two points * @param point_1 * @param point_2 * @return line */ template<int N, typename T, glm::qualifier Q> Line<N, T, Q> lineFromPoints(const glm::vec<N, T, Q>& point_1, const glm::vec<N, T, Q>& point_2) { return {point_2 - point_1, point_1}; } template<int N, typename T, glm::qualifier Q> Ray<N, T, Q> rayFromPoints(const glm::vec<N, T, Q>& point_1, const glm::vec<N, T, Q>& point_2) { return {point_2 - point_1, point_1}; } template<int N, typename T, glm::qualifier Q> Line<N, T, Q> rayToLine(const Ray<N, T, Q>& ray) { return {ray.direction, ray.anchor}; } enum class RectangleSide { Top, Left, Bottom, Right }; struct PointOnRectagle { glm::vec2 position; RectangleSide side; }; std::optional<glm::vec2> lineLineIntersection(const Line<2>& line_1, const Line<2>& line_2); std::optional<glm::vec2> rayLineSegmentIntersection(const Ray<2>& ray, const LineSegment2D& line); std::optional<PointOnRectagle> rayRectangleIntersection(const Ray<2>& ray, const QRectF& rectangle); Plane planeFromTriangle(const Triangle& triangle); glm::vec3 normalVector(const Triangle& triangle); std::optional<glm::vec3> linePlaneIntersection( const Line<3>& line, const Plane& plane, const float epsilon = 1e-6f); glm::vec3 scalingVector(const glm::mat4 matrix); LineSegment2D top(const QRectF& rectangle); LineSegment2D bottom(const QRectF& rectangle); LineSegment2D left(const QRectF& rectangle); LineSegment2D right(const QRectF& rectangle); bool isConvex(const std::vector<glm::vec3>& polygon); struct ScalingExtract { glm::vec3 scaling; glm::mat4 unscaled; }; ScalingExtract extractScaling(const glm::mat4& matrix); struct NPolygon { std::vector<glm::vec3> points; }; inline constexpr bool isclose(const glm::vec3& a, const glm::vec3& b) { return qFuzzyCompare(a.x, b.x) and qFuzzyCompare(a.y, b.y) and qFuzzyCompare(a.z, b.z); } struct CircleF { QPointF center; qreal radius; }; /** * @brief Inscribes a circle * @param circle * @return a QRectF that inscribes the specified circle */ inline constexpr QRectF inscribe(const CircleF& circle) { return { circle.center.x() - circle.radius, circle.center.y() - circle.radius, circle.radius * 2, circle.radius * 2 }; } }