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