LkEngine 0.1.2
 
Loading...
Searching...
No Matches
Vector2.h
1#pragma once
2
3#include <type_traits>
4#include <ostream>
5
6#include <glm/glm.hpp>
7#include <imgui/imgui.h>
8
10
11namespace LkEngine {
12
19 template<typename SizeType>
20 struct TVector2;
21
22 namespace Math::Internal::Vector2Impl
23 {
27 template<typename SizeType, typename VectorTypeA, typename VectorTypeB>
28 struct Dot
29 {
30 static SizeType Calculate(const VectorTypeA& A, const VectorTypeB& B)
31 {
32 static_assert((sizeof(VectorTypeA) > 0) && (sizeof(VectorTypeB) > 0), "Unsupported vector type");
33 return SizeType();
34 }
35 };
36
37 template<typename SizeType>
38 struct Dot<SizeType, TVector2<SizeType>, TVector2<SizeType>>
39 {
40 static SizeType Calculate(const TVector2<SizeType>& A, const TVector2<SizeType>& B)
41 {
42 return (A.X * B.X) + (A.Y * B.Y);
43 }
44 };
45
46 template<typename SizeType>
47 struct Dot<SizeType, TVector2<SizeType>, glm::vec3>
48 {
49 static SizeType Calculate(const TVector2<SizeType>& A, const glm::vec3& B)
50 {
51 return (A.X * B.x) + (A.Y * B.y);
52 }
53 };
54
55 template<typename SizeType>
56 struct Dot<SizeType, glm::vec3, TVector2<SizeType>>
57 {
58 static SizeType Calculate(const glm::vec3& A, const TVector2<SizeType>& B)
59 {
60 return (A.x * B.X) + (A.y * B.Y);
61 }
62 };
63
64
68 template<typename SizeType, typename VectorTypeA, typename VectorTypeB, typename ReturnType>
69 struct Min
70 {
71 static ReturnType Calculate(const VectorTypeA& A, const VectorTypeB& B)
72 {
73 static_assert((sizeof(VectorTypeA) > 0) && (sizeof(VectorTypeB) > 0), "Unsupported vector type");
74 return SizeType();
75 }
76 };
77
83 template<typename SizeType>
84 struct Min<SizeType, TVector2<SizeType>, TVector2<SizeType>, SizeType>
85 {
86 static SizeType Calculate(const TVector2<SizeType>& A, const TVector2<SizeType>& B)
87 {
88 return std::min({
89 A.X, A.Y,
90 B.X, B.Y
91 });
92 }
93 };
94
100 template<typename SizeType>
101 struct Min<SizeType, TVector2<SizeType>, glm::vec3, SizeType>
102 {
103 static SizeType Calculate(const TVector2<SizeType>& A, const glm::vec3& B)
104 {
105 return std::min({
106 A.X, A.Y,
107 B.x, B.y
108 });
109 }
110 };
111
112
116 template<typename SizeType, typename VectorTypeA, typename VectorTypeB, typename ReturnType>
117 struct Max
118 {
119 static ReturnType Calculate(const VectorTypeA& A, const VectorTypeB& B)
120 {
121 static_assert((sizeof(VectorTypeA) > 0) && (sizeof(VectorTypeB) > 0), "Unsupported vector type");
122 return SizeType();
123 }
124 };
125
131 template<typename SizeType>
132 struct Max<SizeType, TVector2<SizeType>, TVector2<SizeType>, SizeType>
133 {
134 static SizeType Calculate(const TVector2<SizeType>& A, const TVector2<SizeType>& B)
135 {
136 return std::max({
137 A.X, A.Y,
138 B.X, B.Y
139 });
140 }
141 };
142
148 template<typename SizeType>
149 struct Max<SizeType, TVector2<SizeType>, glm::vec3, SizeType>
150 {
151 static SizeType Calculate(const TVector2<SizeType>& A, const glm::vec3& B)
152 {
153 return std::max({
154 A.X, A.Y, A.Z,
155 B.x, B.y, B.z
156 });
157 }
158 };
159
163 template<typename SizeType, typename VectorType, typename ReturnType, bool DivisionByZeroGuard>
164 struct Inverse
165 {
166 static ReturnType Calculate(const VectorType& Vector)
167 {
168 static_assert((sizeof(VectorType) > 0), "Unsupported vector type");
169 return ReturnType();
170 }
171 };
172
180 template<typename SizeType>
181 struct Inverse<SizeType, TVector2<SizeType>, TVector2<SizeType>, true>
182 {
183 static TVector2<SizeType> Calculate(const TVector2<SizeType>& Vector)
184 {
185 return TVector2<SizeType>(
186 (Vector.X != static_cast<SizeType>(0)) ? (static_cast<SizeType>(1) / Vector.X) : static_cast<SizeType>(0),
187 (Vector.Y != static_cast<SizeType>(0)) ? (static_cast<SizeType>(1) / Vector.Y) : static_cast<SizeType>(0)
188 );
189 }
190 };
191
199 template<typename SizeType>
200 struct Inverse<SizeType, TVector2<SizeType>, TVector2<SizeType>, false>
201 {
202 static TVector2<SizeType> Calculate(const TVector2<SizeType>& Vector)
203 {
204 return TVector2<SizeType>(
205 (static_cast<SizeType>(1) / Vector.X),
206 (static_cast<SizeType>(1) / Vector.Y)
207 );
208 }
209 };
210 }
211
216 template<typename SizeType>
217 struct TVector2
218 {
219 public:
220 TVector2()
221 : X(SizeType())
222 , Y(SizeType())
223 {
224 }
225
226 TVector2(const SizeType InX, const SizeType InY)
227 : X(InX)
228 , Y(InY)
229 {
230 }
231
232 template<typename OtherType, typename = std::enable_if_t<std::is_convertible_v<OtherType, SizeType>>>
233 TVector2(const OtherType InX, const OtherType InY)
234 : X(static_cast<SizeType>(InX))
235 , Y(static_cast<SizeType>(InY))
236 {
237 }
238
239 template<typename OtherType, typename = std::enable_if_t<std::is_convertible_v<OtherType, SizeType>>>
240 TVector2(const TVector2<OtherType>& Other)
241 : X(static_cast<SizeType>(Other.X))
242 , Y(static_cast<SizeType>(Other.Y))
243 {
244 }
245
246 TVector2(const glm::vec2& InVec)
247 : X(InVec.x)
248 , Y(InVec.y)
249 {
250 }
251
252 TVector2(const ImVec2& InVec)
253 : X(InVec.x)
254 , Y(InVec.y)
255 {
256 }
257
258 TVector2& operator=(const TVector2& Other)
259 {
260 if (this != &Other)
261 {
262 X = Other.X;
263 Y = Other.Y;
264 }
265 return *this;
266 }
267
268 TVector2& operator+=(const TVector2& Other)
269 {
270 X += Other.X;
271 Y += Other.Y;
272 return *this;
273 }
274
275 TVector2& operator-=(const TVector2& Other)
276 {
277 X -= Other.X;
278 Y -= Other.Y;
279 return *this;
280 }
281
282 TVector2 operator-(const TVector2& Other) const
283 {
284 return TVector2((X - Other.X), (Y - Other.Y));
285 }
286
287 template<typename OtherType>
288 TVector2 operator-(const TVector2<OtherType>& Other) const
289 {
290 static_assert(std::is_convertible_v<OtherType, SizeType>, "Narrowing conversion");
291 return TVector2((X - static_cast<SizeType>(Other.X)), (Y - static_cast<SizeType>(Other.Y)));
292 }
293
294 TVector2 operator+(const TVector2& Other) const
295 {
296 return TVector2((X + Other.X), (Y + Other.Y));
297 }
298
299 template<typename OtherType>
300 TVector2 operator+(const TVector2<OtherType>& Other) const
301 {
302 static_assert(std::is_convertible_v<OtherType, SizeType>, "Narrowing conversion");
303 return TVector2((X + static_cast<SizeType>(Other.X)), (Y + static_cast<SizeType>(Other.Y)));
304 }
305
306 template<typename OtherType>
307 TVector2& operator=(const TVector2<OtherType> Other)
308 {
309 static_assert(std::is_convertible_v<OtherType, SizeType>, "Narrowing conversion");
310 X = static_cast<SizeType>(Other.X);
311 Y = static_cast<SizeType>(Other.Y);
312 return *this;
313 }
314
315 bool operator==(const TVector2& Other) const
316 {
317 return ((X == Other.X) && (Y == Other.Y));
318 }
319
320 bool operator!=(const TVector2& Other) const
321 {
322 return !(*this == Other);
323 }
324
325 template<typename OtherType>
326 bool operator==(const TVector2<OtherType>& Other) const
327 {
328 return ((X == static_cast<SizeType>(Other.X)) && (Y == static_cast<SizeType>(Other.Y)));
329 }
330
331 FORCEINLINE bool IsNull() const
332 {
333 return ((X == 0) && (Y == 0));
334 }
335
336 static float Distance(const TVector2& A, const TVector2& B)
337 {
338 return 0.0f;
339 }
340
341 template<typename VectorTypeA, typename VectorTypeB>
342 static SizeType Min(const VectorTypeA& A, const VectorTypeB& B)
343 {
344 using ReturnType = SizeType;
346 }
347
348 template<typename VectorTypeA, typename VectorTypeB>
349 static SizeType Max(const VectorTypeA& A, const VectorTypeB& B)
350 {
351 using ReturnType = SizeType;
353 }
354
355 template<typename VectorType>
356 static VectorType Inverse(const VectorType& Vector)
357 {
359 }
360
361 template<typename VectorType>
362 static VectorType InverseSafe(const VectorType& Vector)
363 {
365 }
366
367 template<typename StringType = std::string>
368 FORCEINLINE StringType ToString() const
369 {
370 if constexpr (std::is_same_v<StringType, std::string>)
371 {
372 if constexpr (std::is_floating_point_v<SizeType>)
373 {
374 return LK_FMT_LIB::format("({:.2f}, {:.2f})", X, Y);
375 }
376 else
377 {
378 return LK_FMT_LIB::format("({}, {})", X, Y);
379 }
380 }
381 /* TODO: This does not work as it should, should be removed. */
382 else if constexpr (std::is_same_v<StringType, const char*>)
383 {
384 static constexpr uint16_t BufSize = 256;
385 if constexpr (std::is_floating_point_v<SizeType>)
386 {
387 static std::array<char, BufSize> Buffer;
388 std::snprintf(Buffer.data(), Buffer.size(), "(%.2f, %.2f)", X, Y);
389 return Buffer.data();
390 }
391 else
392 {
393 static std::array<char, BufSize> Buffer;
394 std::snprintf(Buffer.data(), Buffer.size(), "(%d, %d)", X, Y);
395 return Buffer.data();
396 }
397 }
398 }
399
400 friend std::ostream& operator<<(std::ostream& os, const TVector2& Vector)
401 {
402 os << Vector.ToString();
403 return os;
404 }
405
406 template<typename VectorType>
407 VectorType As() const
408 {
409 if constexpr (std::is_same_v<VectorType, glm::vec2>)
410 {
411 return glm::vec2(X, Y);
412 }
413 else if constexpr (std::is_same_v<VectorType, ImVec2>)
414 {
415 return ImVec2(X, Y);
416 }
417 else
418 {
419 static_assert(!std::is_same_v<VectorType, VectorType>, "Unsupported VectorType in TVector2::As()");
420 }
421
422 return VectorType();
423 }
424
425 operator glm::vec2() { return glm::vec2(X, Y); }
426 operator ImVec2() { return ImVec2(X, Y); }
427
428 static_assert(std::disjunction_v<
429 std::is_same<SizeType, int>,
430 std::is_same<SizeType, uint16_t>,
431 std::is_same<SizeType, uint32_t>,
432 std::is_same<SizeType, uint64_t>,
433 std::is_same<SizeType, int16_t>,
434 std::is_same<SizeType, int32_t>,
435 std::is_same<SizeType, int64_t>,
436 std::is_same<SizeType, float>,
437 std::is_same<SizeType, double>
438 >, "TVector2 can only be instantiated with int, float or double types");
439
440 public:
441 #if LK_VECTOR_ANONYMOUS_STRUCT
442 union
443 {
444 struct { SizeType X, Y; };
445 struct { SizeType R, G; };
446 struct { SizeType S, T; };
447 };
448 #else
449 union { SizeType X, R, S; };
450 union { SizeType Y, G, T; };
451 #endif
452 };
453
456}
Core macros used by the entire engine.
Definition Asset.h:11
Templated two-component vector.
Definition Vector2.h:218