diff options
Diffstat (limited to 'src/o3d/polygon.hpp')
| -rw-r--r-- | src/o3d/polygon.hpp | 69 |
1 files changed, 49 insertions, 20 deletions
diff --git a/src/o3d/polygon.hpp b/src/o3d/polygon.hpp index 5ede910..47ecafe 100644 --- a/src/o3d/polygon.hpp +++ b/src/o3d/polygon.hpp @@ -17,11 +17,39 @@ concept PolygonVectorTypeConcept = engine::math::VectorTypeConcept<T> && (std::i template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count> struct Polygon; +class ToPolygon { + public: + constexpr ToPolygon() {} +}; + template<engine::math::VectorTypeConcept VectorType> -constexpr Polygon<VectorType, 3> from_triangle_derived(const engine::o3d::TriangleDerived<VectorType>& triangle_derived); +constexpr Polygon<VectorType, 3> operator|(const engine::o3d::TriangleDerived<VectorType>& triangle_derived, ToPolygon); template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count, engine::math::vector_coords::VectorCoord coord_id, bool keep_geq> -constexpr Polygon<VectorType, max_points_count + 1> clip_aligned(float boundary, const Polygon<VectorType, max_points_count>& polygon); +class ClipAligned { + public: + constexpr ClipAligned(float boundary) : m_boundary { boundary } {} + + constexpr float boundary() const & { + return m_boundary; + } + private: + float m_boundary; +}; + +template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count, engine::math::vector_coords::VectorCoord coord_id, bool keep_geq> +constexpr Polygon<VectorType, max_points_count + 1> operator|(const Polygon<VectorType, max_points_count>& polygon, + ClipAligned<VectorType, max_points_count, coord_id, keep_geq> clip_aligned); + +class DivByW { + public: + constexpr DivByW() {} +}; + +class SignedAreaXY { + public: + constexpr SignedAreaXY() {} +}; template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count> struct Polygon { @@ -33,19 +61,19 @@ struct Polygon { : points_count { points_count }, points { points } {} constexpr Polygon<VectorType, max_points_count + 2> clip_z(float z1, float z2) const & { - return - clip_aligned<VectorType, max_points_count + 1, engine::math::vector_coords::VectorCoord::z, false>(z2, - clip_aligned<VectorType, max_points_count + 0, engine::math::vector_coords::VectorCoord::z, true >(z1, - *this)); + return *this + | ClipAligned<VectorType, max_points_count + 0, engine::math::vector_coords::VectorCoord::z, true >(z1) + | ClipAligned<VectorType, max_points_count + 1, engine::math::vector_coords::VectorCoord::z, false>(z2) + ; } constexpr Polygon<VectorType, max_points_count + 4> clip_xy(float x1, float y1, float x2, float y2) const & { - return - clip_aligned<VectorType, max_points_count + 3, engine::math::vector_coords::VectorCoord::y, false>(y2, - clip_aligned<VectorType, max_points_count + 2, engine::math::vector_coords::VectorCoord::x, false>(x2, - clip_aligned<VectorType, max_points_count + 1, engine::math::vector_coords::VectorCoord::y, true >(y1, - clip_aligned<VectorType, max_points_count + 0, engine::math::vector_coords::VectorCoord::x, true >(x1, - *this)))); + return *this + | ClipAligned<VectorType, max_points_count + 0, engine::math::vector_coords::VectorCoord::x, true >(x1) + | ClipAligned<VectorType, max_points_count + 1, engine::math::vector_coords::VectorCoord::y, true >(y1) + | ClipAligned<VectorType, max_points_count + 2, engine::math::vector_coords::VectorCoord::x, false>(x2) + | ClipAligned<VectorType, max_points_count + 3, engine::math::vector_coords::VectorCoord::y, false>(y2) + ; } constexpr Polygon<VectorType, max_points_count> map_xy( @@ -89,12 +117,13 @@ struct Polygon { }; template<engine::math::VectorTypeConcept VectorType> -constexpr Polygon<VectorType, 3> from_triangle_derived(const engine::o3d::TriangleDerived<VectorType>& triangle_derived) { +constexpr Polygon<VectorType, 3> operator|(const engine::o3d::TriangleDerived<VectorType>& triangle_derived, ToPolygon) { return { 3, { triangle_derived.derived_vertex1, triangle_derived.derived_vertex2, triangle_derived.derived_vertex3 } }; } template<PolygonVectorTypeConcept VectorType, std::size_t max_points_count, engine::math::vector_coords::VectorCoord coord_id, bool keep_geq> -constexpr Polygon<VectorType, max_points_count + 1> clip_aligned(float boundary, const Polygon<VectorType, max_points_count>& polygon) +constexpr Polygon<VectorType, max_points_count + 1> operator|(const Polygon<VectorType, max_points_count>& polygon, + ClipAligned<VectorType, max_points_count, coord_id, keep_geq> clip_aligned) { using transposition = engine::math::vector_coords::transpose<engine::math::vector_coords::VectorCoord::x, coord_id>; constexpr auto y_coord_id = transposition::template id<engine::math::vector_coords::VectorCoord::y>(); @@ -107,10 +136,10 @@ constexpr Polygon<VectorType, max_points_count + 1> clip_aligned(float boundary, for (size_t i = 0; i < polygon.points_count; i++) { const auto& prev = polygon.points[(i + polygon.points_count - 1) % polygon.points_count]; const auto& cur = polygon.points[i]; - if (is_in(prev, boundary) != is_in(cur, boundary)) { - float fac = (boundary - prev.vertex.template v<coord_id>()) / (cur.vertex.template v<coord_id>() - prev.vertex.template v<coord_id>()); + if (is_in(prev, clip_aligned.boundary()) != is_in(cur, clip_aligned.boundary())) { + float fac = (clip_aligned.boundary() - prev.vertex.template v<coord_id>()) / (cur.vertex.template v<coord_id>() - prev.vertex.template v<coord_id>()); auto& new_point = new_polygon.points[new_polygon.points_count++]; - new_point.vertex.template v<coord_id>() = boundary; + new_point.vertex.template v<coord_id>() = clip_aligned.boundary(); new_point.vertex.template v<y_coord_id>() = engine::math::utils::lerp(prev.vertex.template v<y_coord_id>(), cur.vertex.template v<y_coord_id>(), fac); if constexpr (std::is_same_v<VectorType, engine::math::Vector3>) { // called new_w because it represents w, but because we only need x, y and w, we use @@ -127,14 +156,14 @@ constexpr Polygon<VectorType, max_points_count + 1> clip_aligned(float boundary, new_point.b1 = engine::math::utils::lerp(prev.b1, cur.b1, fac); } } - if (is_in(cur, boundary)) + if (is_in(cur, clip_aligned.boundary())) new_polygon.points[new_polygon.points_count++] = cur; } return new_polygon; } template<std::size_t max_points_count> -constexpr Polygon<engine::math::Vector3, max_points_count> div_by_w(const Polygon<engine::math::Vector4, max_points_count>& polygon) { +constexpr Polygon<engine::math::Vector3, max_points_count> operator|(const Polygon<engine::math::Vector4, max_points_count>& polygon, DivByW) { Polygon<engine::math::Vector3, max_points_count> new_polygon; new_polygon.points_count = polygon.points_count; for (std::size_t i = 0; i < polygon.points_count; i++) @@ -143,7 +172,7 @@ constexpr Polygon<engine::math::Vector3, max_points_count> div_by_w(const Polygo } template<std::size_t max_points_count> -constexpr float signed_area_xy(const Polygon<engine::math::Vector3, max_points_count>& polygon) { +constexpr float operator|(const Polygon<engine::math::Vector3, max_points_count>& polygon, SignedAreaXY) { float res = 0.f; if (polygon.points_count > 0) { for (std::size_t i = 0; i < polygon.points_count - 1; i++) |
