sandbox
Loading...
Searching...
No Matches
vector3.hpp
1#ifndef LIBSBX_MATH_VECTOR3_HPP_
2#define LIBSBX_MATH_VECTOR3_HPP_
3
4#include <concepts>
5#include <cstddef>
6#include <cmath>
7#include <fstream>
8#include <ostream>
9#include <type_traits>
10
11#include <yaml-cpp/yaml.h>
12
13#include <fmt/format.h>
14
15#include <libsbx/math/concepts.hpp>
16#include <libsbx/math/vector.hpp>
17#include <libsbx/math/vector2.hpp>
18
19namespace sbx::math {
20
21template<scalar Type>
22class basic_vector3 : public basic_vector<3u, Type> {
23
25
26 inline static constexpr auto x_axis = std::size_t{0u};
27 inline static constexpr auto y_axis = std::size_t{1u};
28 inline static constexpr auto z_axis = std::size_t{2u};
29
30public:
31
32 using value_type = base_type::value_type;
33 using reference = base_type::reference;
34 using const_reference = base_type::const_reference;
35 using size_type = base_type::size_type;
36 using length_type = base_type::length_type;
37
38 inline static constexpr basic_vector3 zero{base_type::fill(value_type{0})};
39 inline static constexpr basic_vector3 one{base_type::fill(value_type{1})};
40 inline static constexpr basic_vector3 right{base_type::template axis<x_axis>(value_type{1})};
41 inline static constexpr basic_vector3 left{base_type::template axis<x_axis>(value_type{-1})};
42 inline static constexpr basic_vector3 up{base_type::template axis<y_axis>(value_type{1})};
43 inline static constexpr basic_vector3 down{base_type::template axis<y_axis>(value_type{-1})};
44 inline static constexpr basic_vector3 forward{base_type::template axis<z_axis>(value_type{-1})};
45 inline static constexpr basic_vector3 backward{base_type::template axis<z_axis>(value_type{1})};
46
47 using base_type::base_type;
48
49 constexpr basic_vector3(const base_type& base) noexcept;
50
51 template<scalar X, scalar Y, scalar Z>
52 constexpr basic_vector3(X x, Y y, Z z) noexcept;
53
54 template<scalar Other, scalar Scalar = Other>
55 constexpr basic_vector3(const basic_vector2<Other>& vector, Scalar z = Scalar{0}) noexcept;
56
57 [[nodiscard]] static constexpr auto cross(const basic_vector3& lhs, const basic_vector3& rhs) noexcept -> basic_vector3;
58
59 [[nodiscard]] static constexpr auto dot(const basic_vector3& lhs, const basic_vector3& rhs) noexcept -> length_type;
60
61 [[nodiscard]] static constexpr auto normalized(const basic_vector3& vector) noexcept -> basic_vector3;
62
63 [[nodiscard]] static constexpr auto reflect(const basic_vector3& vector, const basic_vector3& normal) noexcept -> basic_vector3;
64
65 [[nodiscard]] static constexpr auto abs(const basic_vector3& vector) noexcept -> basic_vector3;
66
67 [[nodiscard]] static constexpr auto distance_squared(const basic_vector3& lhs, const basic_vector3& rhs) noexcept -> value_type;
68
69 [[nodiscard]] static constexpr auto distance(const basic_vector3& lhs, const basic_vector3& rhs) noexcept -> value_type;
70
71 [[nodiscard]] static constexpr auto splat_x(const basic_vector3& vector) noexcept -> basic_vector3 {
72 return base_type::template splat<x_axis>(vector);
73 }
74
75 [[nodiscard]] static constexpr auto splat_y(const basic_vector3& vector) noexcept -> basic_vector3 {
76 return base_type::template splat<y_axis>(vector);
77 }
78
79 [[nodiscard]] static constexpr auto splat_z(const basic_vector3& vector) noexcept -> basic_vector3 {
80 return base_type::template splat<z_axis>(vector);
81 }
82
83 // /**
84 // * @brief Linearly interpolates between two vectors.
85 // *
86 // * @param start The starting vector.
87 // * @param end The ending vector.
88 // * @param t The interpolation factor [0.0f, 1.0f].
89 // *
90 // * @return A new vector that is the result of the linear interpolation.
91 // */
92 // [[nodiscard]] static constexpr auto lerp(const basic_vector3& start, const basic_vector3& end, const value_type t) noexcept -> basic_vector3 {
93 // utility::assert_that(t >= 0.0f && t <= 1.0f, "Interpolation factor out of bounds in vector3 lerp");
94 // return start * (1.0f - t) + end * t;
95 // }
96
97 [[nodiscard]] constexpr operator basic_vector2<Type>() const noexcept;
98
99 [[nodiscard]] constexpr auto x() noexcept -> reference;
100
101 [[nodiscard]] constexpr auto x() const noexcept -> const_reference;
102
103 [[nodiscard]] constexpr auto y() noexcept -> reference;
104
105 [[nodiscard]] constexpr auto y() const noexcept -> const_reference;
106
107 [[nodiscard]] constexpr auto z() noexcept -> reference;
108
109 [[nodiscard]] constexpr auto z() const noexcept -> const_reference;
110
111 constexpr auto normalize() noexcept -> basic_vector3&;
112
113}; // template<scalar Type>
114
115template<scalar Lhs, scalar Rhs>
116[[nodiscard]] constexpr auto operator+(basic_vector3<Lhs> lhs, const basic_vector3<Rhs>& rhs) noexcept -> basic_vector3<Lhs>;
117
118template<scalar Lhs, scalar Rhs>
119[[nodiscard]] constexpr auto operator-(basic_vector3<Lhs> lhs, const basic_vector3<Rhs>& rhs) noexcept -> basic_vector3<Lhs>;
120
121template<scalar Type>
122[[nodiscard]] constexpr auto operator-(basic_vector3<Type> vector) noexcept -> basic_vector3<Type>;
123
124template<scalar Lhs, scalar Rhs>
125[[nodiscard]] constexpr auto operator*(basic_vector3<Lhs> lhs, Rhs scalar) noexcept -> basic_vector3<Lhs>;
126
127template<scalar Lhs, scalar Rhs>
128[[nodiscard]] constexpr auto operator*(Lhs scalar, basic_vector3<Rhs> rhs) noexcept -> basic_vector3<Rhs>;
129
130template<scalar Lhs, std::convertible_to<Lhs> Rhs>
131requires (!is_scalar_v<Rhs>)
132[[nodiscard]] constexpr auto operator*(basic_vector3<Lhs> lhs, const Rhs& rhs) noexcept -> basic_vector3<Lhs>;
133
134template<scalar Lhs, scalar Rhs>
135[[nodiscard]] constexpr auto operator*(basic_vector3<Lhs> lhs, const basic_vector3<Rhs>& rhs) noexcept -> basic_vector3<Lhs>;
136
137template<scalar Lhs, scalar Rhs>
138[[nodiscard]] constexpr auto operator/(basic_vector3<Lhs> lhs, Rhs scalar) noexcept -> basic_vector3<Lhs>;
139
140template<scalar Lhs, std::convertible_to<Lhs> Rhs>
141requires (!is_scalar_v<Rhs>)
142[[nodiscard]] constexpr auto operator/(basic_vector3<Lhs> lhs, const Rhs& rhs) noexcept -> basic_vector3<Lhs>;
143
145
147
149
150using vector3 = vector3f;
151
152} // namespace sbx::math
153
154template<sbx::math::scalar Type>
155struct std::hash<sbx::math::basic_vector3<Type>> {
156
157 inline auto operator()(const sbx::math::basic_vector3<Type>& vector) const noexcept -> std::size_t;
158
159}; // struct std::hash<sbx::math::basic_vector3<Type>>
160
161template<sbx::math::scalar Type>
162struct fmt::formatter<sbx::math::basic_vector3<Type>> {
163
164 template<typename ParseContext>
165 constexpr auto parse(ParseContext& context) noexcept -> decltype(context.begin());
166
167 template<typename FormatContext>
168 auto format(const sbx::math::basic_vector3<Type>& vector, FormatContext& context) const noexcept -> decltype(context.out());
169
170}; // struct fmt::formatter<sbx::math::basic_vector3<Type>>
171
172template<sbx::math::scalar Type>
173struct YAML::convert<sbx::math::basic_vector3<Type>> {
174
175 static auto encode(const sbx::math::basic_vector3<Type>& rhs) -> YAML::Node {
176 auto node = Node{};
177
178 node.SetStyle(YAML::EmitterStyle::Flow);
179
180 node["x"] = rhs.x();
181 node["y"] = rhs.y();
182 node["z"] = rhs.z();
183
184 return node;
185 }
186
187 static auto decode(const YAML::Node& node, sbx::math::basic_vector3<Type>& rhs) -> bool {
188 if (!node.IsMap()) {
189 return false;
190 }
191
192 rhs.x() = node["x"].as<Type>();
193 rhs.y() = node["y"].as<Type>();
194 rhs.z() = node["z"].as<Type>();
195
196 return true;
197 }
198
199}; // struct YAML::convert<sbx::math::basic_vector3<Type>>
200
201template<sbx::math::scalar Type>
202auto operator<<(YAML::Emitter& out, const sbx::math::basic_vector3<Type>& vector) -> YAML::Emitter& {
203 return out << YAML::convert<sbx::math::basic_vector3<Type>>::encode(vector);
204}
205
206#include <libsbx/math/vector3.ipp>
207
208#endif // LIBSBX_MATH_VECTOR3_HPP_
209
Definition: tests.cpp:5
A vector in two-dimensional space.
Definition: vector2.hpp:27
Definition: vector3.hpp:22
Definition: vector.hpp:22