OPENXR Scol plugin
vrmaths.cpp
1#include "vrmaths.h"
2
3const Vector2i Vector2i::ZERO(0, 0);
4const Vector2 Vector2::ZERO(0.0f, 0.0f);
5const Vector3 Vector3::ZERO(0.0f, 0.0f, 0.0f);
6const Vector4 Vector4::ZERO(0.0f, 0.0f, 0.0, 0.0f);
7
8const Matrix4 Matrix4::IDENTITY(
9 1, 0, 0, 0,
10 0, 1, 0, 0,
11 0, 0, 1, 0,
12 0, 0, 0, 1);
13
14float Quaternion::Norm() const
15{
16 return w*w + x*x + y*y + z*z;
17}
18
19float Quaternion::normalise(void)
20{
21 float len = Norm();
22 float factor = 1.0f / sqrt(len);
23 *this = *this * factor;
24 return len;
25}
26
27Quaternion Quaternion::Inverse() const
28{
29 float fNorm = w*w + x*x + y*y + z*z;
30 if (fNorm > 0.0)
31 {
32 float fInvNorm = 1.0f / fNorm;
33 return Quaternion(w*fInvNorm, -x*fInvNorm, -y*fInvNorm, -z*fInvNorm);
34 }
35 else
36 {
37 return Quaternion(0.0f, 0.0f, 0.0f, 0.0f);
38 }
39}
40
41void Quaternion::ToRotationMatrix(Matrix3& kRot) const
42{
43 float fTx = x + x;
44 float fTy = y + y;
45 float fTz = z + z;
46 float fTwx = fTx * w;
47 float fTwy = fTy * w;
48 float fTwz = fTz * w;
49 float fTxx = fTx * x;
50 float fTxy = fTy * x;
51 float fTxz = fTz * x;
52 float fTyy = fTy * y;
53 float fTyz = fTz * y;
54 float fTzz = fTz * z;
55
56 kRot[0][0] = 1.0f - (fTyy + fTzz);
57 kRot[0][1] = fTxy - fTwz;
58 kRot[0][2] = fTxz + fTwy;
59 kRot[1][0] = fTxy + fTwz;
60 kRot[1][1] = 1.0f - (fTxx + fTzz);
61 kRot[1][2] = fTyz - fTwx;
62 kRot[2][0] = fTxz - fTwy;
63 kRot[2][1] = fTyz + fTwx;
64 kRot[2][2] = 1.0f - (fTxx + fTyy);
65}
66
67void Quaternion::FromRotationMatrix(const Matrix3& kRot)
68{
69 // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
70 // article "Quaternion Calculus and Fast Animation".
71
72 float fTrace = kRot[0][0] + kRot[1][1] + kRot[2][2];
73 float fRoot;
74
75 if (fTrace > 0.0)
76 {
77 // |w| > 1/2, may as well choose w > 1/2
78 fRoot = sqrt(fTrace + 1.0f); // 2w
79 w = 0.5f*fRoot;
80 fRoot = 0.5f / fRoot; // 1/(4w)
81 x = (kRot[2][1] - kRot[1][2])*fRoot;
82 y = (kRot[0][2] - kRot[2][0])*fRoot;
83 z = (kRot[1][0] - kRot[0][1])*fRoot;
84 }
85 else
86 {
87 // |w| <= 1/2
88 static size_t s_iNext[3] = { 1, 2, 0 };
89 size_t i = 0;
90 if (kRot[1][1] > kRot[0][0])
91 i = 1;
92 if (kRot[2][2] > kRot[i][i])
93 i = 2;
94 size_t j = s_iNext[i];
95 size_t k = s_iNext[j];
96
97 fRoot = sqrt(kRot[i][i] - kRot[j][j] - kRot[k][k] + 1.0f);
98 float* apkQuat[3] = { &x, &y, &z };
99 *apkQuat[i] = 0.5f*fRoot;
100 fRoot = 0.5f / fRoot;
101 w = (kRot[k][j] - kRot[j][k])*fRoot;
102 *apkQuat[j] = (kRot[j][i] + kRot[i][j])*fRoot;
103 *apkQuat[k] = (kRot[k][i] + kRot[i][k])*fRoot;
104 }
105}