1 //------------------------------------------------------------------------------
2 //  Copyright (c) 2018-2020 Michele Morrone
3 //  All rights reserved.
4 //
5 //  https://michelemorrone.eu - https://BrutPitt.com
6 //
7 //  twitter: https://twitter.com/BrutPitt - github: https://github.com/BrutPitt
8 //
9 //  mailto:brutpitt@gmail.com - mailto:me@michelemorrone.eu
10 //
11 //  This software is distributed under the terms of the BSD 2-Clause license
12 //------------------------------------------------------------------------------
13 #pragma once
14 
15 #include "vgConfig.h"
16 
17 #ifdef VGM_USES_DOUBLE_PRECISION
18     #define VG_T_TYPE double
19     #define VGM_USES_TEMPLATE
20 #else
21     #define VG_T_TYPE float
22 #endif
23 
24 #ifdef VGIZMO_USES_GLM
25     #ifndef VGM_USES_TEMPLATE
26         #define VGM_USES_TEMPLATE    // glm uses template ==> vGizmo needs to know
27     #endif
28 
29     #define VGM_NAMESPACE glm
30 
31     #include <glm/glm.hpp>
32     #include <glm/gtx/vector_angle.hpp>
33     #include <glm/gtx/exterior_product.hpp>
34     #include <glm/gtc/type_ptr.hpp>
35     #include <glm/gtc/quaternion.hpp>
36     #include <glm/gtc/matrix_transform.hpp>
37 
38     using tVec2 = glm::tvec2<VG_T_TYPE>;
39     using tVec3 = glm::tvec3<VG_T_TYPE>;
40     using tVec4 = glm::tvec4<VG_T_TYPE>;
41     using tQuat = glm::tquat<VG_T_TYPE>;
42     using tMat3 = glm::tmat3x3<VG_T_TYPE>;
43     using tMat4 = glm::tmat4x4<VG_T_TYPE>;
44 
45     #define T_PI glm::pi<VG_T_TYPE>()
46     #define T_INV_PI glm::one_over_pi<VG_T_TYPE>()
47 
48     #define VGIZMO_BASE_CLASS virtualGizmoBaseClass<T>
49     #define TEMPLATE_TYPENAME_T  template<typename T>
50 
51 #else // use vGizmoMath
52 
53     #include <math.h>
54     #include <cmath>
55     #include <stdint.h>
56     #define VGM_NAMESPACE vgm
57 
58     #ifdef VGM_USES_TEMPLATE
59         #define TEMPLATE_TYPENAME_T  template<typename T>
60 
61         #define VEC2_T Vec2<T>
62         #define VEC3_T Vec3<T>
63         #define VEC4_T Vec4<T>
64         #define QUAT_T Quat<T>
65         #define MAT3_T Mat3<T>
66         #define MAT4_T Mat4<T>
67 
68         #define VEC2_PRECISION Vec2<VG_T_TYPE>
69         #define VEC3_PRECISION Vec3<VG_T_TYPE>
70         #define VEC4_PRECISION Vec4<VG_T_TYPE>
71         #define QUAT_PRECISION Quat<VG_T_TYPE>
72         #define MAT3_PRECISION Mat3<VG_T_TYPE>
73         #define MAT4_PRECISION Mat4<VG_T_TYPE>
74 
75         #define T_PI vgm::pi<VG_T_TYPE>()
76         #define T_INV_PI vgm::one_over_pi<VG_T_TYPE>()
77 
78     #else
79         #define TEMPLATE_TYPENAME_T
80 
81         #define VEC2_T Vec2
82         #define VEC3_T Vec3
83         #define VEC4_T Vec4
84         #define QUAT_T Quat
85         #define MAT3_T Mat3
86         #define MAT4_T Mat4
87 
88         #define VEC2_PRECISION Vec2
89         #define VEC3_PRECISION Vec3
90         #define VEC4_PRECISION Vec4
91         #define QUAT_PRECISION Quat
92         #define MAT3_PRECISION Mat3
93         #define MAT4_PRECISION Mat4
94 
95         #define T_PI vgm::pi()
96         #define T_INV_PI vgm::one_over_pi()
97     #endif
98 
99 namespace vgm {
100 
101 TEMPLATE_TYPENAME_T class Vec3;
102 TEMPLATE_TYPENAME_T class Vec4;
103 TEMPLATE_TYPENAME_T class Mat4;
104 
105 #if !defined(VGM_USES_TEMPLATE)
106     #define T VG_T_TYPE
107 #endif
108 
109 // Vec2
110 //////////////////////////
111 TEMPLATE_TYPENAME_T class Vec2 {
112 public:
113     union {
114         struct { T x, y; };
115         struct { T u, v; };
116     };
117 
118     Vec2()              = default;
119     Vec2(const VEC2_T&) = default;
Vec2(T s)120     explicit Vec2(T s)  : x(s), y(s) {}
Vec2(T x,T y)121     Vec2(T x, T y)      : x(x), y(y) {}
122     Vec2(const VEC3_T&);
123 
124     Vec2 operator-() const { return {-x, -y}; }
125 
126     Vec2& operator+=(const Vec2& v) { x += v.x; y += v.y; return *this; }
127     Vec2& operator-=(const Vec2& v) { x -= v.x; y -= v.y; return *this; }
128     Vec2& operator*=(const Vec2& v) { x *= v.x; y *= v.y; return *this; }
129     Vec2& operator/=(const Vec2& v) { x /= v.x; y /= v.y; return *this; }
130     Vec2& operator*=(T s)           { x *= s  ; y *= s  ; return *this; }
131     Vec2& operator/=(T s)           { x /= s  ; y /= s  ; return *this; }
132 
133     Vec2 operator+(const Vec2& v) const { return { x + v.x, y + v.y }; }
134     Vec2 operator-(const Vec2& v) const { return { x - v.x, y - v.y }; }
135     Vec2 operator*(const Vec2& v) const { return { x * v.x, y * v.y }; }
136     Vec2 operator/(const Vec2& v) const { return { x / v.x, y / v.y }; }
137     Vec2 operator*(T s)           const { return { x * s  , y * s   }; }
138     Vec2 operator/(T s)           const { return { x / s  , y / s   }; }
139 
140     const T& operator[](int i) const { return *(&x + i); }
141           T& operator[](int i)       { return *(&x + i); }
142 
143     explicit operator const T *() const { return &x; }
144     explicit operator       T *()       { return &x; }
145 };
146 // Vec3
147 //////////////////////////
148 TEMPLATE_TYPENAME_T class Vec3 {
149 public:
150     union {
151         struct { T x, y, z; };
152         struct { T r, g, b; };
153     };
154 
155     Vec3()                              = default;
156     Vec3(const VEC3_T&)                 = default;
Vec3(T s)157     explicit Vec3(T s)                  : x(s), y(s), z(s)      {}
Vec3(T x,T y,T z)158     Vec3(T x, T y, T z)                 : x(x), y(y), z(z)      {}
Vec3(T s,const VEC2_T & v)159     explicit Vec3(T s, const VEC2_T& v) : x(s), y(v.x), z(v.y)  {}
Vec3(const VEC2_T & v,T s)160     explicit Vec3(const VEC2_T& v, T s) : x(v.x), y(v.y), z(s)  {}
161     Vec3(const VEC4_T& v);
162 
163     Vec3 operator-() const { return {-x, -y, -z}; }
164 
165     Vec3& operator+=(const Vec3& v) { x += v.x; y += v.y; z += v.z; return *this; }
166     Vec3& operator-=(const Vec3& v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
167     Vec3& operator*=(const Vec3& v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
168     Vec3& operator/=(const Vec3& v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
169     Vec3& operator*=(T s)           { x *= s  ; y *= s  ; z *= s  ; return *this; }
170     Vec3& operator/=(T s)           { x /= s  ; y /= s  ; z /= s  ; return *this; }
171 
172     Vec3 operator+(const Vec3& v) const { return { x + v.x, y + v.y, z + v.z }; }
173     Vec3 operator-(const Vec3& v) const { return { x - v.x, y - v.y, z - v.z }; }
174     Vec3 operator*(const Vec3& v) const { return { x * v.x, y * v.y, z * v.z }; }
175     Vec3 operator/(const Vec3& v) const { return { x / v.x, y / v.y, z / v.z }; }
176     Vec3 operator*(T s)           const { return { x * s  , y * s  , z * s   }; }
177     Vec3 operator/(T s)           const { return { x / s  , y / s  , z / s   }; }
178 
179     const T& operator[](int i) const { return *(&x + i); }
180           T& operator[](int i)       { return *(&x + i); }
181 
182     explicit operator const T *() const { return &x; }
183     explicit operator       T *()       { return &x; }
184 };
185 // Vec4
186 //////////////////////////
187 TEMPLATE_TYPENAME_T class Vec4 {
188 public:
189     union {
190         struct { T x, y, z, w; };
191         struct { T r, g, b, a; };
192     };
193 
194     Vec4()                              = default;
195     Vec4(const VEC4_T&)                 = default;
Vec4(T s)196     explicit Vec4(T s)                  : x(s),   y(s),   z(s),   w(s)   {}
Vec4(T x,T y,T z,T w)197     Vec4(T x, T y, T z, T w)            : x(x),   y(y),   z(z),   w(w)   {}
Vec4(const VEC3_T & v,T s)198     explicit Vec4(const VEC3_T& v, T s) : x(v.x), y(v.y), z(v.z), w(s)   {}
Vec4(T s,const VEC3_T & v)199     explicit Vec4(T s, const VEC3_T& v) : x(s),   y(v.x), z(v.y), w(v.z) {}
200 
201     //operator VEC3_T() const { return *((VEC3_T *) &x); }
202     Vec4 operator-() const { return {-x, -y, -z, -w}; }
203 
204     Vec4& operator+=(const Vec4& v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
205     Vec4& operator-=(const Vec4& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }
206     Vec4& operator*=(const Vec4& v) { x *= v.x; y *= v.y; z *= v.z; w *= v.w; return *this; }
207     Vec4& operator/=(const Vec4& v) { x /= v.x; y /= v.y; z /= v.z; w /= v.w; return *this; }
208     Vec4& operator*=(T s)           { x *= s  ; y *= s  ; z *= s  ; w *= s  ; return *this; }
209     Vec4& operator/=(T s)           { x /= s  ; y /= s  ; z /= s  ; w /= s  ; return *this; }
210 
211     Vec4 operator+(const Vec4& v) const { return { x + v.x, y + v.y, z + v.z, w + v.w }; }
212     Vec4 operator-(const Vec4& v) const { return { x - v.x, y - v.y, z - v.z, w - v.w }; }
213     Vec4 operator*(const Vec4& v) const { return { x * v.x, y * v.y, z * v.z, w * v.w }; }
214     Vec4 operator/(const Vec4& v) const { return { x / v.x, y / v.y, z / v.z, w / v.w }; }
215     Vec4 operator*(T s)           const { return { x * s  , y * s  , z * s  , w * s   }; }
216     Vec4 operator/(T s)           const { return { x / s  , y / s  , z / s  , w / s   }; }
217 
218     const T& operator[](int i) const { return *(&x + i); }
219           T& operator[](int i)       { return *(&x + i); }
220 
221     explicit operator const T *() const { return &x; }
222     explicit operator       T *()       { return &x; }
223 };
224 // Quat
225 //////////////////////////
226 TEMPLATE_TYPENAME_T class Quat {
227 public:
228     T x, y, z, w;
229 
230     Quat()                              = default;
231     Quat(const QUAT_T&)                 = default;
Quat(T w,T x,T y,T z)232     Quat(T w, T x, T y, T z)            : x(x),   y(y),   z(z),   w(w)   {}
Quat(T s,const VEC3_T & v)233     explicit Quat(T s, const VEC3_T& v) : x(v.x), y(v.y), z(v.z), w(s)   {}
234 
235     Quat operator-() const { return Quat(-w, -x, -y, -z); }
236 
237     Quat& operator+=(const Quat& q)  { x += q.x; y += q.y; z += q.z; w += q.w; return *this; }
238     Quat& operator-=(const Quat& q)  { x -= q.x; y -= q.y; z -= q.z; w -= q.w; return *this; }
239     Quat& operator*=(const Quat& q)  { return *this = *this * q; }
240     Quat& operator*=(T s)            { x *= s  ; y *= s  ; z *= s  ; w *= s  ; return *this; }
241     Quat& operator/=(T s)            { x /= s  ; y /= s  ; z /= s  ; w /= s  ; return *this; }
242 
243     Quat operator+(const Quat& q) const { return { w + q.w, x + q.x, y + q.y, z + q.z }; }
244     Quat operator-(const Quat& q) const { return { w - q.w, x - q.x, y - q.y, z - q.z }; }
245     Quat operator*(const Quat& q) const { return { w * q.w - x * q.x - y * q.y - z * q.z,
246                                                    w * q.x + x * q.w + y * q.z - z * q.y,
247                                                    w * q.y + y * q.w + z * q.x - x * q.z,
248                                                    w * q.z + z * q.w + x * q.y - y * q.x }; }
249 
250     Quat operator*(T s) const { return { w * s, x * s  , y * s  , z * s }; }
251     Quat operator/(T s) const { return { w / s, x / s  , y / s  , z / s }; }
252 
253     const T& operator[](int i) const { return *(&x + i); }
254           T& operator[](int i)       { return *(&x + i); }
255 
256     explicit operator const T *() const { return &x; }
257     explicit operator       T *()       { return &x; }
258 };
259 // Mat3
260 //////////////////////////
261 TEMPLATE_TYPENAME_T class Mat3 {
262 public:
263     union {
264         VEC3_T v[3];
265         struct { T m00, m01, m02,
266                    m10, m11, m12,
267                    m20, m21, m22; };
268     };
269 
270     Mat3()                  = default;
271     Mat3(const MAT3_T &)    = default;
Mat3(T s)272     explicit Mat3(T s) : v { VEC3_T(s, 0, 0), VEC3_T(0, s, 0), VEC3_T(0, 0, s) } {}
Mat3(const VEC3_T & v0,const VEC3_T & v1,const VEC3_T & v2)273     Mat3(const VEC3_T& v0, const VEC3_T& v1, const VEC3_T& v2) : v {v0, v1, v2 } {}
274     Mat3(const MAT4_T& m);
Mat3(T v0x,T v0y,T v0z,T v1x,T v1y,T v1z,T v2x,T v2y,T v2z)275     Mat3(T v0x, T v0y, T v0z,
276          T v1x, T v1y, T v1z,
277          T v2x, T v2y, T v2z) : v { VEC3_T(v0x, v0y, v0z), VEC3_T(v1x, v1y, v1z), VEC3_T(v2x, v2y, v2z) } {}
278 
279     const VEC3_T& operator[](int i) const { return v[i]; }
280           VEC3_T& operator[](int i)       { return v[i]; }
281 
282     Mat3 operator-() const { return Mat3(-v[0], -v[1], -v[2]); }
283 
284     Mat3& operator+=(const Mat3& m) { v[0] += m.v[0]; v[1] += m.v[1]; v[2] += m.v[2]; return *this; }
285     Mat3& operator-=(const Mat3& m) { v[0] -= m.v[0]; v[1] -= m.v[1]; v[2] -= m.v[2]; return *this; }
286     Mat3& operator/=(const Mat3& m) { v[0] /= m.v[0]; v[1] /= m.v[1]; v[2] /= m.v[2]; return *this; }
287     Mat3& operator*=(T s)           { v[0] *= s;      v[1] *= s;      v[2] *= s;      return *this; }
288     Mat3& operator/=(T s)           { v[0] /= s;      v[1] /= s;      v[2] /= s;      return *this; }
289     Mat3& operator*=(const Mat3& m) { return *this = *this * m;  }
290 
291     Mat3 operator+(const Mat3& m) const { return { v[0] + m.v[0], v[1] + m.v[1], v[2] + m.v[2] }; }
292     Mat3 operator-(const Mat3& m) const { return { v[0] - m.v[0], v[1] - m.v[1], v[2] - m.v[2] }; }
293 #define M(X,Y) (m##X * m.m##Y)
294     Mat3 operator*(const Mat3& m) const { return { M(00,00) + M(10,01) + M(20,02),
295                                                    M(01,00) + M(11,01) + M(21,02),
296                                                    M(02,00) + M(12,01) + M(22,02),
297                                                    M(00,10) + M(10,11) + M(20,12),
298                                                    M(01,10) + M(11,11) + M(21,12),
299                                                    M(02,10) + M(12,11) + M(22,12),
300                                                    M(00,20) + M(10,21) + M(20,22),
301                                                    M(01,20) + M(11,21) + M(21,22),
302                                                    M(02,20) + M(12,21) + M(22,22)}; }
303 #undef M
304     Mat3 operator*(T s) const { return { v[0] * s, v[1] * s, v[2] * s }; }
305     Mat3 operator/(T s) const { return { v[0] / s, v[1] / s, v[2] / s }; }
306 
307     VEC3_T operator*(const VEC3_T& v) const { return { m00 * v.x + m10 * v.y + m20 * v.z,
308                                                        m01 * v.x + m11 * v.y + m21 * v.z,
309                                                        m02 * v.x + m12 * v.y + m22 * v.z }; }
310     explicit operator const T *() const { return &m00; }
311     explicit operator       T *()       { return &m00; }
312 };
313 // Mat4
314 //////////////////////////
315 TEMPLATE_TYPENAME_T class Mat4 {
316 public:
317     union {
318         VEC4_T v[4];
319         struct { T m00, m01, m02, m03,
320                    m10, m11, m12, m13,
321                    m20, m21, m22, m23,
322                    m30, m31, m32, m33; };
323     };
324 
325     Mat4() = default;
Mat4(T s)326     explicit Mat4(T s) : v { VEC4_T(s, 0, 0, 0), VEC4_T(0, s, 0, 0), VEC4_T(0, 0, s, 0), VEC4_T(0, 0, 0, s)} {}
Mat4(const VEC4_T & v0,const VEC4_T & v1,const VEC4_T & v2,const VEC4_T & v3)327     Mat4(const VEC4_T& v0, const VEC4_T& v1, const VEC4_T& v2, const VEC4_T& v3) : v {v0, v1, v2, v3} {}
Mat4(const MAT3_T & m)328     Mat4(const MAT3_T& m) : v {VEC4_T(m.v[0],0), VEC4_T(m.v[1],0), VEC4_T(m.v[2],0), VEC4_T(0, 0, 0, 1)}  {}
Mat4(T v0x,T v0y,T v0z,T v0w,T v1x,T v1y,T v1z,T v1w,T v2x,T v2y,T v2z,T v2w,T v3x,T v3y,T v3z,T v3w)329     Mat4(T v0x, T v0y, T v0z, T v0w,
330          T v1x, T v1y, T v1z, T v1w,
331          T v2x, T v2y, T v2z, T v2w,
332          T v3x, T v3y, T v3z, T v3w) : v {VEC4_T(v0x, v0y, v0z, v0w), VEC4_T(v1x, v1y, v1z, v1w), VEC4_T(v2x, v2y, v2z, v2w), VEC4_T(v3x, v3y, v3z, v3w) } {}
333 
334     const VEC4_T& operator[](int i) const { return v[i]; }
335           VEC4_T& operator[](int i)       { return v[i]; }
336 
337     Mat4 operator-() const { return { -v[0], -v[1], -v[2], -v[3] }; }
338 
339     Mat4& operator+=(const Mat4& m) { v[0] += m.v[0]; v[1] += m.v[1]; v[2] += m.v[2]; v[3] += m.v[3]; return *this; }
340     Mat4& operator-=(const Mat4& m) { v[0] -= m.v[0]; v[1] -= m.v[1]; v[2] -= m.v[2]; v[3] -= m.v[3]; return *this; }
341     Mat4& operator/=(const Mat4& m) { v[0] /= m.v[0]; v[1] /= m.v[1]; v[2] /= m.v[2]; v[3] /= m.v[3]; return *this; }
342     Mat4& operator*=(T s)           { v[0] *= s;      v[1] *= s;      v[2] *= s;      v[3] *= s;      return *this; }
343     Mat4& operator/=(T s)           { v[0] /= s;      v[1] /= s;      v[2] /= s;      v[3] /= s;      return *this; }
344     Mat4& operator*=(const Mat4& m) { return *this = *this * m; }
345 
346     Mat4 operator+(const Mat4& m) const { return { v[0] + m.v[0], v[1] + m.v[1], v[2] + m.v[2], v[3] + m.v[3] }; }
347     Mat4 operator-(const Mat4& m) const { return { v[0] - m.v[0], v[1] - m.v[1], v[2] - m.v[2], v[3] - m.v[3] }; }
348     Mat4 operator*(T s)           const { return { v[0] * s     , v[1] * s     , v[2] * s     , v[3] * s      }; }
349     Mat4 operator/(T s)           const { return { v[0] / s     , v[1] / s     , v[2] / s     , v[3] / s      }; }
350 #define M(X,Y) (m##X * m.m##Y)
351     Mat4 operator*(const Mat4& m) const { return { M(00,00) + M(10,01) + M(20,02) + M(30,03),
352                                                    M(01,00) + M(11,01) + M(21,02) + M(31,03),
353                                                    M(02,00) + M(12,01) + M(22,02) + M(32,03),
354                                                    M(03,00) + M(13,01) + M(23,02) + M(33,03),
355                                                    M(00,10) + M(10,11) + M(20,12) + M(30,13),
356                                                    M(01,10) + M(11,11) + M(21,12) + M(31,13),
357                                                    M(02,10) + M(12,11) + M(22,12) + M(32,13),
358                                                    M(03,10) + M(13,11) + M(23,12) + M(33,13),
359                                                    M(00,20) + M(10,21) + M(20,22) + M(30,23),
360                                                    M(01,20) + M(11,21) + M(21,22) + M(31,23),
361                                                    M(02,20) + M(12,21) + M(22,22) + M(32,23),
362                                                    M(03,20) + M(13,21) + M(23,22) + M(33,23),
363                                                    M(00,30) + M(10,31) + M(20,32) + M(30,33),
364                                                    M(01,30) + M(11,31) + M(21,32) + M(31,33),
365                                                    M(02,30) + M(12,31) + M(22,32) + M(32,33),
366                                                    M(03,30) + M(13,31) + M(23,32) + M(33,33) };  }
367 #undef M
368     VEC4_T operator*(const VEC4_T& v) const { return { m00 * v.x + m10 * v.y + m20 * v.z + m30 * v.w,
369                                                        m01 * v.x + m11 * v.y + m21 * v.z + m31 * v.w,
370                                                        m02 * v.x + m12 * v.y + m22 * v.z + m32 * v.w,
371                                                        m03 * v.x + m13 * v.y + m23 * v.z + m33 * v.w }; }
372     explicit operator const T *() const { return &m00; }
373     explicit operator       T *()       { return &m00; }
374 };
375 // cast / conversion
376 //////////////////////////
Vec2(const VEC3_T & v)377 TEMPLATE_TYPENAME_T inline VEC2_T::Vec2(const VEC3_T& v) : VEC2_T{ v.x, v.y } {}
Vec3(const VEC4_T & v)378 TEMPLATE_TYPENAME_T inline VEC3_T::Vec3(const VEC4_T& v) : VEC3_T{ v.x, v.y, v.z } {}
Mat3(const MAT4_T & m)379 TEMPLATE_TYPENAME_T inline MAT3_T::Mat3(const MAT4_T& m) : v { VEC3_T(m.v[0]), m.v[1], m.v[2] } {}
mat3_cast(QUAT_T const & q)380 TEMPLATE_TYPENAME_T inline MAT3_T mat3_cast(QUAT_T const& q) {
381     T xx(q.x * q.x); T yy(q.y * q.y); T zz(q.z * q.z);
382     T xz(q.x * q.z); T xy(q.x * q.y); T yz(q.y * q.z);
383     T wx(q.w * q.x); T wy(q.w * q.y); T wz(q.w * q.z);
384 
385     return { T(1) - T(2) * (yy + zz),         T(2) * (xy + wz),         T(2) * (xz - wy),
386                     T(2) * (xy - wz),  T(1) - T(2) * (xx + zz),         T(2) * (yz + wx),
387                     T(2) * (xz + wy),         T(2) * (yz - wx),  T(1) - T(2) * (xx + yy) }; }
mat4_cast(QUAT_T const & q)388 TEMPLATE_TYPENAME_T inline MAT4_T mat4_cast(QUAT_T const& q) { return { mat3_cast(q) }; }
uintBitsToFloat(uint32_t const v)389 inline float uintBitsToFloat(uint32_t const v) { return *((float *)(&v)); }
floatBitsToUint(float const v)390 inline uint32_t floatBitsToUint(float const v) { return *((uint32_t *)(&v)); }
391 // dot
392 //////////////////////////
dot(const VEC2_T & v0,const VEC2_T & v1)393 TEMPLATE_TYPENAME_T inline T dot(const VEC2_T& v0, const VEC2_T& v1) { return v0.x * v1.x + v0.y * v1.y; }
dot(const VEC3_T & v0,const VEC3_T & v1)394 TEMPLATE_TYPENAME_T inline T dot(const VEC3_T& v0, const VEC3_T& v1) { return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z; }
dot(const VEC4_T & v0,const VEC4_T & v1)395 TEMPLATE_TYPENAME_T inline T dot(const VEC4_T& v0, const VEC4_T& v1) { return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w; }
dot(const QUAT_T & q0,const QUAT_T & q1)396 TEMPLATE_TYPENAME_T inline T dot(const QUAT_T& q0, const QUAT_T& q1) { return q0.x * q1.x + q0.y * q1.y + q0.z * q1.z + q0.w * q1.w; }
397 // cross
398 //////////////////////////
cross(const VEC2_T & u,const VEC2_T & v)399 TEMPLATE_TYPENAME_T inline      T cross(const VEC2_T& u, const VEC2_T& v) { return u.x * v.y - v.x * u.y; }
cross(const VEC3_T & u,const VEC3_T & v)400 TEMPLATE_TYPENAME_T inline VEC3_T cross(const VEC3_T& u, const VEC3_T& v) { return { u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x }; }
401 // length
402 //////////////////////////
length(const VEC2_T & v)403 TEMPLATE_TYPENAME_T inline T length(const VEC2_T& v) { return sqrt(dot(v, v)); }
length(const VEC3_T & v)404 TEMPLATE_TYPENAME_T inline T length(const VEC3_T& v) { return sqrt(dot(v, v)); }
length(const VEC4_T & v)405 TEMPLATE_TYPENAME_T inline T length(const VEC4_T& v) { return sqrt(dot(v, v)); }
length(const QUAT_T & q)406 TEMPLATE_TYPENAME_T inline T length(const QUAT_T& q) { return sqrt(dot(q, q)); }
407 // distance
408 //////////////////////////
distance(const VEC2_T & v0,const VEC2_T & v1)409 TEMPLATE_TYPENAME_T inline T distance(const VEC2_T& v0, const VEC2_T& v1) { return length(v1 - v0); }
distance(const VEC3_T & v0,const VEC3_T & v1)410 TEMPLATE_TYPENAME_T inline T distance(const VEC3_T& v0, const VEC3_T& v1) { return length(v1 - v0); }
distance(const VEC4_T & v0,const VEC4_T & v1)411 TEMPLATE_TYPENAME_T inline T distance(const VEC4_T& v0, const VEC4_T& v1) { return length(v1 - v0); }
412 // abs
413 //////////////////////////
tAbs(T x)414 TEMPLATE_TYPENAME_T inline T tAbs(T x) { return x>=T(0) ? x : -x; }
abs(const VEC2_T & v)415 TEMPLATE_TYPENAME_T inline VEC2_T abs(const VEC2_T& v) { return { tAbs(v.x), tAbs(v.y) }; }
abs(const VEC3_T & v)416 TEMPLATE_TYPENAME_T inline VEC3_T abs(const VEC3_T& v) { return { tAbs(v.x), tAbs(v.y), tAbs(v.z) }; }
abs(const VEC4_T & v)417 TEMPLATE_TYPENAME_T inline VEC4_T abs(const VEC4_T& v) { return { tAbs(v.x), tAbs(v.y), tAbs(v.z), tAbs(v.w) }; }
abs(const QUAT_T & q)418 TEMPLATE_TYPENAME_T inline QUAT_T abs(const QUAT_T& q) { return { tAbs(q.w), tAbs(q.x), tAbs(q.y), tAbs(q.z) }; }
419 // sign
420 //////////////////////////
sign(const T v)421 TEMPLATE_TYPENAME_T inline T sign(const T v) { return v>T(0) ? T(1) : ( v<T(0) ? T(-1) : T(0)); }
422 // normalize
423 //////////////////////////
normalize(const VEC2_T & v)424 TEMPLATE_TYPENAME_T inline VEC2_T normalize(const VEC2_T& v) { return v / length(v); }
normalize(const VEC3_T & v)425 TEMPLATE_TYPENAME_T inline VEC3_T normalize(const VEC3_T& v) { return v / length(v); }
normalize(const VEC4_T & v)426 TEMPLATE_TYPENAME_T inline VEC4_T normalize(const VEC4_T& v) { return v / length(v); }
normalize(const QUAT_T & q)427 TEMPLATE_TYPENAME_T inline QUAT_T normalize(const QUAT_T& q) { return q / length(q); }
428 // mix
429 //////////////////////////
mix(const T x,const T y,const T a)430 TEMPLATE_TYPENAME_T inline      T mix(const      T  x, const      T  y, const T a)   { return x + (y-x) * a; }
mix(const VEC2_T & x,const VEC2_T & y,const T a)431 TEMPLATE_TYPENAME_T inline VEC2_T mix(const VEC2_T& x, const VEC2_T& y, const T a)   { return x + (y-x) * a; }
mix(const VEC3_T & x,const VEC3_T & y,const T a)432 TEMPLATE_TYPENAME_T inline VEC3_T mix(const VEC3_T& x, const VEC3_T& y, const T a)   { return x + (y-x) * a; }
mix(const VEC4_T & x,const VEC4_T & y,const T a)433 TEMPLATE_TYPENAME_T inline VEC4_T mix(const VEC4_T& x, const VEC4_T& y, const T a)   { return x + (y-x) * a; }
434 // pow
435 //////////////////////////
pow(const VEC2_T & b,const VEC2_T & e)436 TEMPLATE_TYPENAME_T inline VEC2_T pow(const VEC2_T& b, const VEC2_T& e) { return { ::pow(b.x,e.x), ::pow(b.y,e.y) }; }
pow(const VEC3_T & b,const VEC3_T & e)437 TEMPLATE_TYPENAME_T inline VEC3_T pow(const VEC3_T& b, const VEC3_T& e) { return { ::pow(b.x,e.x), ::pow(b.y,e.y), ::pow(b.z,e.z) }; }
pow(const VEC4_T & b,const VEC4_T & e)438 TEMPLATE_TYPENAME_T inline VEC4_T pow(const VEC4_T& b, const VEC4_T& e) { return { ::pow(b.x,e.x), ::pow(b.y,e.y), ::pow(b.z,e.z), ::pow(b.w,e.w) }; }
439 // value_ptr
440 //////////////////////////
value_ptr(const VEC2_T & v)441 TEMPLATE_TYPENAME_T inline T *value_ptr(const VEC2_T &v) { return const_cast<T *>(&v.x); }
value_ptr(const VEC3_T & v)442 TEMPLATE_TYPENAME_T inline T *value_ptr(const VEC3_T &v) { return const_cast<T *>(&v.x); }
value_ptr(const VEC4_T & v)443 TEMPLATE_TYPENAME_T inline T *value_ptr(const VEC4_T &v) { return const_cast<T *>(&v.x); }
value_ptr(const QUAT_T & q)444 TEMPLATE_TYPENAME_T inline T *value_ptr(const QUAT_T &q) { return const_cast<T *>(&q.x); }
value_ptr(const MAT3_T & m)445 TEMPLATE_TYPENAME_T inline T *value_ptr(const MAT3_T &m) { return const_cast<T *>(&m.m00); }
value_ptr(const MAT4_T & m)446 TEMPLATE_TYPENAME_T inline T *value_ptr(const MAT4_T &m) { return const_cast<T *>(&m.m00); }
447 // transpose
448 //////////////////////////
transpose(MAT3_T m)449 TEMPLATE_TYPENAME_T inline MAT3_T transpose(MAT3_T m) {
450     return { m.m00, m.m10, m.m20,
451              m.m01, m.m11, m.m21,
452              m.m02, m.m12, m.m22}; }
transpose(MAT4_T m)453 TEMPLATE_TYPENAME_T inline MAT4_T transpose(MAT4_T m) {
454     return { m.m00, m.m10, m.m20, m.m30,
455              m.m01, m.m11, m.m21, m.m31,
456              m.m02, m.m12, m.m22, m.m32,
457              m.m03, m.m13, m.m23, m.m33}; }
458 // inverse
459 //////////////////////////
460 #define M(X,Y) (m.m##X * m.m##Y)
inverse(QUAT_T const & q)461 TEMPLATE_TYPENAME_T inline QUAT_T inverse(QUAT_T const &q) { return QUAT_T(q.w, -q.x, -q.y, -q.z) / dot(q, q); }
inverse(MAT3_T const & m)462 TEMPLATE_TYPENAME_T inline MAT3_T inverse(MAT3_T const &m) {
463     T invDet = T(1) / (m.m00 * (M(11,22) - M(21,12)) - m.m10 * (M(01,22) - M(21,02)) + m.m20 * (M(01,12) - M(11,02)));
464     return MAT3_T(  (M(11,22) - M(21,12)), - (M(01,22) - M(21,02)),   (M(01,12) - M(11,02)),
465                   - (M(10,22) - M(20,12)),   (M(00,22) - M(20,02)), - (M(00,12) - M(10,02)),
466                     (M(10,21) - M(20,11)), - (M(00,21) - M(20,01)),   (M(00,11) - M(10,01))) * invDet; } // ==> "operator *" is faster
inverse(MAT4_T const & m)467 TEMPLATE_TYPENAME_T inline MAT4_T inverse(MAT4_T const &m) {
468     const T c0 = M(22,33) - M(32,23);   VEC4_T f0(c0, c0, M(12,33) - M(32,13), M(12,23) - M(22,13));
469     const T c1 = M(21,33) - M(31,23);   VEC4_T f1(c1, c1, M(11,33) - M(31,13), M(11,23) - M(21,13));
470     const T c2 = M(21,32) - M(31,22);   VEC4_T f2(c2, c2, M(11,32) - M(31,12), M(11,22) - M(21,12));
471     const T c3 = M(20,33) - M(30,23);   VEC4_T f3(c3, c3, M(10,33) - M(30,13), M(10,23) - M(20,13));
472     const T c4 = M(20,32) - M(30,22);   VEC4_T f4(c4, c4, M(10,32) - M(30,12), M(10,22) - M(20,12));
473     const T c5 = M(20,31) - M(30,21);   VEC4_T f5(c5, c5, M(10,31) - M(30,11), M(10,21) - M(20,11));
474 #undef M
475     VEC4_T v0(m.m10, m.m00, m.m00, m.m00);
476     VEC4_T v1(m.m11, m.m01, m.m01, m.m01);
477     VEC4_T v2(m.m12, m.m02, m.m02, m.m02);
478     VEC4_T v3(m.m13, m.m03, m.m03, m.m03);
479 
480     VEC4_T signV(T(1), T(-1),  T(1), T(-1));
481     MAT4_T inv((v1 * f0 - v2 * f1 + v3 * f2) *  signV,
482                (v0 * f0 - v2 * f3 + v3 * f4) * -signV,
483                (v0 * f1 - v1 * f3 + v3 * f5) *  signV,
484                (v0 * f2 - v1 * f4 + v2 * f5) * -signV);
485 
486     VEC4_T v0r0(m.v[0] * VEC4_T(inv.m00, inv.m10, inv.m20, inv.m30));
487     return inv * (T(1) / (v0r0.x + v0r0.y + v0r0.z + v0r0.w)); }// 1/determinant ==> "operator *" is faster
488 // external operators
489 //////////////////////////
490 TEMPLATE_TYPENAME_T inline VEC2_T operator*(const T s, const VEC2_T& v) {  return v * s; }
491 TEMPLATE_TYPENAME_T inline VEC3_T operator*(const T s, const VEC3_T& v) {  return v * s; }
492 TEMPLATE_TYPENAME_T inline VEC4_T operator*(const T s, const VEC4_T& v) {  return v * s; }
493 TEMPLATE_TYPENAME_T inline QUAT_T operator*(const T s, const QUAT_T& q) {  return q * s; }
494 
495 TEMPLATE_TYPENAME_T inline VEC2_T operator/(const T s, const VEC2_T& v) {  return { s/v.x, s/v.y }; }
496 TEMPLATE_TYPENAME_T inline VEC3_T operator/(const T s, const VEC3_T& v) {  return { s/v.x, s/v.y, s/v.z }; }
497 TEMPLATE_TYPENAME_T inline VEC4_T operator/(const T s, const VEC4_T& v) {  return { s/v.x, s/v.y, s/v.z, s/v.w }; }
498 TEMPLATE_TYPENAME_T inline QUAT_T operator/(const T s, const QUAT_T& q) {  return { s/q.x, s/q.y, s/q.z, s/q.w }; }
499 
500 TEMPLATE_TYPENAME_T inline VEC3_T operator*(const QUAT_T& q, const VEC3_T& v) {
501     const VEC3_T qV(q.x, q.y, q.z), uv(cross(qV, v));
502     return v + ((uv * q.w) + cross(qV, uv)) * T(2); }
503 TEMPLATE_TYPENAME_T inline  VEC3_T operator*(const VEC3_T& v, const QUAT_T& q) {  return inverse(q) * v; }
504 // translate / scale
505 //////////////////////////
translate(MAT4_T const & m,VEC3_T const & v)506 TEMPLATE_TYPENAME_T inline MAT4_T translate(MAT4_T const& m, VEC3_T const& v) {
507     MAT4_T r(m); r[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
508     return r; }
scale(MAT4_T const & m,VEC3_T const & v)509 TEMPLATE_TYPENAME_T inline MAT4_T scale(MAT4_T const& m, VEC3_T const& v) {
510     return MAT4_T(m[0] * v[0], m[1] * v[1], m[2] * v[2], m[3]); }
511 // quat angle/axis
512 //////////////////////////
angleAxis(T const & a,VEC3_T const & v)513 TEMPLATE_TYPENAME_T inline QUAT_T angleAxis(T const &a, VEC3_T const &v) {	return QUAT_T(cos(a * T(0.5)), v * sin(a * T(0.5))); }
angle(QUAT_T const & q)514 TEMPLATE_TYPENAME_T inline T angle(QUAT_T const& q) { return acos(q.w) * T(2); }
axis(QUAT_T const & q)515 TEMPLATE_TYPENAME_T inline VEC3_T axis(QUAT_T const& q) {
516     const T t1 = T(1) - q.w * q.w; if(t1 <= T(0)) return VEC3_T(0, 0, 1);
517     const T t2 = T(1) / sqrt(t1);  return VEC3_T(q.x * t2, q.y * t2, q.z * t2); }
518 // trigonometric
519 //////////////////////////
radians(T d)520 TEMPLATE_TYPENAME_T inline T radians(T d) { return d * T(0.0174532925199432957692369076849); }
degrees(T r)521 TEMPLATE_TYPENAME_T inline T degrees(T r) { return r * T(57.295779513082320876798154814105); }
pi()522 TEMPLATE_TYPENAME_T inline T pi() { return T(3.1415926535897932384626433832795029); }
one_over_pi()523 TEMPLATE_TYPENAME_T inline T one_over_pi() { return T(0.318309886183790671537767526745028724); }
524 
525 // lookAt
526 //////////////////////////
lookAt(const VEC3_T & pov,const VEC3_T & tgt,const VEC3_T & up)527 TEMPLATE_TYPENAME_T inline MAT4_T lookAt(const VEC3_T& pov, const VEC3_T& tgt, const VEC3_T& up)
528 {
529 #ifdef VGM_USES_LEFT_HAND_AXES
530     VEC3_T k = normalize(tgt - pov), i = normalize(cross(up, k)), j = cross(k, i);
531 #else
532     VEC3_T k = normalize(tgt - pov), i = normalize(cross(k, up)), j = cross(i, k);   k = -k;
533 #endif
534     return {     i.x,          j.x,          k.x,     T(0),
535                  i.y,          j.y,          k.y,     T(0),
536                  i.z,          j.z,          k.z,     T(0),
537             -dot(i, pov), -dot(j, pov), -dot(k, pov), T(1)}; }
538 // ortho
539 //////////////////////////
ortho(T l,T r,T b,T t,T n,T f)540 TEMPLATE_TYPENAME_T inline MAT4_T ortho(T l, T r, T b, T t, T n, T f)
541 {
542 #ifdef VGM_USES_LEFT_HAND_AXES
543     const T v = T(2);
544 #else
545     const T v = T(-2);
546 #endif
547     return {  T(2)/(r-l),     T(0),         T(0),     T(0),
548                 T(0),       T(2)/(t-b),     T(0),     T(0),
549                 T(0),         T(0),        v/(f-n),   T(0),
550             -(r+l)/(r-l), -(t+b)/(t-b), -(f+n)/(f-n), T(1)}; }
551 // perspective
552 //////////////////////////
perspective(T fovy,T a,T n,T f)553 TEMPLATE_TYPENAME_T inline MAT4_T perspective(T fovy, T a, T n, T f)
554 {
555 #ifdef VGM_USES_LEFT_HAND_AXES
556     const T v = T(1), f_n = (f+n)/(f-n);
557 #else
558     const T v = T(-1), f_n = -(f+n)/(f-n);
559 #endif
560     const T hFovy = tan(fovy / T(2));
561     return { T(1)/(a*hFovy),  T(0),           T(0),      T(0),
562                T(0),        T(1)/(hFovy),     T(0),      T(0),
563                T(0),          T(0),            f_n,        v ,
564                T(0),          T(0),   -(T(2)*f*n)/(f-n), T(0)}; }
565 // perspectiveFov
566 //////////////////////////
perspectiveFov(T fovy,T w,T h,T n,T f)567 TEMPLATE_TYPENAME_T inline MAT4_T perspectiveFov(T fovy, T w, T h, T n, T f) { return perspective(fovy, w/h, n, f); }
568 // frustrum
569 //////////////////////////
frustum(T l,T r,T b,T t,T n,T f)570 TEMPLATE_TYPENAME_T inline MAT4_T frustum(T l, T r, T b, T t, T n, T f)
571 {
572 #ifdef VGM_USES_LEFT_HAND_AXES
573     const T v = T(1),  f_n =  (f+n)/(f-n);
574 #else
575     const T v = T(-1), f_n = -(f+n)/(f-n);
576 #endif
577     return { (T(2)*n)/(r-l),       T(0),         T(0),         T(0),
578                    T(0),     (T(2)*n)/(t-b),     T(0),         T(0),
579                 (r+l)/(r-l),    (t+b)/(t-b),      f_n,           v ,
580                    T(0),           T(0),    -(T(2)*f*n)/(f-n), T(0)}; }
581 
582 } // end namespace vgm
583 
584 #ifdef VGM_USES_TEMPLATE
585     using vec2 = vgm::Vec2<float>;
586     using vec3 = vgm::Vec3<float>;
587     using vec4 = vgm::Vec4<float>;
588     using quat = vgm::Quat<float>;
589     using mat3 = vgm::Mat3<float>;
590     using mat4 = vgm::Mat4<float>;
591     using mat3x3 = mat3;
592     using mat4x4 = mat4;
593 
594     using dvec2 = vgm::Vec2<double>;
595     using dvec3 = vgm::Vec3<double>;
596     using dvec4 = vgm::Vec4<double>;
597     using dquat = vgm::Quat<double>;
598     using dmat3 = vgm::Mat3<double>;
599     using dmat4 = vgm::Mat4<double>;
600     using dmat3x3 = dmat3;
601     using dmat4x4 = dmat4;
602 
603     using ivec2 = vgm::Vec2<int32_t>;
604     using ivec3 = vgm::Vec3<int32_t>;
605     using ivec4 = vgm::Vec4<int32_t>;
606 
607     using uvec2 = vgm::Vec2<uint32_t>;
608     using uvec3 = vgm::Vec3<uint32_t>;
609     using uvec4 = vgm::Vec4<uint32_t>;
610 
611 #ifdef VGIZMO_USES_HLSL_TYPES // testing phase
612     using float2   = vgm::Vec2<float>;
613     using float3   = vgm::Vec3<float>;
614     using float4   = vgm::Vec4<float>;
615     using float3x3 = vgm::Mat3<float>;
616     using float4x4 = vgm::Mat4<float>;
617 
618     using double2   = vgm::Vec2<double>;
619     using double3   = vgm::Vec3<double>;
620     using double4   = vgm::Vec4<double>;
621     using double3x3 = vgm::Mat3<double>;
622     using double4x4 = vgm::Mat4<double>;
623 
624     using int2 = vgm::Vec2<int32_t>;
625     using int3 = vgm::Vec3<int32_t>;
626     using int4 = vgm::Vec4<int32_t>;
627 
628     using uint2 = vgm::Vec2<uint32_t>;
629     using uint3 = vgm::Vec3<uint32_t>;
630     using uint4 = vgm::Vec4<uint32_t>;
631 #endif
632 #else
633     using vec2 = vgm::Vec2;
634     using vec3 = vgm::Vec3;
635     using vec4 = vgm::Vec4;
636     using quat = vgm::Quat;
637     using mat3 = vgm::Mat3;
638     using mat4 = vgm::Mat4;
639     using mat3x3 = mat3;
640     using mat4x4 = mat4;
641 
642 #ifdef VGIZMO_USES_HLSL_TYPES
643     using float2   = vgm::Vec2;
644     using float3   = vgm::Vec3;
645     using float4   = vgm::Vec4;
646     using float3x3 = vgm::Mat3;
647     using float4x4 = vgm::Mat4;
648 #endif
649 
650 #endif
651 // Internal vGizmo USES ONLY
652     using tVec2 = vgm::VEC2_PRECISION;
653     using tVec3 = vgm::VEC3_PRECISION;
654     using tVec4 = vgm::VEC4_PRECISION;
655     using tQuat = vgm::QUAT_PRECISION;
656     using tMat3 = vgm::MAT3_PRECISION;
657     using tMat4 = vgm::MAT4_PRECISION;
658 
659     using uint8  = uint8_t;
660     using  int8  =  int8_t;
661     using uint   = uint32_t;
662     using  int32 =  int32_t;
663     using uint32 = uint32_t;
664     using  int64 =  int64_t;
665     using uint64 = uint64_t;
666 
667     #undef VEC2_T
668     #undef VEC3_T
669     #undef VEC4_T
670     #undef QUAT_T
671     #undef MAT3_T
672     #undef MAT4_T
673 
674     #undef VEC2_PRECISION
675     #undef VEC3_PRECISION
676     #undef VEC4_PRECISION
677     #undef QUAT_PRECISION
678     #undef MAT3_PRECISION
679     #undef MAT4_PRECISION
680 
681 
682 #endif // use vGizmoMath
683 #if !defined(VGM_DISABLE_AUTO_NAMESPACE) || defined(VGIZMO_H_FILE)
684     using namespace VGM_NAMESPACE;
685 #endif
686 
687 #undef VGM_NAMESPACE
688 #undef T // if used T as #define, undef it
689