OPENVR Scol plugin
vrmaths.cpp
1 #include "vrmaths.h"
2 
3 const Vector3 Vector3::ZERO(0.0f, 0.0f, 0.0f);
4 const Matrix4 Matrix4::IDENTITY(
5  1, 0, 0, 0,
6  0, 1, 0, 0,
7  0, 0, 1, 0,
8  0, 0, 0, 1);
9 
10 float Quaternion::Norm() const
11 {
12  return w*w + x*x + y*y + z*z;
13 }
14 
15 float Quaternion::normalise(void)
16 {
17  float len = Norm();
18  float factor = 1.0f / sqrt(len);
19  *this = *this * factor;
20  return len;
21 }
22 
23 Quaternion Quaternion::Inverse() const
24 {
25  float fNorm = w*w + x*x + y*y + z*z;
26  if (fNorm > 0.0)
27  {
28  float fInvNorm = 1.0f / fNorm;
29  return Quaternion(w*fInvNorm, -x*fInvNorm, -y*fInvNorm, -z*fInvNorm);
30  }
31  else
32  {
33  return Quaternion(0.0f, 0.0f, 0.0f, 0.0f);
34  }
35 }
36 
37 void Quaternion::FromRotationMatrix(const Matrix3& kRot)
38 {
39  // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
40  // article "Quaternion Calculus and Fast Animation".
41 
42  float fTrace = kRot[0][0] + kRot[1][1] + kRot[2][2];
43  float fRoot;
44 
45  if (fTrace > 0.0)
46  {
47  // |w| > 1/2, may as well choose w > 1/2
48  fRoot = sqrt(fTrace + 1.0f); // 2w
49  w = 0.5f*fRoot;
50  fRoot = 0.5f / fRoot; // 1/(4w)
51  x = (kRot[2][1] - kRot[1][2])*fRoot;
52  y = (kRot[0][2] - kRot[2][0])*fRoot;
53  z = (kRot[1][0] - kRot[0][1])*fRoot;
54  }
55  else
56  {
57  // |w| <= 1/2
58  static size_t s_iNext[3] = { 1, 2, 0 };
59  size_t i = 0;
60  if (kRot[1][1] > kRot[0][0])
61  i = 1;
62  if (kRot[2][2] > kRot[i][i])
63  i = 2;
64  size_t j = s_iNext[i];
65  size_t k = s_iNext[j];
66 
67  fRoot = sqrt(kRot[i][i] - kRot[j][j] - kRot[k][k] + 1.0f);
68  float* apkQuat[3] = { &x, &y, &z };
69  *apkQuat[i] = 0.5f*fRoot;
70  fRoot = 0.5f / fRoot;
71  w = (kRot[k][j] - kRot[j][k])*fRoot;
72  *apkQuat[j] = (kRot[j][i] + kRot[i][j])*fRoot;
73  *apkQuat[k] = (kRot[k][i] + kRot[i][k])*fRoot;
74  }
75 }