rev |
line source |
nuclear@13
|
1 #ifndef QUATERNION_H_
|
nuclear@13
|
2 #define QUATERNION_H_
|
nuclear@13
|
3
|
nuclear@13
|
4 class Quat;
|
nuclear@13
|
5
|
nuclear@13
|
6 inline Quat operator *(const Quat &a, const Quat &b);
|
nuclear@13
|
7
|
nuclear@13
|
8 class Quat{
|
nuclear@13
|
9 public:
|
nuclear@13
|
10 float x, y, z, w;
|
nuclear@13
|
11
|
nuclear@13
|
12 Quat() : x(0), y(0), z(0), w(1) {}
|
nuclear@13
|
13 Quat(float xx, float yy, float zz, float ww) : x(xx), y(yy), z(zz), w(ww) {}
|
nuclear@13
|
14
|
nuclear@13
|
15 void set_identity()
|
nuclear@13
|
16 {
|
nuclear@13
|
17 x = y = z = 0.0f;
|
nuclear@13
|
18 w = 1.0f;
|
nuclear@13
|
19 }
|
nuclear@13
|
20
|
nuclear@13
|
21 Quat conjugate() const
|
nuclear@13
|
22 {
|
nuclear@13
|
23 return Quat(-x, -y, -z, w);
|
nuclear@13
|
24 }
|
nuclear@13
|
25
|
nuclear@13
|
26 float length() const
|
nuclear@13
|
27 {
|
nuclear@13
|
28 return (float)sqrt(x * x + y * y + z * z + w * w);
|
nuclear@13
|
29 }
|
nuclear@13
|
30
|
nuclear@13
|
31 float length_sq() const
|
nuclear@13
|
32 {
|
nuclear@13
|
33 return x * x + y * y + z * z + w * w;
|
nuclear@13
|
34 }
|
nuclear@13
|
35
|
nuclear@13
|
36 void normalize()
|
nuclear@13
|
37 {
|
nuclear@13
|
38 float len = length();
|
nuclear@13
|
39 if(len != 0.0) {
|
nuclear@13
|
40 x /= len;
|
nuclear@13
|
41 y /= len;
|
nuclear@13
|
42 z /= len;
|
nuclear@13
|
43 w /= len;
|
nuclear@13
|
44 }
|
nuclear@13
|
45 }
|
nuclear@13
|
46
|
nuclear@13
|
47 Quat inverse() const
|
nuclear@13
|
48 {
|
nuclear@13
|
49 Quat inv = conjugate();
|
nuclear@13
|
50 float len_sq = length_sq();
|
nuclear@13
|
51 if(len_sq != 0.0) {
|
nuclear@13
|
52 inv.x /= len_sq;
|
nuclear@13
|
53 inv.y /= len_sq;
|
nuclear@13
|
54 inv.z /= len_sq;
|
nuclear@13
|
55 inv.w /= len_sq;
|
nuclear@13
|
56 }
|
nuclear@13
|
57 return inv;
|
nuclear@13
|
58 }
|
nuclear@13
|
59
|
nuclear@13
|
60 void set_rotation(float angle, float axis_x, float axis_y, float axis_z)
|
nuclear@13
|
61 {
|
nuclear@13
|
62 float half_angle = angle * 0.5;
|
nuclear@13
|
63 float sin_half = sin(half_angle);
|
nuclear@13
|
64
|
nuclear@13
|
65 w = cos(half_angle);
|
nuclear@13
|
66 x = axis_x * sin_half;
|
nuclear@13
|
67 y = axis_y * sin_half;
|
nuclear@13
|
68 z = axis_z * sin_half;
|
nuclear@13
|
69 }
|
nuclear@13
|
70
|
nuclear@13
|
71 void rotate(float angle, float x, float y, float z)
|
nuclear@13
|
72 {
|
nuclear@13
|
73 Quat q;
|
nuclear@13
|
74 q.set_rotation(angle, x, y, z);
|
nuclear@13
|
75 *this = *this * q;
|
nuclear@13
|
76 }
|
nuclear@13
|
77
|
nuclear@13
|
78 void rotate(const Quat &q)
|
nuclear@13
|
79 {
|
nuclear@13
|
80 *this = q * *this * q.conjugate();
|
nuclear@13
|
81 }
|
nuclear@13
|
82
|
nuclear@13
|
83 Matrix4x4 get_matrix() const
|
nuclear@13
|
84 {
|
nuclear@13
|
85 return Matrix4x4(
|
nuclear@13
|
86 1.0 - 2.0 * y*y - 2.0 * z*z, 2.0 * x * y - 2.0 * w * z, 2.0 * z * x + 2.0 * w * y, 0,
|
nuclear@13
|
87 2.0 * x * y + 2.0 * w * z, 1.0 - 2.0 * x*x - 2.0 * z*z, 2.0 * y * z - 2.0 * w * x, 0,
|
nuclear@13
|
88 2.0 * z * x - 2.0 * w * y, 2.0 * y * z + 2.0 * w * x, 1.0 - 2.0 * x*x - 2.0 * y*y, 0,
|
nuclear@13
|
89 0, 0, 0, 1);
|
nuclear@13
|
90 }
|
nuclear@13
|
91 };
|
nuclear@13
|
92
|
nuclear@13
|
93 inline Quat operator *(const Quat &a, const Quat &b)
|
nuclear@13
|
94 {
|
nuclear@13
|
95 float dot = a.x * b.x + a.y * b.y + a.z * b.z;
|
nuclear@13
|
96 float cross_x = a.y * b.z - a.z * b.y;
|
nuclear@13
|
97 float cross_y = a.z * b.x - a.x * b.z;
|
nuclear@13
|
98 float cross_z = a.x * b.y - a.y * b.x;
|
nuclear@13
|
99
|
nuclear@13
|
100 float w = a.w * b.w - dot;
|
nuclear@13
|
101 float x = a.x * b.w + b.x * a.w + cross_x;
|
nuclear@13
|
102 float y = a.y * b.w + b.y * a.w + cross_y;
|
nuclear@13
|
103 float z = a.z * b.w + b.z * a.w + cross_z;
|
nuclear@13
|
104
|
nuclear@13
|
105 return Quat(x, y, z, w);
|
nuclear@13
|
106 }
|
nuclear@13
|
107
|
nuclear@13
|
108 #endif // QUATERNION_H_
|