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  inline Vector3(void) : x(0), y(0), z(0) {}
21  inline 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  Vector3(const Vector3<U> & a_Rhs): x(static_cast<T>(a_Rhs.x)), y(static_cast<T>(a_Rhs.y)), z(static_cast<T>(a_Rhs.z)) {}
35  // tolua_begin
36 
37  inline void Set(T a_x, T a_y, T a_z)
38  {
39  x = a_x;
40  y = a_y;
41  z = a_z;
42  }
43 
44  inline void Normalize(void)
45  {
46  double Len = 1.0 / Length();
47 
48  x = static_cast<T>(x * Len);
49  y = static_cast<T>(y * Len);
50  z = static_cast<T>(z * Len);
51  }
52 
53  inline Vector3<T> NormalizeCopy(void) const
54  {
55  double Len = 1.0 / Length();
56 
57  return Vector3<T>(
58  static_cast<T>(x * Len),
59  static_cast<T>(y * Len),
60  static_cast<T>(z * Len)
61  );
62  }
63 
64  // tolua_end
65 
68  inline void NormalizeCopy(Vector3<T> & a_Rhs) const
69  {
70  double Len = 1.0 / Length();
71 
72  a_Rhs.Set(
73  static_cast<T>(x * Len),
74  static_cast<T>(y * Len),
75  static_cast<T>(z * Len)
76  );
77  }
78 
79  // tolua_begin
80 
81  inline bool HasNonZeroLength(void) const
82  {
83  #ifdef __clang__
84  #pragma clang diagnostic push
85  #pragma clang diagnostic ignored "-Wfloat-equal"
86  #endif
87 
88  return ((x != 0) || (y != 0) || (z != 0));
89 
90  #ifdef __clang__
91  #pragma clang diagnostic pop
92  #endif
93  }
94 
95  inline double Length(void) const
96  {
97  return sqrt(static_cast<double>(x * x + y * y + z * z));
98  }
99 
100  inline double SqrLength(void) const
101  {
102  return x * x + y * y + z * z;
103  }
104 
105  inline T Dot(const Vector3<T> & a_Rhs) const
106  {
107  return x * a_Rhs.x + y * a_Rhs.y + z * a_Rhs.z;
108  }
109 
111  inline void Abs()
112  {
113  x = std::abs(x);
114  y = std::abs(y);
115  z = std::abs(z);
116  }
117 
119  inline void Clamp(T a_Min, T a_Max)
120  {
121  x = ::Clamp(x, a_Min, a_Max);
122  y = ::Clamp(y, a_Min, a_Max);
123  z = ::Clamp(z, a_Min, a_Max);
124  }
125 
126  inline Vector3<T> Cross(const Vector3<T> & a_Rhs) const
127  {
128  return Vector3<T>(
129  y * a_Rhs.z - z * a_Rhs.y,
130  z * a_Rhs.x - x * a_Rhs.z,
131  x * a_Rhs.y - y * a_Rhs.x
132  );
133  }
134 
135  inline bool Equals(const Vector3<T> & a_Rhs) const
136  {
137  // Perform a strict comparison of the contents - we want to know whether this object is exactly equal
138  // To perform EPS-based comparison, use the EqualsEps() function
139 
140  #ifdef __clang__
141  #pragma clang diagnostic push
142  #pragma clang diagnostic ignored "-Wfloat-equal"
143  #endif
144 
145  return !((x != a_Rhs.x) || (y != a_Rhs.y) || (z != a_Rhs.z));
146 
147  #ifdef __clang__
148  #pragma clang diagnostic pop
149  #endif
150  }
151 
152  inline bool EqualsEps(const Vector3<T> & a_Rhs, T a_Eps) const
153  {
154  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);
155  }
156 
157  inline void Move(T a_X, T a_Y, T a_Z)
158  {
159  x += a_X;
160  y += a_Y;
161  z += a_Z;
162  }
163 
164  inline void Move(const Vector3<T> & a_Diff)
165  {
166  x += a_Diff.x;
167  y += a_Diff.y;
168  z += a_Diff.z;
169  }
170 
172  inline Vector3<int> Floor(void) const
173  {
174  return Vector3<int>(
175  FloorC(x),
176  FloorC(y),
177  FloorC(z)
178  );
179  }
180 
181  // tolua_end
182 
183  inline bool operator != (const Vector3<T> & a_Rhs) const
184  {
185  return !Equals(a_Rhs);
186  }
187 
188  inline bool operator == (const Vector3<T> & a_Rhs) const
189  {
190  return Equals(a_Rhs);
191  }
192 
193  inline bool operator > (const Vector3<T> & a_Rhs) const
194  {
195  return (SqrLength() > a_Rhs.SqrLength());
196  }
197 
198  inline bool operator < (const Vector3<T> & a_Rhs) const
199  {
200  return (SqrLength() < a_Rhs.SqrLength());
201  }
202 
203  inline void operator += (const Vector3<T> & a_Rhs)
204  {
205  x += a_Rhs.x;
206  y += a_Rhs.y;
207  z += a_Rhs.z;
208  }
209 
210  inline void operator -= (const Vector3<T> & a_Rhs)
211  {
212  x -= a_Rhs.x;
213  y -= a_Rhs.y;
214  z -= a_Rhs.z;
215  }
216 
217  inline void operator *= (const Vector3<T> & a_Rhs)
218  {
219  x *= a_Rhs.x;
220  y *= a_Rhs.y;
221  z *= a_Rhs.z;
222  }
223 
224  inline void operator *= (T a_v)
225  {
226  x *= a_v;
227  y *= a_v;
228  z *= a_v;
229  }
230 
231  // tolua_begin
232 
233  inline Vector3<T> operator + (const Vector3<T>& a_Rhs) const
234  {
235  return Vector3<T>(
236  x + a_Rhs.x,
237  y + a_Rhs.y,
238  z + a_Rhs.z
239  );
240  }
241 
242  inline Vector3<T> operator - (const Vector3<T>& a_Rhs) const
243  {
244  return Vector3<T>(
245  x - a_Rhs.x,
246  y - a_Rhs.y,
247  z - a_Rhs.z
248  );
249  }
250 
251  inline Vector3<T> operator - (void) const
252  {
253  return Vector3<T>(-x, -y, -z);
254  }
255 
256  inline Vector3<T> operator * (const Vector3<T>& a_Rhs) const
257  {
258  return Vector3<T>(
259  x * a_Rhs.x,
260  y * a_Rhs.y,
261  z * a_Rhs.z
262  );
263  }
264 
265  inline Vector3<T> operator / (const Vector3<T> & a_Rhs)
266  {
267  return Vector3<T>(
268  x / a_Rhs.x,
269  y / a_Rhs.y,
270  z / a_Rhs.z
271  );
272  }
273 
274  inline Vector3<T> operator * (T a_v) const
275  {
276  return Vector3<T>(
277  x * a_v,
278  y * a_v,
279  z * a_v
280  );
281  }
282 
283  inline Vector3<T> operator / (T a_v) const
284  {
285  return Vector3<T>(
286  x / a_v,
287  y / a_v,
288  z / a_v
289  );
290  }
291 
293  inline Vector3<T> addedX(T a_AddX) const
294  {
295  return Vector3<T>(x + a_AddX, y, z);
296  }
297 
299  inline Vector3<T> addedY(T a_AddY) const
300  {
301  return Vector3<T>(x, y + a_AddY, z);
302  }
303 
305  inline Vector3<T> addedZ(T a_AddZ) const
306  {
307  return Vector3<T>(x, y, z + a_AddZ);
308  }
309 
311  inline Vector3<T> addedXZ(T a_AddX, T a_AddZ) const
312  {
313  return Vector3<T>(x + a_AddX, y, z + a_AddZ);
314  }
315 
321  inline double LineCoeffToXYPlane(const Vector3<T> & a_OtherEnd, T a_Z) const
322  {
323  if (std::abs(z - a_OtherEnd.z) < EPS)
324  {
325  return NO_INTERSECTION;
326  }
327 
328  return (a_Z - z) / (a_OtherEnd.z - z);
329  }
330 
336  inline double LineCoeffToXZPlane(const Vector3<T> & a_OtherEnd, T a_Y) const
337  {
338  if (std::abs(y - a_OtherEnd.y) < EPS)
339  {
340  return NO_INTERSECTION;
341  }
342 
343  return (a_Y - y) / (a_OtherEnd.y - y);
344  }
345 
351  inline double LineCoeffToYZPlane(const Vector3<T> & a_OtherEnd, T a_X) const
352  {
353  if (std::abs(x - a_OtherEnd.x) < EPS)
354  {
355  return NO_INTERSECTION;
356  }
357 
358  return (a_X - x) / (a_OtherEnd.x - x);
359  }
360 
363  inline void TurnCW(void)
364  {
365  std::swap(x, z);
366  x = -x;
367  }
368 
371  inline void TurnCCW(void)
372  {
373  std::swap(x, z);
374  z = -z;
375  }
376 
377  // tolua_end
378 
381  template <typename ArgFormatter>
382  friend void format_arg(fmt::BasicFormatter<char, ArgFormatter> & a_Formatter, const char *& a_FormatStr, Vector3 a_Vec)
383  {
384  std::array<T, 3> Data{{a_Vec.x, a_Vec.y, a_Vec.z}};
385 
386  a_Formatter.writer() << '{';
387  fmt::format_arg(a_Formatter, a_FormatStr, fmt::join(Data.cbegin(), Data.cend(), ", "));
388  a_Formatter.writer() << '}';
389  }
390 
391  // tolua_begin
392 
394  static const double EPS;
395 
397  static const double NO_INTERSECTION;
398 };
399 // tolua_end
400 
401 
402 
403 
404 
405 template <> inline Vector3<int> Vector3<int>::Floor(void) const
406 {
407  return *this;
408 }
409 
410 
411 
412 
413 
414 template <typename What>
416 {
417 public:
419  size_t operator()(const Vector3<What> & a_Vector) const
420  {
421  // Guaranteed to have non repeating hashes for any 128x128x128 area
422  size_t Hash = static_cast<size_t>(a_Vector.y);
423  Hash <<= 16;
424  Hash ^= static_cast<size_t>(a_Vector.x);
425  Hash ^= static_cast<size_t>(a_Vector.z) << 8;
426  return Hash;
427  }
428 };
429 
430 
431 
432 
433 
434 template <typename T>
435 const double Vector3<T>::EPS = 0.000001;
436 
437 template <typename T>
438 const double Vector3<T>::NO_INTERSECTION = 1e70;
439 
440 
441 
442 
443 
444 // tolua_begin
448 // tolua_end
449 
450 
451 
452 
453 
454 typedef std::vector<Vector3i> cVector3iArray;
455 
456 
457 
458 
459 
460 
Vector3< T > operator+(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:233
bool operator>(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:193
T x
Definition: Vector3.h:17
Vector3< int > Floor(void) const
Returns a new Vector3i with coords set to std::floor() of this vector&#39;s coords.
Definition: Vector3.h:172
T Dot(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:105
Vector3(T a_x, T a_y, T a_z)
Definition: Vector3.h:21
bool Equals(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:135
#define TOLUA_TEMPLATE_BIND(x)
Definition: Globals.h:392
void TurnCCW(void)
Rotates the vector 90 degrees counterclockwise around the vertical axis.
Definition: Vector3.h:371
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:311
Vector3(void)
Definition: Vector3.h:20
Vector3< float > Vector3f
Definition: Vector3.h:446
Vector3(const Vector3< U > &a_Rhs)
Definition: Vector3.h:34
void operator+=(const Vector3< T > &a_Rhs)
Definition: Vector3.h:203
void Move(T a_X, T a_Y, T a_Z)
Definition: Vector3.h:157
bool HasNonZeroLength(void) const
Definition: Vector3.h:81
void Set(T a_x, T a_y, T a_z)
Definition: Vector3.h:37
void Move(const Vector3< T > &a_Diff)
Definition: Vector3.h:164
std::vector< Vector3i > cVector3iArray
Definition: Vector3.h:454
T y
Definition: Vector3.h:17
T z
Definition: Vector3.h:17
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:299
static const double NO_INTERSECTION
Return value of LineCoeffToPlane() if the line is parallel to the plane.
Definition: Vector3.h:397
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:293
Vector3< T > operator*(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:256
void Clamp(T a_Min, T a_Max)
Clamps each coord into the specified range.
Definition: Vector3.h:119
bool operator!=(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:183
void Normalize(void)
Definition: Vector3.h:44
Vector3< T > operator/(const Vector3< T > &a_Rhs)
Definition: Vector3.h:265
double Length(void) const
Definition: Vector3.h:95
Vector3< double > Vector3d
Definition: Vector3.h:445
bool operator==(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:188
Vector3< T > Cross(const Vector3< T > &a_Rhs) const
Definition: Vector3.h:126
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:305
void operator-=(const Vector3< T > &a_Rhs)
Definition: Vector3.h:210
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:351
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:336
double SqrLength(void) const
Definition: Vector3.h:100
void operator*=(const Vector3< T > &a_Rhs)
Definition: Vector3.h:217
static const double EPS
The max difference between two coords for which the coords are assumed equal.
Definition: Vector3.h:394
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:321
void NormalizeCopy(Vector3< T > &a_Rhs) const
Sets the given vector to the normalized version of this vector.
Definition: Vector3.h:68
Vector3< int > Vector3i
Definition: Vector3.h:447
size_t operator()(const Vector3< What > &a_Vector) const
Provides a hash of a vector&#39;s contents.
Definition: Vector3.h:419
Vector3< T > NormalizeCopy(void) const
Definition: Vector3.h:53
void TurnCW(void)
Rotates the vector 90 degrees clockwise around the vertical axis.
Definition: Vector3.h:363
friend void format_arg(fmt::BasicFormatter< char, ArgFormatter > &a_Formatter, const char *&a_FormatStr, Vector3 a_Vec)
Allows formatting a Vector<T> using the same format specifiers as for T e.g.
Definition: Vector3.h:382
void Abs()
Updates each coord to its absolute value.
Definition: Vector3.h:111
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:362
Vector3< T > operator-(void) const
Definition: Vector3.h:251
bool EqualsEps(const Vector3< T > &a_Rhs, T a_Eps) const
Definition: Vector3.h:152