rayzor

annotate src/quat.h @ 17:79609d482762

the renderer renders, also fixed an unnoticed matrix conversion problem between scenegraph and min3d
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 14 Apr 2014 07:34:45 +0300
parents
children
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_