Pioneer
Loading...
Searching...
No Matches
vector3.h
Go to the documentation of this file.
1// Copyright © 2008-2024 Pioneer Developers. See AUTHORS.txt for details
2// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3
4#ifndef _VECTOR3_H
5#define _VECTOR3_H
6
7#include "FloatComparison.h"
8#include "vector2.h"
9#include <math.h>
10#include <stdio.h>
11
12// Need this pragma due to operator[] implementation.
13#pragma pack(4)
14
15template <typename T>
16class alignas(sizeof(T)) vector3 {
17public:
18 using element_type = T;
19
20 T x, y, z;
21
22 // Constructor definitions are outside class declaration to enforce that
23 // only float and double versions are possible.
24 vector3() = default;
25 vector3(const vector2f &v, T t);
26 explicit vector3(const T vals[3]);
27 explicit vector3(T val);
28 vector3(T _x, T _y, T _z);
29
30 // disallow implicit conversion between floating point sizes
31 explicit vector3(const vector3<typename other_floating_type<T>::type> &v);
32 explicit vector3(const typename other_floating_type<T>::type vals[3]);
33
34 const T &operator[](const size_t i) const { return (const_cast<const T *>(&x))[i]; }
35 T &operator[](const size_t i) { return (&x)[i]; }
36
37 vector3 operator+(const vector3 &a) const { return vector3(a.x + x, a.y + y, a.z + z); }
39 {
40 x += a.x;
41 y += a.y;
42 z += a.z;
43 return *this;
44 }
46 {
47 x -= a.x;
48 y -= a.y;
49 z -= a.z;
50 return *this;
51 }
52 vector3 &operator*=(const float a)
53 {
54 x *= a;
55 y *= a;
56 z *= a;
57 return *this;
58 }
59 vector3 &operator*=(const double a)
60 {
61 x *= a;
62 y *= a;
63 z *= a;
64 return *this;
65 }
66 vector3 &operator/=(const float a)
67 {
68 const T inva = T(1.0 / a);
69 x *= inva;
70 y *= inva;
71 z *= inva;
72 return *this;
73 }
74 vector3 &operator/=(const double a)
75 {
76 const T inva = T(1.0 / a);
77 x *= inva;
78 y *= inva;
79 z *= inva;
80 return *this;
81 }
82 vector3 operator-(const vector3 &a) const { return vector3(x - a.x, y - a.y, z - a.z); }
83 vector3 operator-() const { return vector3(-x, -y, -z); }
84
85 bool operator==(const vector3 &a) const
86 {
87 return is_equal_exact(a.x, x) && is_equal_exact(a.y, y) && is_equal_exact(a.z, z);
88 }
89 bool ExactlyEqual(const vector3 &a) const
90 {
91 return is_equal_exact(a.x, x) && is_equal_exact(a.y, y) && is_equal_exact(a.z, z);
92 }
93
94 friend vector3 operator+(const vector3 &a, const T &scalar) { return vector3(a.x + scalar, a.y + scalar, a.z + scalar); }
95 friend vector3 operator+(const T scalar, const vector3 &a) { return a + scalar; }
96 friend vector3 operator-(const vector3 &a, const T &scalar) { return vector3(a.x - scalar, a.y - scalar, a.z - scalar); }
97 friend vector3 operator-(const T scalar, const vector3 &a) { return a - scalar; }
98
99 friend vector3 operator*(const vector3 &a, const vector3 &b) { return vector3(T(a.x * b.x), T(a.y * b.y), T(a.z * b.z)); }
100 friend vector3 operator*(const vector3 &a, const T scalar) { return vector3(T(a.x * scalar), T(a.y * scalar), T(a.z * scalar)); }
101 //friend vector3 operator*(const vector3 &a, const double scalar) { return vector3(T(a.x*scalar), T(a.y*scalar), T(a.z*scalar)); }
102 friend vector3 operator*(const T scalar, const vector3 &a) { return a * scalar; }
103 //friend vector3 operator*(const double scalar, const vector3 &a) { return a*scalar; }
104 friend vector3 operator/(const vector3 &a, const float scalar)
105 {
106 const T inv = 1.0 / scalar;
107 return vector3(a.x * inv, a.y * inv, a.z * inv);
108 }
109 friend vector3 operator/(const vector3 &a, const double scalar)
110 {
111 const T inv = 1.0 / scalar;
112 return vector3(a.x * inv, a.y * inv, a.z * inv);
113 }
114 friend vector3 operator/(const T scalar, const vector3 &a)
115 {
116 return vector3(scalar / a.x, scalar / a.y, scalar / a.z);
117 }
118
119 // component-wise ALL-less-than
120 auto operator<(const vector3 &b) const { return x < b.x && y < b.y && z < b.z; }
121 // component-wise ALL-less-equal
122 auto operator<=(const vector3 &b) const { return x <= b.x && y <= b.y && z <= b.z; }
123 // component-wise ALL-greater-than
124 auto operator>(const vector3 &b) const { return x > b.x && y > b.y && z > b.z; }
125 // component-wise ALL-greater-equal
126 auto operator>=(const vector3 &b) const { return x >= b.x && y >= b.y && z >= b.z; }
127
128 vector3 Cross(const vector3 &b) const { return vector3(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); }
129 T Dot(const vector3 &b) const { return x * b.x + y * b.y + z * b.z; }
130 T Length() const { return sqrt(x * x + y * y + z * z); }
131 T LengthSqr() const { return x * x + y * y + z * z; }
132 vector3 Lerp(const vector3 &b, const double percent) const
133 {
134 return *this + percent * (b - *this);
135 }
137 {
138 const T l = 1.0f / sqrt(x * x + y * y + z * z);
139 return vector3(x * l, y * l, z * l);
140 }
142 {
143 const T lenSqr = x * x + y * y + z * z;
144 if (lenSqr < 1e-18) // sqrt(lenSqr) < 1e-9
145 return vector3(1, 0, 0);
146 else {
147 const T l = sqrt(lenSqr);
148 return vector3(x / l, y / l, z / l);
149 }
150 }
151
152 void Print() const { printf("v(%f,%f,%f)\n", x, y, z); }
153
154 /* Rotate this vector about point o, in axis defined by v. */
155 void ArbRotateAroundPoint(const vector3 &o, const vector3 &__v, T ang)
156 {
157 vector3 t;
158 T a = o.x;
159 T b = o.y;
160 T c = o.z;
161 T u = __v.x;
162 T v = __v.y;
163 T w = __v.z;
164 T cos_a = cos(ang);
165 T sin_a = sin(ang);
166 T inv_poo = 1.0f / (u * u + v * v + w * w);
167 t.x = a * (v * v + w * w) + u * (-b * v - c * w + u * x + v * y + w * z) + (-a * (v * v + w * w) + u * (b * v + c * w - v * y - w * z) + (v * v + w * w) * x) * cos_a +
168 sqrtf(u * u + v * v + w * w) * (-c * v + b * w - w * y + v * z) * sin_a;
169 t.x *= inv_poo;
170 t.y = b * (u * u + w * w) + v * (-a * u - c * w + u * x + v * y + w * z) + (-b * (u * u + w * w) + v * (a * u + c * w - u * x - w * z) + (u * u + w * w) * y) * cos_a +
171 sqrtf(u * u + v * v + w * w) * (-c * u - a * w + w * x - u * z) * sin_a;
172 t.y *= inv_poo;
173 t.z = c * (u * u + v * v) + w * (-a * u + b * v + u * x + v * y + w * z) + (-c * (u * u + v * v) + w * (a * u + b * v - u * x - v * y) + (u * u + v * v) * z) * cos_a +
174 sqrtf(u * u + v * v + w * w) * (-b * u + a * v - v * x + u * y) * sin_a;
175 t.z *= inv_poo;
176 *this = t;
177 }
178
179 /* Rotate this vector about origin, in axis defined by v. */
180 void ArbRotate(const vector3 &__v, T ang)
181 {
182 vector3 t;
183 T u = __v.x;
184 T v = __v.y;
185 T w = __v.z;
186 T cos_a = cos(ang);
187 T sin_a = sin(ang);
188 T inv_poo = 1.0f / (u * u + v * v + w * w);
189 t.x = u * (u * x + v * y + w * z) + (u * (-v * y - w * z) + (v * v + w * w) * x) * cos_a +
190 sqrtf(u * u + v * v + w * w) * (-w * y + v * z) * sin_a;
191 t.x *= inv_poo;
192 t.y = v * (u * x + v * y + w * z) + (v * (-u * x - w * z) + (u * u + w * w) * y) * cos_a +
193 sqrtf(u * u + v * v + w * w) * (w * x - u * z) * sin_a;
194 t.y *= inv_poo;
195 t.z = w * (u * x + v * y + w * z) + (w * (-u * x - v * y) + (u * u + v * v) * z) * cos_a +
196 sqrtf(u * u + v * v + w * w) * (-v * x + u * y) * sin_a;
197 t.z *= inv_poo;
198 *this = t;
199 }
200
201 void xy(const vector2<T> &v2)
202 {
203 x = v2.x;
204 y = v2.y;
205 }
206 void xz(const vector2<T> &v2)
207 {
208 x = v2.x;
209 z = v2.y;
210 }
211 void yz(const vector2<T> &v2)
212 {
213 y = v2.x;
214 z = v2.y;
215 }
216
217 vector2<T> xy() { return vector2<T>(x, y); }
218 vector2<T> xz() { return vector2<T>(x, z); }
219 vector2<T> yz() { return vector2<T>(y, z); }
220 vector2<T> yx() { return vector2<T>(y, x); }
221 vector2<T> zx() { return vector2<T>(z, x); }
222};
223
224// These are here in this manner to enforce that only float and double versions are possible.
225template <>
226inline vector3<float>::vector3(const vector2f &v, float t) :
227 x(v.x),
228 y(v.y),
229 z(t)
230{
231}
232template <>
234 x(float(v.x)),
235 y(float(v.y)),
236 z(float(v.z))
237{
238}
239template <>
241 x(v.x),
242 y(v.y),
243 z(v.z)
244{
245}
246template <>
247inline vector3<double>::vector3(const vector2f &v, double t) :
248 x(v.x),
249 y(v.y),
250 z(t)
251{
252}
253template <>
254inline vector3<float>::vector3(float val) :
255 x(val),
256 y(val),
257 z(val)
258{
259}
260template <>
261inline vector3<double>::vector3(double val) :
262 x(val),
263 y(val),
264 z(val)
265{
266}
267template <>
268inline vector3<float>::vector3(float _x, float _y, float _z) :
269 x(_x),
270 y(_y),
271 z(_z)
272{
273}
274template <>
275inline vector3<double>::vector3(double _x, double _y, double _z) :
276 x(_x),
277 y(_y),
278 z(_z)
279{
280}
281template <>
282inline vector3<float>::vector3(const float vals[3]) :
283 x(vals[0]),
284 y(vals[1]),
285 z(vals[2])
286{
287}
288template <>
289inline vector3<float>::vector3(const double vals[3]) :
290 x(float(vals[0])),
291 y(float(vals[1])),
292 z(float(vals[2]))
293{
294}
295template <>
296inline vector3<double>::vector3(const float vals[3]) :
297 x(vals[0]),
298 y(vals[1]),
299 z(vals[2])
300{
301}
302template <>
303inline vector3<double>::vector3(const double vals[3]) :
304 x(vals[0]),
305 y(vals[1]),
306 z(vals[2])
307{
308}
309
310// max() overload for use with C++ ADL
311template <typename T>
312vector3<T> max(const vector3<T> &lhs, const vector3<T> &rhs)
313{
314 using std::max; // support max(T) overloads
315 return vector3<T>(max(lhs.x, rhs.x), max(lhs.y, rhs.y), max(lhs.z, rhs.z));
316}
317
318// min() overload for use with C++ ADL
319template <typename T>
320vector3<T> min(const vector3<T> &lhs, const vector3<T> &rhs)
321{
322 using std::min; // support min(T) overloads
323 return vector3<T>(min(lhs.x, rhs.x), min(lhs.y, rhs.y), min(lhs.z, rhs.z));
324}
325
326#pragma pack()
327
330
331// ensure both packing and structure alignment match the constraints we have set
332static_assert(alignof(vector3d) == 8);
333static_assert(offsetof(vector3d, y) == 8);
334static_assert(offsetof(vector3d, z) == 16);
335
336static_assert(alignof(vector3f) == 4);
337static_assert(offsetof(vector3f, y) == 4);
338static_assert(offsetof(vector3f, z) == 8);
339
340#endif /* _VECTOR3_H */
bool is_equal_exact(float a, float b)
Definition: FloatComparison.h:112
double val
Definition: PrecalcPath.cpp:40
T y
Definition: vector2.h:26
T x
Definition: vector2.h:26
Definition: vector3.h:16
T Dot(const vector3 &b) const
Definition: vector3.h:129
vector2< T > xy()
Definition: vector3.h:217
T & operator[](const size_t i)
Definition: vector3.h:35
vector3 operator-(const vector3 &a) const
Definition: vector3.h:82
vector2< T > xz()
Definition: vector3.h:218
vector3 & operator/=(const double a)
Definition: vector3.h:74
T y
Definition: vector3.h:20
vector3 & operator/=(const float a)
Definition: vector3.h:66
void xy(const vector2< T > &v2)
Definition: vector3.h:201
auto operator>=(const vector3 &b) const
Definition: vector3.h:126
vector3(T _x, T _y, T _z)
void ArbRotateAroundPoint(const vector3 &o, const vector3 &__v, T ang)
Definition: vector3.h:155
void Print() const
Definition: vector3.h:152
vector3 & operator*=(const float a)
Definition: vector3.h:52
friend vector3 operator/(const vector3 &a, const float scalar)
Definition: vector3.h:104
const T & operator[](const size_t i) const
Definition: vector3.h:34
T LengthSqr() const
Definition: vector3.h:131
vector3 Lerp(const vector3 &b, const double percent) const
Definition: vector3.h:132
vector3 & operator+=(const vector3 &a)
Definition: vector3.h:38
T x
Definition: vector3.h:20
friend vector3 operator*(const vector3 &a, const T scalar)
Definition: vector3.h:100
vector2< T > yx()
Definition: vector3.h:220
vector3 NormalizedSafe() const
Definition: vector3.h:141
friend vector3 operator*(const vector3 &a, const vector3 &b)
Definition: vector3.h:99
T element_type
Definition: vector3.h:18
friend vector3 operator/(const vector3 &a, const double scalar)
Definition: vector3.h:109
vector3()=default
void xz(const vector2< T > &v2)
Definition: vector3.h:206
vector3(const T vals[3])
vector3(T val)
T Length() const
Definition: vector3.h:130
friend vector3 operator-(const T scalar, const vector3 &a)
Definition: vector3.h:97
vector2< T > zx()
Definition: vector3.h:221
auto operator<=(const vector3 &b) const
Definition: vector3.h:122
T z
Definition: vector3.h:20
friend vector3 operator*(const T scalar, const vector3 &a)
Definition: vector3.h:102
void ArbRotate(const vector3 &__v, T ang)
Definition: vector3.h:180
friend vector3 operator/(const T scalar, const vector3 &a)
Definition: vector3.h:114
auto operator<(const vector3 &b) const
Definition: vector3.h:120
vector3 & operator-=(const vector3 &a)
Definition: vector3.h:45
vector3 operator-() const
Definition: vector3.h:83
void yz(const vector2< T > &v2)
Definition: vector3.h:211
auto operator>(const vector3 &b) const
Definition: vector3.h:124
friend vector3 operator+(const vector3 &a, const T &scalar)
Definition: vector3.h:94
bool ExactlyEqual(const vector3 &a) const
Definition: vector3.h:89
vector2< T > yz()
Definition: vector3.h:219
bool operator==(const vector3 &a) const
Definition: vector3.h:85
vector3 Normalized() const
Definition: vector3.h:136
friend vector3 operator+(const T scalar, const vector3 &a)
Definition: vector3.h:95
vector3 & operator*=(const double a)
Definition: vector3.h:59
vector3(const vector3< typename other_floating_type< T >::type > &v)
friend vector3 operator-(const vector3 &a, const T &scalar)
Definition: vector3.h:96
vector3 Cross(const vector3 &b) const
Definition: vector3.h:128
vector3 operator+(const vector3 &a) const
Definition: vector3.h:37
vector3(const typename other_floating_type< T >::type vals[3])
vector3(const vector2f &v, T t)
Definition: vector2.h:13
vector3< float > vector3f
Definition: vector3.h:328
vector3< T > max(const vector3< T > &lhs, const vector3< T > &rhs)
Definition: vector3.h:312
vector3< double > vector3d
Definition: vector3.h:329
vector3< T > min(const vector3< T > &lhs, const vector3< T > &rhs)
Definition: vector3.h:320