Created
May 2, 2025 09:45
-
-
Save kikitte/b07286141a92f87e4ed0c9a502ecfda5 to your computer and use it in GitHub Desktop.
defining multiple geometry types based on glm vector
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include <type_traits> | |
| #define GLM_FORCE_XYZW_ONLY | |
| #include <glm/vec2.hpp> | |
| #include <glm/vec3.hpp> | |
| #include <boost/geometry/core/cs.hpp> | |
| #include <boost/geometry/geometries/point.hpp> | |
| #include <boost/geometry/geometries/multi_point.hpp> | |
| #include <boost/geometry/geometries/linestring.hpp> | |
| #include <boost/geometry/geometries/multi_linestring.hpp> | |
| #include <boost/geometry/geometries/polygon.hpp> | |
| #include <boost/geometry/geometries/multi_polygon.hpp> | |
| #include <boost/geometry/geometries/box.hpp> | |
| // Traits to check if a type is a glm vector | |
| template<typename T> | |
| struct is_glm_vector : std::false_type | |
| {}; | |
| template<glm::length_t L, typename T, glm::qualifier Q> | |
| struct is_glm_vector<glm::vec<L, T, Q>> : std::true_type | |
| {}; | |
| template<typename T> | |
| struct is_glm_vector2 : std::false_type | |
| {}; | |
| template<typename T, glm::qualifier Q> | |
| struct is_glm_vector2<glm::vec<2, T, Q>> : std::true_type | |
| {}; | |
| template<typename T> | |
| struct is_glm_vector3 : std::false_type | |
| {}; | |
| template<typename T, glm::qualifier Q> | |
| struct is_glm_vector3<glm::vec<3, T, Q>> : std::true_type | |
| {}; | |
| // Make a glm vector as a valid point geometry | |
| namespace boost | |
| { | |
| namespace geometry | |
| { | |
| namespace traits | |
| { | |
| template<typename T> | |
| struct tag<T, typename std::enable_if<is_glm_vector<T>::value>::type> | |
| { | |
| using type = point_tag; | |
| }; | |
| template<typename T> | |
| struct dimension<T, typename std::enable_if<is_glm_vector<T>::value>::type> | |
| { | |
| static constexpr std::size_t value = static_cast<std::size_t>( T::length() ); | |
| }; | |
| template<typename T> | |
| struct coordinate_type<T, typename std::enable_if<is_glm_vector<T>::value>::type> | |
| { | |
| using type = typename T::value_type; | |
| }; | |
| template<typename T> | |
| struct coordinate_system<T, typename std::enable_if<is_glm_vector<T>::value>::type> | |
| { | |
| using type = boost::geometry::cs::cartesian; | |
| }; | |
| template<typename T> | |
| struct access<T, 0, typename std::enable_if<is_glm_vector<T>::value>::type> | |
| { | |
| using CoordinateType = typename coordinate_type<T>::type; | |
| static inline CoordinateType get( const T &p ) { return p.x; } | |
| static inline void set( T &p, const CoordinateType &value ) { p.x = value; } | |
| }; | |
| template<typename T> | |
| struct access<T, 1, typename std::enable_if<is_glm_vector<T>::value>::type> | |
| { | |
| using CoordinateType = typename coordinate_type<T>::type; | |
| static inline CoordinateType get( const T &p ) { return p.y; } | |
| static inline void set( T &p, const CoordinateType &value ) { p.y = value; } | |
| }; | |
| template<typename T> | |
| struct access<T, 2, typename std::enable_if<is_glm_vector3<T>::value>::type> | |
| { | |
| using CoordinateType = typename coordinate_type<T>::type; | |
| static inline CoordinateType get( const T &p ) { return p.z; } | |
| static inline void set( T &p, const CoordinateType &value ) { p.z = value; } | |
| }; | |
| } //namespace traits | |
| } //namespace geometry | |
| } //namespace boost | |
| namespace glm_bg | |
| { | |
| // 3 is the dimension number. | |
| using point3 = glm::dvec3; | |
| using multipoint3 = boost::geometry::model::multi_point<point3>; | |
| using line3 = boost::geometry::model::linestring<point3>; | |
| using multiline3 = boost::geometry::model::multi_linestring<line3>; | |
| using polygon3 = boost::geometry::model::polygon<point3>; | |
| using multipolygon3 = boost::geometry::model::multi_polygon<polygon3>; | |
| using box3 = boost::geometry::model::box<point3>; | |
| using point2 = glm::dvec2; | |
| using multipoint2 = boost::geometry::model::multi_point<point2>; | |
| using line2 = boost::geometry::model::linestring<point2>; | |
| using multiline2 = boost::geometry::model::multi_linestring<line2>; | |
| using polygon2 = boost::geometry::model::polygon<point2>; | |
| using multipolygon2 = boost::geometry::model::multi_polygon<polygon2>; | |
| using box2 = boost::geometry::model::box<point2>; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment