Subversion Repositories gelsvn

Rev

Rev 188 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 188 Rev 306
Line 1... Line 1...
1
#ifndef __CGLA_QUATERNION_H__
1
#ifndef __CGLA_QUATERNION_H__
2
#define __CGLA_QUATERNION_H__
2
#define __CGLA_QUATERNION_H__
3
 
3
 
4
#include "Vec3f.h"
-
 
5
#include "Vec4f.h"
4
#include "Quatf.h"
6
#include "Mat3x3f.h"
-
 
7
#include "Mat4x4f.h"
-
 
8
 
5
 
9
namespace CGLA {
6
namespace CGLA {
10
 
7
 
11
	/** \brief A Quaterinion class. 
-
 
12
 
-
 
13
	Quaternions are algebraic entities useful for rotation. */
-
 
14
 
-
 
15
	class Quaternion
-
 
16
	{
-
 
17
	public:
-
 
18
 
-
 
19
		/// Vector part of quaternion
-
 
20
		Vec3f qv;
-
 
21
 
-
 
22
		/// Scalar part of quaternion
-
 
23
		float qw;
-
 
24
 
-
 
25
		/// Construct 0 quaternion
-
 
26
		Quaternion(): qw(CGLA_INIT_VALUE) {}
-
 
27
 
-
 
28
		/// Construct quaternion from vector and scalar
-
 
29
		Quaternion(const Vec3f _qv, float _qw=1) : 
-
 
30
			qv(_qv) , qw(_qw) {}
-
 
31
 
-
 
32
		/// Construct quaternion from four scalars
-
 
33
		Quaternion(float x, float y, float z, float _qw) : 
-
 
34
			qv(x,y,z), qw(_qw) {}
-
 
35
 
-
 
36
		/// Assign values to a quaternion
-
 
37
		void set(float x, float y, float z, float _qw) 
-
 
38
		{
-
 
39
			qv.set(x,y,z);
-
 
40
			qw = _qw;
-
 
41
		}
-
 
42
 
-
 
43
		/// Get values from a quaternion
-
 
44
		void get(float& x, float& y, float& z, float& _qw) const
-
 
45
		{
-
 
46
			x  = qv[0];
-
 
47
			y  = qv[1];
-
 
48
			z  = qv[2];
-
 
49
			_qw = qw;
-
 
50
		}
-
 
51
 
-
 
52
		/// Get a 3x3 rotation matrix from a quaternion
-
 
53
		Mat3x3f get_mat3x3f() const;
-
 
54
 
-
 
55
		/// Get a 4x4 rotation matrix from a quaternion
-
 
56
		Mat4x4f get_mat4x4f() const;
-
 
57
 
-
 
58
		/// Construct a Quaternion from a rotation matrix.
-
 
59
		/// Matrix must be orthogonal
-
 
60
		void make_rot(const Mat4x4f& m);
-
 
61
	
-
 
62
		/// Construct a Quaternion from an angle and axis of rotation.
-
 
63
		void make_rot(float angle, const Vec3f&);
-
 
64
 
-
 
65
		/** Construct a Quaternion rotating from the direction given
-
 
66
				by the first argument to the direction given by the second.*/
-
 
67
		void make_rot(const Vec3f&,const Vec3f&);
-
 
68
 
-
 
69
		/// Obtain angle of rotation and axis
-
 
70
		void get_rot(float& angle, Vec3f&);
-
 
71
 
-
 
72
		/// Multiply two quaternions. (Combine their rotation)
-
 
73
		Quaternion operator *(Quaternion quat) const;
-
 
74
 
-
 
75
		/// Multiply scalar onto quaternion.
-
 
76
		Quaternion operator *(float scalar) const;
-
 
77
 
-
 
78
		/// Add two quaternions.
-
 
79
		Quaternion operator +(Quaternion quat) const;
-
 
80
		
-
 
81
		/// Invert quaternion
8
	typedef Quatf Quaternion;
82
		Quaternion inverse() const;
-
 
83
 
-
 
84
		/// Return conjugate quaternion
-
 
85
		Quaternion conjugate() const;
-
 
86
 
-
 
87
		/// Compute norm of quaternion
-
 
88
		float norm() const;
-
 
89
 
-
 
90
		/// Normalize quaternion.
-
 
91
		Quaternion normalize();
-
 
92
 
-
 
93
		/// Rotate vector according to quaternion
-
 
94
		Vec3f apply(const Vec3f& vec) const;
-
 
95
	};
-
 
96
 
-
 
97
	/// Compare for equality.
-
 
98
	inline bool operator==(const Quaternion& q0, const Quaternion& q1)
-
 
99
	{
-
 
100
		return (q0.qw == q1.qw && q0.qv == q1.qv);
-
 
101
	}
-
 
102
 
-
 
103
	/// Print quaternion to stream.
-
 
104
	inline std::ostream& operator<<(std::ostream&os, const Quaternion v)
-
 
105
	{
-
 
106
		os << "[ ";
-
 
107
		for(unsigned int i=0;i<3;i++) os << v.qv[i] << " ";
-
 
108
		os << " ~ " << v.qw << " ";
-
 
109
		os << "]";
-
 
110
 
-
 
111
		return os;
-
 
112
	}
-
 
113
 
-
 
114
	inline Quaternion Quaternion::operator *(Quaternion quat) const
-
 
115
	{
-
 
116
		return Quaternion(cross(qv,quat.qv) + quat.qw*qv + qw*quat.qv, 
-
 
117
											qw*quat.qw - dot(qv,quat.qv));
-
 
118
	}
-
 
119
 
-
 
120
	inline Quaternion Quaternion::operator *(float scalar) const
-
 
121
	{
-
 
122
		return Quaternion(scalar*qv,scalar*qw);
-
 
123
	}
-
 
124
 
-
 
125
	/// Multiply scalar onto quaternion
-
 
126
	inline Quaternion operator *(float scalar, Quaternion quat) 
-
 
127
	{
-
 
128
		return Quaternion(scalar*quat.qv,scalar*quat.qw);
-
 
129
	}
-
 
130
 
-
 
131
	
-
 
132
	inline Quaternion Quaternion::operator +(Quaternion quat) const
-
 
133
	{
-
 
134
		return Quaternion(qv + quat.qv,qw + quat.qw);
-
 
135
	}
-
 
136
 
-
 
137
	inline float Quaternion::norm() const
-
 
138
	{
-
 
139
		return qv[0]*qv[0] + qv[1]*qv[1] + qv[2]*qv[2] + qw*qw;
-
 
140
	}
-
 
141
 
-
 
142
	inline Quaternion Quaternion::normalize() 
-
 
143
	{
-
 
144
		return Quaternion(1.0/norm()*(*this));
-
 
145
	}
-
 
146
 
-
 
147
	inline Quaternion Quaternion::conjugate() const
-
 
148
	{
-
 
149
		return Quaternion(-qv,qw);
-
 
150
	}
-
 
151
 
-
 
152
	inline Quaternion Quaternion::inverse() const
-
 
153
	{
-
 
154
		return Quaternion(1.0/norm()*conjugate());
-
 
155
	}
-
 
156
 
-
 
157
 
-
 
158
	/** Perform linear interpolation of two quaternions. 
-
 
159
			The last argument is the parameter used to interpolate
-
 
160
			between the two first. SLERP - invented by Shoemake -
-
 
161
			is a good way to interpolate because the interpolation
-
 
162
			is performed on the unit sphere. 	
-
 
163
	*/
-
 
164
	inline Quaternion slerp(Quaternion q0, Quaternion q1, float t) 
-
 
165
	{
-
 
166
		float angle=acos(q0.qv[0]*q1.qv[0]+q0.qv[1]*q1.qv[1]+q0.qv[2]*q1.qv[2]+q0.qw*q1.qw);
-
 
167
		return (q0*sin((1-t)*angle)+q1*sin(t*angle))*(1/sin(angle));
-
 
168
	}
-
 
169
 
-
 
170
}
9
}
171
#endif
10
#endif