1///////////////////////////////////////////////////////////////////////////////////
2/// OpenGL Mathematics (glm.g-truc.net)
3///
4/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
5/// Permission is hereby granted, free of charge, to any person obtaining a copy
6/// of this software and associated documentation files (the "Software"), to deal
7/// in the Software without restriction, including without limitation the rights
8/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9/// copies of the Software, and to permit persons to whom the Software is
10/// furnished to do so, subject to the following conditions:
11///
12/// The above copyright notice and this permission notice shall be included in
13/// all copies or substantial portions of the Software.
14///
15/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21/// THE SOFTWARE.
22///
23/// @ref gtx_dual_quaternion
24/// @file glm/gtx/dual_quaternion.hpp
25/// @date 2013-02-10 / 2013-02-20
26/// @author Maksim Vorobiev (msomeone@gmail.com)
27///
28/// @see core (dependence)
29/// @see gtc_half_float (dependence)
30/// @see gtc_constants (dependence)
31/// @see gtc_quaternion (dependence)
32///
33/// @defgroup gtc_dual_quaternion GLM_GTX_dual_quaternion
34/// @ingroup gtc
35///
36/// @brief Defines a templated dual-quaternion type and several dual-quaternion operations.
37///
38/// <glm/gtx/dual_quaternion.hpp> need to be included to use these functionalities.
39///////////////////////////////////////////////////////////////////////////////////
40
41#ifndef GLM_GTX_dual_quaternion
42#define GLM_GTX_dual_quaternion
43
44// Dependency:
45#include "../glm.hpp"
46#include "../gtc/constants.hpp"
47#include "../gtc/quaternion.hpp"
48
49#if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED))
50#	pragma message("GLM: GLM_GTX_dual_quaternion extension included")
51#endif
52
53namespace glm{
54namespace detail
55{
56	template <typename T, precision P>
57	struct tdualquat
58	{
59		enum ctor{null};
60
61		typedef glm::detail::tquat<T, P> part_type;
62
63	public:
64		glm::detail::tquat<T, P> real, dual;
65
66		GLM_FUNC_DECL GLM_CONSTEXPR int length() const;
67
68		// Constructors
69		GLM_FUNC_DECL tdualquat();
70		GLM_FUNC_DECL explicit tdualquat(tquat<T, P> const & real);
71		GLM_FUNC_DECL tdualquat(tquat<T, P> const & real,tquat<T, P> const & dual);
72		GLM_FUNC_DECL tdualquat(tquat<T, P> const & orientation,tvec3<T, P> const& translation);
73
74		//////////////////////////////////////////////////////////////
75		// tdualquat conversions
76		GLM_FUNC_DECL explicit tdualquat(tmat2x4<T, P> const & holder_mat);
77		GLM_FUNC_DECL explicit tdualquat(tmat3x4<T, P> const & aug_mat);
78
79		// Accesses
80		GLM_FUNC_DECL part_type & operator[](int i);
81		GLM_FUNC_DECL part_type const & operator[](int i) const;
82
83		// Operators
84		GLM_FUNC_DECL tdualquat<T, P> & operator*=(T const & s);
85		GLM_FUNC_DECL tdualquat<T, P> & operator/=(T const & s);
86	};
87
88	template <typename T, precision P>
89	GLM_FUNC_DECL detail::tquat<T, P> operator- (
90		detail::tquat<T, P> const & q);
91
92	template <typename T, precision P>
93	GLM_FUNC_DECL detail::tdualquat<T, P> operator+ (
94		detail::tdualquat<T, P> const & q,
95		detail::tdualquat<T, P> const & p);
96
97	template <typename T, precision P>
98	GLM_FUNC_DECL detail::tdualquat<T, P> operator* (
99		detail::tdualquat<T, P> const & q,
100		detail::tdualquat<T, P> const & p);
101
102	template <typename T, precision P>
103	GLM_FUNC_DECL detail::tvec3<T, P> operator* (
104		detail::tquat<T, P> const & q,
105		detail::tvec3<T, P> const & v);
106
107	template <typename T, precision P>
108	GLM_FUNC_DECL detail::tvec3<T, P> operator* (
109		detail::tvec3<T, P> const & v,
110		detail::tquat<T, P> const & q);
111
112	template <typename T, precision P>
113	GLM_FUNC_DECL detail::tvec4<T, P> operator* (
114		detail::tquat<T, P> const & q,
115		detail::tvec4<T, P> const & v);
116
117	template <typename T, precision P>
118	GLM_FUNC_DECL detail::tvec4<T, P> operator* (
119		detail::tvec4<T, P> const & v,
120		detail::tquat<T, P> const & q);
121
122	template <typename T, precision P>
123	GLM_FUNC_DECL detail::tdualquat<T, P> operator* (
124		detail::tdualquat<T, P> const & q,
125		T const & s);
126
127	template <typename T, precision P>
128	GLM_FUNC_DECL detail::tdualquat<T, P> operator* (
129		T const & s,
130		detail::tdualquat<T, P> const & q);
131
132	template <typename T, precision P>
133	GLM_FUNC_DECL detail::tdualquat<T, P> operator/ (
134		detail::tdualquat<T, P> const & q,
135		T const & s);
136} //namespace detail
137
138	/// @addtogroup gtc_dual_quaternion
139	/// @{
140
141	/// Returns the normalized quaternion.
142	///
143	/// @see gtc_dual_quaternion
144	template <typename T, precision P>
145	GLM_FUNC_DECL detail::tdualquat<T, P> normalize(
146		detail::tdualquat<T, P> const & q);
147
148	/// Returns the linear interpolation of two dual quaternion.
149	///
150	/// @see gtc_dual_quaternion
151	template <typename T, precision P>
152	GLM_FUNC_DECL detail::tdualquat<T, P> lerp(
153		detail::tdualquat<T, P> const & x,
154		detail::tdualquat<T, P> const & y,
155		T const & a);
156
157	/// Returns the q inverse.
158	///
159	/// @see gtc_dual_quaternion
160	template <typename T, precision P>
161	GLM_FUNC_DECL detail::tdualquat<T, P> inverse(
162		detail::tdualquat<T, P> const & q);
163
164	/*
165	/// Extracts a rotation part from dual-quaternion to a 3 * 3 matrix.
166	/// TODO
167	///
168	/// @see gtc_dual_quaternion
169	template <typename T, precision P>
170	detail::tmat3x3<T, P> mat3_cast(
171		detail::tdualquat<T, P> const & x);
172	*/
173
174	/// Converts a quaternion to a 2 * 4 matrix.
175	///
176	/// @see gtc_dual_quaternion
177	template <typename T, precision P>
178	GLM_FUNC_DECL detail::tmat2x4<T, P> mat2x4_cast(
179		detail::tdualquat<T, P> const & x);
180
181	/// Converts a quaternion to a 3 * 4 matrix.
182	///
183	/// @see gtc_dual_quaternion
184	template <typename T, precision P>
185	GLM_FUNC_DECL detail::tmat3x4<T, P> mat3x4_cast(
186		detail::tdualquat<T, P> const & x);
187
188	/// Converts a 2 * 4 matrix (matrix which holds real and dual parts) to a quaternion.
189	///
190	/// @see gtc_dual_quaternion
191	template <typename T, precision P>
192	GLM_FUNC_DECL detail::tdualquat<T, P> dualquat_cast(
193		detail::tmat2x4<T, P> const & x);
194
195	/// Converts a 3 * 4 matrix (augmented matrix rotation + translation) to a quaternion.
196	///
197	/// @see gtc_dual_quaternion
198	template <typename T, precision P>
199	GLM_FUNC_DECL detail::tdualquat<T, P> dualquat_cast(
200		detail::tmat3x4<T, P> const & x);
201
202
203	/// Dual-quaternion of low single-precision floating-point numbers.
204	///
205	/// @see gtc_dual_quaternion
206	typedef detail::tdualquat<float, lowp>		lowp_dualquat;
207
208	/// Dual-quaternion of medium single-precision floating-point numbers.
209	///
210	/// @see gtc_dual_quaternion
211	typedef detail::tdualquat<float, mediump>	mediump_dualquat;
212
213	/// Dual-quaternion of high single-precision floating-point numbers.
214	///
215	/// @see gtc_dual_quaternion
216	typedef detail::tdualquat<float, highp>		highp_dualquat;
217
218
219	/// Dual-quaternion of low single-precision floating-point numbers.
220	///
221	/// @see gtc_dual_quaternion
222	typedef detail::tdualquat<float, lowp>		lowp_fdualquat;
223
224	/// Dual-quaternion of medium single-precision floating-point numbers.
225	///
226	/// @see gtc_dual_quaternion
227	typedef detail::tdualquat<float, mediump>	mediump_fdualquat;
228
229	/// Dual-quaternion of high single-precision floating-point numbers.
230	///
231	/// @see gtc_dual_quaternion
232	typedef detail::tdualquat<float, highp>		highp_fdualquat;
233
234
235	/// Dual-quaternion of low double-precision floating-point numbers.
236	///
237	/// @see gtc_dual_quaternion
238	typedef detail::tdualquat<double, lowp>		lowp_ddualquat;
239
240	/// Dual-quaternion of medium double-precision floating-point numbers.
241	///
242	/// @see gtc_dual_quaternion
243	typedef detail::tdualquat<double, mediump>	mediump_ddualquat;
244
245	/// Dual-quaternion of high double-precision floating-point numbers.
246	///
247	/// @see gtc_dual_quaternion
248	typedef detail::tdualquat<double, highp>	highp_ddualquat;
249
250
251#if(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
252	/// Dual-quaternion of floating-point numbers.
253	///
254	/// @see gtc_dual_quaternion
255	typedef highp_fdualquat			dualquat;
256
257	/// Dual-quaternion of single-precision floating-point numbers.
258	///
259	/// @see gtc_dual_quaternion
260	typedef highp_fdualquat			fdualquat;
261#elif(defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
262	typedef highp_fdualquat			dualquat;
263	typedef highp_fdualquat			fdualquat;
264#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
265	typedef mediump_fdualquat		dualquat;
266	typedef mediump_fdualquat		fdualquat;
267#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && defined(GLM_PRECISION_LOWP_FLOAT))
268	typedef lowp_fdualquat			dualquat;
269	typedef lowp_fdualquat			fdualquat;
270#else
271#	error "GLM error: multiple default precision requested for single-precision floating-point types"
272#endif
273
274
275#if(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
276	/// Dual-quaternion of default double-precision floating-point numbers.
277	///
278	/// @see gtc_dual_quaternion
279	typedef highp_ddualquat			ddualquat;
280#elif(defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
281	typedef highp_ddualquat			ddualquat;
282#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
283	typedef mediump_ddualquat		ddualquat;
284#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && defined(GLM_PRECISION_LOWP_DOUBLE))
285	typedef lowp_ddualquat			ddualquat;
286#else
287#	error "GLM error: Multiple default precision requested for double-precision floating-point types"
288#endif
289
290	/// @}
291} //namespace glm
292
293#include "dual_quaternion.inl"
294
295#endif//GLM_GTX_dual_quaternion
296