libs/base/src/base/vec3.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <tuple> | ||
| 4 | |||
| 5 | #include "assert/assert.h" | ||
| 6 | |||
| 7 | #include "base/numeric.h" | ||
| 8 | |||
| 9 | namespace eu | ||
| 10 | { | ||
| 11 | /** \addtogroup math | ||
| 12 | * @{ | ||
| 13 | */ | ||
| 14 | |||
| 15 | //////////////////////////////////////////////////////////////////////////////// | ||
| 16 | // Forward declarations | ||
| 17 | |||
| 18 | struct Q; | ||
| 19 | |||
| 20 | struct v3; | ||
| 21 | struct n3; | ||
| 22 | |||
| 23 | //////////////////////////////////////////////////////////////////////////////// | ||
| 24 | |||
| 25 | /// a 3d vector | ||
| 26 | struct v3 | ||
| 27 | { | ||
| 28 | float x; | ||
| 29 | float y; | ||
| 30 | float z; | ||
| 31 | |||
| 32 | explicit v3(float a); | ||
| 33 | explicit v3(const std::tuple<float, float, float> &a); | ||
| 34 | 305 | constexpr v3(float ax, float ay, float az) | |
| 35 | 305 | : x(ax), y(ay), z(az) | |
| 36 | { | ||
| 37 | 305 | } | |
| 38 | |||
| 39 | /// assumes the given pointer is a array of 3 floats | ||
| 40 | explicit v3(const float *a); | ||
| 41 | |||
| 42 | /// creates a vector going from `from` to `to` | ||
| 43 | static v3 from_to(const v3 &from, const v3 &to); | ||
| 44 | |||
| 45 | /// Creates a vector in quaterion local space from Right Up In. | ||
| 46 | [[nodiscard]] static v3 from_localspace_rui(const Q& rotation, float right, float up, float in); | ||
| 47 | |||
| 48 | [[nodiscard]] float dot(const v3 &rhs) const; | ||
| 49 | [[nodiscard]] v3 cross(const v3 &u) const; | ||
| 50 | |||
| 51 | void operator+=(const v3 &rhs); | ||
| 52 | void operator-=(const v3 &rhs); | ||
| 53 | void operator/=(float rhs); | ||
| 54 | void operator*=(float rhs); | ||
| 55 | v3 operator-() const; | ||
| 56 | |||
| 57 | /// Returns an array to the data. | ||
| 58 | /// non const so it's useful for letting an API tweak the members. | ||
| 59 | float *get_data_ptr(); | ||
| 60 | |||
| 61 | /// Returns an array to the data | ||
| 62 | [[nodiscard]] const float *get_data_ptr() const; | ||
| 63 | |||
| 64 | /// Returns the squared length of the vector. | ||
| 65 | /// This is useful if you want to compare to zero, sort by length or similar, otherwise see @ref get_length() | ||
| 66 | 299 | [[nodiscard]] constexpr float get_length_squared() const | |
| 67 | { | ||
| 68 | 299 | return x * x + y * y + z * z; | |
| 69 | } | ||
| 70 | |||
| 71 | /// Returns the length of the vector | ||
| 72 | [[nodiscard]] float get_length() const; | ||
| 73 | |||
| 74 | /** Changes the length to 1. | ||
| 75 | * If the calculated length is zero, the vector is changed to a known value and false is returned | ||
| 76 | */ | ||
| 77 | bool normalize(); | ||
| 78 | |||
| 79 | /// Returns a unit vector. | ||
| 80 | /// if the length is zero, `nullopt` is returend | ||
| 81 | [[nodiscard]] std::optional<n3> get_normalized() const; | ||
| 82 | |||
| 83 | bool operator==(const v3 &rhs) = delete; | ||
| 84 | }; | ||
| 85 | |||
| 86 | constexpr v3 zero3f = v3{0.0f, 0.0f, 0.0f}; | ||
| 87 | |||
| 88 | //////////////////////////////////////////////////////////////////////////////// | ||
| 89 | |||
| 90 | /// a 3d unit (vector) | ||
| 91 | struct n3 : public v3 | ||
| 92 | { | ||
| 93 | 29 | constexpr n3 operator-() const | |
| 94 | { | ||
| 95 | 29 | return {-this->x, -this->y, -this->z}; | |
| 96 | } | ||
| 97 | |||
| 98 | /// returns false if the length isn't 1 | ||
| 99 | [[nodiscard]] constexpr bool | ||
| 100 | 245 | is_valid() const | |
| 101 | { | ||
| 102 | 245 | return is_equal(get_length_squared(), 1.0f); | |
| 103 | } | ||
| 104 | |||
| 105 | bool operator==(const n3 &rhs) = delete; | ||
| 106 | |||
| 107 | /// asserts that the length is 1 | ||
| 108 | 41 | constexpr n3(float a, float b, float c) | |
| 109 | 41 | : v3(a, b, c) | |
| 110 | { | ||
| 111 | 41 | ASSERT(is_valid()); | |
| 112 | 41 | } | |
| 113 | |||
| 114 | /// asserts that the length is 1 | ||
| 115 | 58 | constexpr explicit n3(const v3& v) | |
| 116 | 58 | : v3(v) | |
| 117 | { | ||
| 118 | 58 | ASSERT(is_valid()); | |
| 119 | 58 | } | |
| 120 | }; | ||
| 121 | |||
| 122 | namespace kk | ||
| 123 | { | ||
| 124 | constexpr n3 x_axis = n3{1.0f, 0.0f, 0.0f}; | ||
| 125 | constexpr n3 y_axis = n3{0.0f, 1.0f, 0.0f}; | ||
| 126 | constexpr n3 z_axis = n3{0.0f, 0.0f, 1.0f}; | ||
| 127 | constexpr n3 up = y_axis; | ||
| 128 | constexpr n3 down = -y_axis; | ||
| 129 | constexpr n3 right = x_axis; | ||
| 130 | constexpr n3 left = -x_axis; | ||
| 131 | constexpr n3 in = -z_axis; | ||
| 132 | constexpr n3 out = z_axis; | ||
| 133 | } | ||
| 134 | |||
| 135 | v3 operator+(const v3 &lhs, const v3 &rhs); | ||
| 136 | v3 operator-(const v3 &lhs, const v3 &rhs); | ||
| 137 | v3 operator*(float lhs, const v3 &rhs); | ||
| 138 | v3 operator*(const v3 &lhs, float rhs); | ||
| 139 | v3 operator/(const v3 &lhs, float rhs); | ||
| 140 | v3 operator/(float lhs, const v3 &rhs); | ||
| 141 | |||
| 142 | |||
| 143 | v3 lerp_v3(const v3 &f, float v, const v3 &t); | ||
| 144 | |||
| 145 | /// convert a 3d vector to string, prefer fmt | ||
| 146 | std::string string_from(const v3 &v); | ||
| 147 | |||
| 148 | /// converts a 3d unit vector to string, prefer fmt | ||
| 149 | std::string string_from(const n3 &v); | ||
| 150 | |||
| 151 | /// component wise min value | ||
| 152 | constexpr v3 | ||
| 153 | min(const v3 &lhs, const v3 &rhs) | ||
| 154 | { | ||
| 155 | return { | ||
| 156 | eu::min(lhs.x, rhs.x), | ||
| 157 | eu::min(lhs.y, rhs.y), | ||
| 158 | eu::min(lhs.z, rhs.z) | ||
| 159 | }; | ||
| 160 | } | ||
| 161 | |||
| 162 | /// component wise max value | ||
| 163 | constexpr v3 | ||
| 164 | max(const v3 &lhs, const v3 &rhs) | ||
| 165 | { | ||
| 166 | return { | ||
| 167 | eu::max(lhs.x, rhs.x), | ||
| 168 | eu::max(lhs.y, rhs.y), | ||
| 169 | eu::max(lhs.z, rhs.z) | ||
| 170 | }; | ||
| 171 | } | ||
| 172 | |||
| 173 | /** @}*/ | ||
| 174 | |||
| 175 | ADD_CATCH_FORMATTER_DEF(v3) | ||
| 176 | ADD_CATCH_FORMATTER_DEF(n3) | ||
| 177 | |||
| 178 | } | ||
| 179 | |||
| 180 | 2 | ADD_DEFAULT_FORMATTER(eu::v3, std::string, eu::string_from); | |
| 181 | 10 | ADD_DEFAULT_FORMATTER(eu::n3, std::string, eu::string_from); | |
| 182 | |||
| 183 |