Cuberite
A lightweight, fast and extensible game server for Minecraft
Vector3.h
Go to the documentation of this file.
1 
2 #pragma once
3 
4 
5 
6 
7 
8 template <typename T>
9 // tolua_begin
10 class Vector3
11 {
12 
13  TOLUA_TEMPLATE_BIND((T, int, float, double))
14 
15 public:
16 
17  T x, y, z;
18 
19 
20  constexpr Vector3(void) : x(0), y(0), z(0) {}
21  constexpr Vector3(T a_x, T a_y, T a_z) : x(a_x), y(a_y), z(a_z) {}
22 
23 
24  #ifdef TOLUA_EXPOSITION // Hardcoded copy constructors (tolua++ does not support function templates .. yet)
25  Vector3(const Vector3<float> & a_Rhs);
26  Vector3(const Vector3<double> & a_Rhs);
27  Vector3(const Vector3<int> & a_Rhs);
28  #endif
29 
30 
31  // tolua_end
32  // Conversion constructors where U is not the same as T leaving the copy-constructor implicitly generated
33  template <typename U, typename = typename std::enable_if<!std::is_same<U, T>::value>::type>
34  constexpr Vector3(const Vector3<U> & a_Rhs):
35  x(static_cast<T>(a_Rhs.x)),
36  y(static_cast<T>(a_Rhs.y)),
37  z(static_cast<T>(a_Rhs.z))
38  {
39  }
40  // tolua_begin
41 
42  inline void Set(T a_x, T a_y, T a_z)
43  {
44  x = a_x;
45  y = a_y;
46  z = a_z;
47  }
48 
49  inline void Normalize(void)
50  {
51  double Len = 1.0 / Length();
52 
53  x = static_cast<T>(x * Len);
54  y = static_cast<T>(y * Len);
55  z = static_cast<T>(z * Len);
56  }
57 
58  inline Vector3<T> NormalizeCopy(void) const
59  {
60  double Len = 1.0 / Length();
61 
62  return Vector3<T>(
63  static_cast<T>(x * Len),
64  static_cast<T>(y * Len),
65  static_cast<T>(z * Len)
66  );
67  }
68 
69  // tolua_end
70 
73  inline void NormalizeCopy(Vector3<T> & a_Rhs) const
74  {
75  double Len = 1.0 / Length();
76 
77  a_Rhs.Set(
78  static_cast<T>(x * Len),
79  static_cast<T>(y * Len),
80  static_cast<T>(z * Len)
81  );
82  }
83 
84  // tolua_begin
85 
86  inline bool HasNonZeroLength(void) const
87  {
88  #ifdef __clang__
89  #pragma clang diagnostic push
90  #pragma clang diagnostic ignored "-Wfloat-equal"
91  #endif
92 
93  return ((x != 0) || (y != 0) || (z != 0));
94 
95  #ifdef __clang__
96  #pragma clang diagnostic pop
97  #endif
98  }
99 
100  inline double Length(void) const
101  {
102  return sqrt(static_cast<double>(x * x + y * y + z * z));
103  }
104 
105  inline double SqrLength(void) const
106  {
107  return x * x + y * y + z * z;
108  }
109 
110  inline T Dot(const Vector3<T> & a_Rhs) const
111  {
112  return x * a_Rhs.x + y * a_Rhs.y + z * a_Rhs.z;
113  }
114 
116  inline void Abs()
117  {
118  x = std::abs(x);
119  y = std::abs(y);
120  z = std::abs(z);
121  }
122 
124  inline void Clamp(T a_Min, T a_Max)
125  {
126  x = ::Clamp(x, a_Min, a_Max);
127  y = ::Clamp(y, a_Min, a_Max);
128  z = ::Clamp(z, a_Min, a_Max);
129  }
130 
131  inline Vector3<T> Cross(const Vector3<T> & a_Rhs) const
132  {
133  return Vector3<T>(
134  y * a_Rhs.z - z * a_Rhs.y,
135  z * a_Rhs.x - x * a_Rhs.z,
136  x * a_Rhs.y - y * a_Rhs.x
137  );
138  }
139 
140  inline bool Equals(const Vector3<T> & a_Rhs) const
141  {
142  // Perform a strict comparison of the contents - we want to know whether this object is exactly equal
143  // To perform EPS-based comparison, use the EqualsEps() function
144 
145  #ifdef __clang__
146  #pragma clang diagnostic push
147  #pragma clang diagnostic ignored "-Wfloat-equal"
148  #endif
149 
150  return !((x != a_Rhs.x) || (y != a_Rhs.y) || (z != a_Rhs.z));
151 
152  #ifdef __clang__
153  #pragma clang diagnostic pop
154  #endif
155  }
156 
157  inline bool EqualsEps(const Vector3<T> & a_Rhs, T a_Eps) const
158  {
159  return (std::abs(x - a_Rhs.x) < a_Eps) && (std::abs(y - a_Rhs.y) < a_Eps) && (std::abs(z - a_Rhs.z) < a_Eps);
160  }
161 
162  inline void Move(T a_X, T a_Y, T a_Z)
163  {
164  x += a_X;
165  y += a_Y;
166  z += a_Z;
167  }
168 
169  inline void Move(const Vector3<T> & a_Diff)
170  {
171  x += a_Diff.x;
172  y += a_Diff.y;
173  z += a_Diff.z;
174  }
175 
177  inline Vector3<int> Floor(void) const
178  {
179  return Vector3<int>(
180  FloorC(x),
181  FloorC(y),
182  FloorC(z)
183  );
184  }
185 
187  inline Vector3<int> Ceil() const
188  {
189  return Vector3<int>(
190  CeilC(x),
191  CeilC(y),
192  CeilC(z)
193  );
194  }
195 
196  // tolua_end
197 
198  inline bool operator != (const Vector3<T> & a_Rhs) const
199  {
200  return !Equals(a_Rhs);
201  }
202 
203  inline bool operator == (const Vector3<T> & a_Rhs) const
204  {
205  return Equals(a_Rhs);
206  }
207 
208  inline bool operator > (const Vector3<T> & a_Rhs) const
209  {
210  return (SqrLength() > a_Rhs.SqrLength());
211  }
212 
213  inline bool operator < (const Vector3<T> & a_Rhs) const
214  {
215  return (SqrLength() < a_Rhs.SqrLength());
216  }
217 
218  inline void operator += (const Vector3<T> & a_Rhs)
219  {
220  x += a_Rhs.x;
221  y += a_Rhs.y;
222  z += a_Rhs.z;
223  }
224 
225  inline void operator -= (const Vector3<T> & a_Rhs)
226  {
227  x -= a_Rhs.x;
228  y -= a_Rhs.y;
229  z -= a_Rhs.z;
230  }
231 
232  inline void operator *= (const Vector3<T> & a_Rhs)
233  {
234  x *= a_Rhs.x;
235  y *= a_Rhs.y;
236  z *= a_Rhs.z;
237  }
238 
239  inline void operator *= (T a_v)
240  {
241  x *= a_v;
242  y *= a_v;
243  z *= a_v;
244  }
245 
246  // tolua_begin
247 
248  inline Vector3<T> operator + (const Vector3<T>& a_Rhs) const
249  {
250  return Vector3<T>(
251  x + a_Rhs.x,
252  y + a_Rhs.y,
253  z + a_Rhs.z
254  );
255  }
256 
257  inline Vector3<T> operator - (const Vector3<T>& a_Rhs) const
258  {
259  return Vector3<T>(
260  x - a_Rhs.x,
261  y - a_Rhs.y,
262  z - a_Rhs.z
263  );
264  }
265 
266  inline Vector3<T> operator - (void) const
267  {
268  return Vector3<T>(-x, -y, -z);
269  }
270 
271  inline Vector3<T> operator * (const Vector3<T>& a_Rhs) const
272  {
273  return Vector3<T>(
274  x * a_Rhs.x,
275  y * a_Rhs.y,
276  z * a_Rhs.z
277  );
278  }
279 
280  inline Vector3<T> operator / (const Vector3<T> & a_Rhs)
281  {
282  return Vector3<T>(
283  x / a_Rhs.x,
284  y / a_Rhs.y,
285  z / a_Rhs.z
286  );
287  }
288 
289  inline Vector3<T> operator * (T a_v) const
290  {
291  return Vector3<T>(
292  x * a_v,
293  y * a_v,
294  z * a_v
295  );
296  }
297 
298  inline Vector3<T> operator / (T a_v) const
299  {
300  return Vector3<T>(
301  x / a_v,
302  y / a_v,
303  z / a_v
304  );
305  }
306 
308  inline Vector3<T> addedX(T a_AddX) const
309  {
310  return Vector3<T>(x + a_AddX, y, z);
311  }
312 
314  inline Vector3<T> addedY(T a_AddY) const
315  {
316  return Vector3<T>(x, y + a_AddY, z);
317  }
318 
320  inline Vector3<T> addedZ(T a_AddZ) const
321  {
322  return Vector3<T>(x, y, z + a_AddZ);
323  }
324 
326  inline Vector3<T> addedXZ(T a_AddX, T a_AddZ) const
327  {
328  return Vector3<T>(x + a_AddX, y, z + a_AddZ);
329  }
330 
336  inline double LineCoeffToXYPlane(const Vector3<T> & a_OtherEnd, T a_Z) const
337  {
338  if (std::abs(z - a_OtherEnd.z) < EPS)
339  {
340  return NO_INTERSECTION;
341  }
342 
343  return (a_Z - z) / (a_OtherEnd.z - z);
344  }
345 
351  inline double LineCoeffToXZPlane(const Vector3<T> & a_OtherEnd, T a_Y) const
352  {
353  if (std::abs(y - a_OtherEnd.y) < EPS)
354  {
355  return NO_INTERSECTION;
356  }
357 
358  return (a_Y - y) / (a_OtherEnd.y - y);
359  }
360 
366  inline double LineCoeffToYZPlane(const Vector3<T> & a_OtherEnd, T a_X) const
367  {
368  if (std::abs(x - a_OtherEnd.x) < EPS)
369  {
370  return NO_INTERSECTION;
371  }
372 
373  return (a_X - x) / (a_OtherEnd.x - x);
374  }
375 
378  inline void TurnCW(void)
379  {
380  std::swap(x, z);
381  x = -x;
382  }
383 
386  inline void TurnCCW(void)
387  {
388  std::swap(x, z);
389  z = -z;
390  }
391 
393  static const double EPS;
394 
396  static const double NO_INTERSECTION;
397 };
398 // tolua_end
399 
400 
401 
402 
403 
406 template <typename What>
407 class fmt::formatter<Vector3<What>> : public fmt::formatter<What>
408 {
409  using Super = fmt::formatter<What>;
410 
411  template <typename FormatContext, size_t Len>
412  void Write(FormatContext & a_Ctx, const char (& a_Str)[Len])
413  {
414  const auto Itr = std::copy_n(&a_Str[0], Len - 1, a_Ctx.out());
415  a_Ctx.advance_to(Itr);
416  }
417 
418  template <typename FormatContext>
419  void Write(FormatContext & a_Ctx, const What & a_Arg)
420  {
421  const auto Itr = Super::format(a_Arg, a_Ctx);
422  a_Ctx.advance_to(Itr);
423  }
424 
425 public:
426 
427  template <typename FormatContext>
428  auto format(const Vector3<What> & a_Vec, FormatContext & a_Ctx)
429  {
430  Write(a_Ctx, "{");
431  Write(a_Ctx, a_Vec.x);
432  Write(a_Ctx, ", ");
433  Write(a_Ctx, a_Vec.y);
434  Write(a_Ctx, ", ");
435  Write(a_Ctx, a_Vec.z);
436  Write(a_Ctx, "}");
437  return a_Ctx.out();
438  }
439 };
440 
441 
442 
443 
444 
445 template <> inline Vector3<int> Vector3<int>::Floor(void) const
446 {
447  return *this;
448 }
449 
450 
451 
452 
453 
454 template <typename What>
456 {
457 public:
459  size_t operator()(const Vector3<What> & a_Vector) const
460  {
461  // Guaranteed to have non repeating hashes for any 128x128x128 area
462  size_t Hash = static_cast<size_t>(a_Vector.y);
463  Hash <<= 16;
464  Hash ^= static_cast<size_t>(a_Vector.x);
465  Hash ^= static_cast<size_t>(a_Vector.z) << 8;
466  return Hash;
467  }
468 };
469 
470 
471 
472 
473 
474 template <typename T>
475 const double Vector3<T>::EPS = 0.000001;
476 
477 template <typename T>
478 const double Vector3<T>::NO_INTERSECTION = 1e70;
479 
480 
481 
482 
483 
484 // tolua_begin
488 // tolua_end
489 
490 
491 
492 
493 
494 typedef std::vector<Vector3i> cVector3iArray;
FloorC
std::enable_if< std::is_arithmetic< T >::value, C >::type FloorC(T a_Value)
Floors a value, then casts it to C (an int by default).
Definition: Globals.h:344
Vector3::operator==
bool operator==(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:203
Vector3::EqualsEps
bool EqualsEps(const Vector3< T > &a_Rhs, T a_Eps) const
Definition: Vector3.h:157
Vector3::NormalizeCopy
void NormalizeCopy(Vector3< T > &a_Rhs) const
Sets the given vector to the normalized version of this vector.
Definition: Vector3.h:73
Vector3::HasNonZeroLength
bool HasNonZeroLength(void) const
Definition: Vector3.h:86
Vector3::operator+=
void operator+=(const Vector3< T > &a_Rhs)
Definition: Vector3.h:218
Vector3::x
T x
Definition: Vector3.h:17
Vector3i
Vector3< int > Vector3i
Definition: Vector3.h:487
Vector3::Normalize
void Normalize(void)
Definition: Vector3.h:49
Vector3::Dot
T Dot(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:110
Vector3::operator<
bool operator<(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:213
Vector3::NormalizeCopy
Vector3< T > NormalizeCopy(void) const
Definition: Vector3.h:58
Vector3::Abs
void Abs()
Updates each coord to its absolute value.
Definition: Vector3.h:116
fmt::formatter< Vector3< What > >::Write
void Write(FormatContext &a_Ctx, const What &a_Arg)
Definition: Vector3.h:419
Vector3f
Vector3< float > Vector3f
Definition: Vector3.h:486
Vector3::operator-
Vector3< T > operator-(void) const
Definition: Vector3.h:266
Vector3::operator/
Vector3< T > operator/(const Vector3< T > &a_Rhs)
Definition: Vector3.h:280
Vector3::Move
void Move(T a_X, T a_Y, T a_Z)
Definition: Vector3.h:162
Vector3::Cross
Vector3< T > Cross(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:131
Vector3::Vector3
constexpr Vector3(const Vector3< U > &a_Rhs)
Definition: Vector3.h:34
Vector3::LineCoeffToXYPlane
double LineCoeffToXYPlane(const Vector3< T > &a_OtherEnd, T a_Z) const
Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Z coord.
Definition: Vector3.h:336
Vector3::TurnCW
void TurnCW(void)
Rotates the vector 90 degrees clockwise around the vertical axis.
Definition: Vector3.h:378
Vector3::operator*
Vector3< T > operator*(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:271
Vector3::addedXZ
Vector3< T > addedXZ(T a_AddX, T a_AddZ) const
Returns a copy of this vector moved by the specified amount on the X and Z axes.
Definition: Vector3.h:326
Vector3::Vector3
constexpr Vector3(T a_x, T a_y, T a_z)
Definition: Vector3.h:21
Vector3::z
T z
Definition: Vector3.h:17
Vector3::EPS
static const double EPS
The max difference between two coords for which the coords are assumed equal.
Definition: Vector3.h:393
Vector3::Set
void Set(T a_x, T a_y, T a_z)
Definition: Vector3.h:42
Vector3::Length
double Length(void) const
Definition: Vector3.h:100
Vector3::SqrLength
double SqrLength(void) const
Definition: Vector3.h:105
Vector3::operator+
Vector3< T > operator+(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:248
Vector3::Move
void Move(const Vector3< T > &a_Diff)
Definition: Vector3.h:169
Vector3::NO_INTERSECTION
static const double NO_INTERSECTION
Return value of LineCoeffToPlane() if the line is parallel to the plane.
Definition: Vector3.h:396
Vector3::Ceil
Vector3< int > Ceil() const
Returns a new Vector3i with coords set to std::ceil() of this vector's coords.
Definition: Vector3.h:187
VectorHasher::operator()
size_t operator()(const Vector3< What > &a_Vector) const
Provides a hash of a vector's contents.
Definition: Vector3.h:459
Vector3::operator-=
void operator-=(const Vector3< T > &a_Rhs)
Definition: Vector3.h:225
fmt::formatter< Vector3< What > >::Write
void Write(FormatContext &a_Ctx, const char(&a_Str)[Len])
Definition: Vector3.h:412
CeilC
std::enable_if< std::is_arithmetic< T >::value, C >::type CeilC(T a_Value)
Ceils a value, then casts it to C (an int by default).
Definition: Globals.h:351
Vector3::Clamp
void Clamp(T a_Min, T a_Max)
Clamps each coord into the specified range.
Definition: Vector3.h:124
Vector3d
Vector3< double > Vector3d
Definition: Vector3.h:485
Vector3::LineCoeffToYZPlane
double LineCoeffToYZPlane(const Vector3< T > &a_OtherEnd, T a_X) const
Returns the coefficient for the (a_OtherEnd - this) line to reach the specified X coord.
Definition: Vector3.h:366
Vector3::TurnCCW
void TurnCCW(void)
Rotates the vector 90 degrees counterclockwise around the vertical axis.
Definition: Vector3.h:386
VectorHasher
Definition: Vector3.h:455
fmt::formatter< Vector3< What > >::format
auto format(const Vector3< What > &a_Vec, FormatContext &a_Ctx)
Definition: Vector3.h:428
Vector3::addedX
Vector3< T > addedX(T a_AddX) const
Returns a copy of this vector moved by the specified amount on the X axis.
Definition: Vector3.h:308
Vector3::addedZ
Vector3< T > addedZ(T a_AddZ) const
Returns a copy of this vector moved by the specified amount on the Z axis.
Definition: Vector3.h:320
Vector3::Vector3
constexpr Vector3(void)
Definition: Vector3.h:20
Vector3::Floor
Vector3< int > Floor(void) const
Returns a new Vector3i with coords set to std::floor() of this vector's coords.
Definition: Vector3.h:177
Vector3::operator*=
void operator*=(const Vector3< T > &a_Rhs)
Definition: Vector3.h:232
Vector3::operator>
bool operator>(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:208
Vector3::addedY
Vector3< T > addedY(T a_AddY) const
Returns a copy of this vector moved by the specified amount on the y axis.
Definition: Vector3.h:314
Vector3::y
T y
Definition: Vector3.h:17
Vector3::LineCoeffToXZPlane
double LineCoeffToXZPlane(const Vector3< T > &a_OtherEnd, T a_Y) const
Returns the coefficient for the (a_OtherEnd - this) line to reach the specified Y coord.
Definition: Vector3.h:351
fmt::formatter< Vector3< What > >::Super
fmt::formatter< What > Super
Definition: Vector3.h:409
Vector3::Equals
bool Equals(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:140
cVector3iArray
std::vector< Vector3i > cVector3iArray
Definition: Vector3.h:494
Vector3
Definition: Vector3.h:10
Vector3::operator!=
bool operator!=(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:198
GZipFile::Write
void Write(const std::string &a_FileName, ContiguousByteBufferView a_Contents)
Writes a_Contents into file, compressing it along the way.
Definition: GZipFile.cpp:27
TOLUA_TEMPLATE_BIND
#define TOLUA_TEMPLATE_BIND(x)
Definition: Globals.h:376