summaryrefslogtreecommitdiff
path: root/src/mbgl/util/vec.hpp
blob: 40d540fca4eef47cd7a3384cfda0a49ae1c21abc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#ifndef MBGL_UTIL_VEC
#define MBGL_UTIL_VEC

#include <limits>
#include <type_traits>
#include <cmath>
#include <cstdint>
#include <array>

namespace mbgl {

template <typename T = double>
struct vec2 {
    struct null {};
    typedef T Type;

    T x, y;

    inline vec2() = default;

    template<typename U = T, typename std::enable_if<std::numeric_limits<U>::has_quiet_NaN, int>::type = 0>
    inline vec2(null) : x(std::numeric_limits<T>::quiet_NaN()), y(std::numeric_limits<T>::quiet_NaN()) {}

    template<typename U = T, typename std::enable_if<!std::numeric_limits<U>::has_quiet_NaN, int>::type = 0>
    inline vec2(null) : x(std::numeric_limits<T>::min()), y(std::numeric_limits<T>::min()) {}

    inline vec2(const vec2& o) = default;

    template<typename U>
    inline vec2(const U& u) : x(u.x), y(u.y) {}

    inline vec2(T x_, T y_) : x(x_), y(y_) {}

    inline bool operator==(const vec2& rhs) const {
        return x == rhs.x && y == rhs.y;
    }

    template <typename O>
    inline typename std::enable_if<std::is_arithmetic<O>::value, vec2>::type
    operator*(O o) const {
        return {x * o, y * o};
    }

    inline void operator*=(T o) {
        x *= o;
        y *= o;
    }

    template <typename O>
    inline typename std::enable_if<std::is_arithmetic<O>::value, vec2>::type
    operator/(O o) const {
        return {x / o, y / o};
    }

    inline void operator/=(T o) {
        x /= o;
        y /= o;
    }

    inline vec2<T> operator *(const std::array<float, 16>& matrix) {
        return { x * matrix[0] + y * matrix[4] + matrix[12], x * matrix[1] + y * matrix[5] + matrix[13] };
    }

    template <typename O>
    inline typename std::enable_if<std::is_arithmetic<O>::value, vec2>::type
    operator-(O o) const {
        return {x - o, y - o};
    }

    template <typename O>
    inline typename std::enable_if<!std::is_arithmetic<O>::value, vec2>::type
    operator-(const O &o) const {
        return vec2<T>(x - o.x, y - o.y);
    }

    template <typename O>
    inline typename std::enable_if<!std::is_arithmetic<O>::value, vec2>::type
    operator+(const O &o) const {
        return vec2<T>(x + o.x, y + o.y);
    }

    template <typename M>
    inline vec2 matMul(const M &m) const {
        return {m[0] * x + m[1] * y, m[2] * x + m[3] * y};
    }

    template<typename U = T, typename std::enable_if<std::numeric_limits<U>::has_quiet_NaN, int>::type = 0>
    explicit operator bool() const {
        return !std::isnan(x) && !std::isnan(y);
    }

    template<typename U = T, typename std::enable_if<!std::numeric_limits<U>::has_quiet_NaN, int>::type = 0>
    explicit operator bool() const {
        return x != std::numeric_limits<T>::min() && y != std::numeric_limits<T>::min();
    }
};

template <typename T = double>
struct vec4 {
    T x, y, z, w;

    inline vec4() = default;
    inline vec4(const vec4& o) : x(o.x), y(o.y), z(o.z), w(o.w) {}
    inline vec4(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) {}
    inline bool operator==(const vec4& rhs) const {
        return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w;
    }

    template<typename U = T, typename std::enable_if<std::numeric_limits<U>::has_quiet_NaN, int>::type = 0>
    explicit operator bool() const {
        return !std::isnan(x) && !std::isnan(y) && !std::isnan(z) && !std::isnan(w);
    }

    template<typename U = T, typename std::enable_if<!std::numeric_limits<U>::has_quiet_NaN, int>::type = 0>
    explicit operator bool() const {
        return x != std::numeric_limits<T>::min()
            && y != std::numeric_limits<T>::min()
            && z != std::numeric_limits<T>::min()
            && w != std::numeric_limits<T>::min();
    }
};


} // namespace mbgl

#endif // MBGL_UTIL_VEC