Home | History | Annotate | Download | only in gtx
      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_simd_quat
     24 /// @file glm/gtx/simd_quat.hpp
     25 /// @date 2009-05-07 / 2011-06-07
     26 /// @author Christophe Riccio
     27 ///
     28 /// @see core (dependence)
     29 ///
     30 /// @defgroup gtx_simd_vec4 GLM_GTX_simd_quat
     31 /// @ingroup gtx
     32 ///
     33 /// @brief SIMD implementation of quat type.
     34 ///
     35 /// <glm/gtx/simd_quat.hpp> need to be included to use these functionalities.
     36 ///////////////////////////////////////////////////////////////////////////////////
     37 
     38 #ifndef GLM_GTX_simd_quat
     39 #define GLM_GTX_simd_quat
     40 
     41 // Dependency:
     42 #include "../glm.hpp"
     43 #include "../gtc/quaternion.hpp"
     44 #include "../gtx/fast_trigonometry.hpp"
     45 
     46 #if(GLM_ARCH != GLM_ARCH_PURE)
     47 
     48 #if(GLM_ARCH & GLM_ARCH_SSE2)
     49 #   include "../gtx/simd_mat4.hpp"
     50 #else
     51 #	error "GLM: GLM_GTX_simd_quat requires compiler support of SSE2 through intrinsics"
     52 #endif
     53 
     54 #if(defined(GLM_MESSAGES) && !defined(GLM_EXT_INCLUDED))
     55 #	pragma message("GLM: GLM_GTX_simd_quat extension included")
     56 #endif
     57 
     58 
     59 // Warning silencer for nameless struct/union.
     60 #if (GLM_COMPILER & GLM_COMPILER_VC)
     61 #   pragma warning(push)
     62 #   pragma warning(disable:4201)   // warning C4201: nonstandard extension used : nameless struct/union
     63 #endif
     64 
     65 
     66 namespace glm{
     67 namespace detail
     68 {
     69 	/// Quaternion implemented using SIMD SEE intrinsics.
     70 	/// \ingroup gtx_simd_vec4
     71 	GLM_ALIGNED_STRUCT(16) fquatSIMD
     72 	{
     73 		enum ctor{null};
     74 		typedef __m128 value_type;
     75 		typedef std::size_t size_type;
     76 		static size_type value_size();
     77 
     78 		typedef fquatSIMD type;
     79 		typedef tquat<bool, defaultp> bool_type;
     80 
     81 #ifdef GLM_SIMD_ENABLE_XYZW_UNION
     82         union
     83         {
     84 		    __m128 Data;
     85             struct {float x, y, z, w;};
     86         };
     87 #else
     88         __m128 Data;
     89 #endif
     90 
     91 		//////////////////////////////////////
     92 		// Implicit basic constructors
     93 
     94 		fquatSIMD();
     95 		fquatSIMD(__m128 const & Data);
     96 		fquatSIMD(fquatSIMD const & q);
     97 
     98 		//////////////////////////////////////
     99 		// Explicit basic constructors
    100 
    101 		explicit fquatSIMD(
    102 			ctor);
    103 		explicit fquatSIMD(
    104 			float const & w,
    105 			float const & x,
    106 			float const & y,
    107 			float const & z);
    108 		explicit fquatSIMD(
    109 			quat const & v);
    110         explicit fquatSIMD(
    111 			vec3 const & eulerAngles);
    112 
    113 
    114 		//////////////////////////////////////
    115 		// Unary arithmetic operators
    116 
    117         fquatSIMD& operator =(fquatSIMD const & q);
    118         fquatSIMD& operator*=(float const & s);
    119 		fquatSIMD& operator/=(float const & s);
    120 	};
    121 
    122 
    123     //////////////////////////////////////
    124     // Arithmetic operators
    125 
    126 	detail::fquatSIMD operator- (
    127 		detail::fquatSIMD const & q);
    128 
    129 	detail::fquatSIMD operator+ (
    130 		detail::fquatSIMD const & q,
    131 		detail::fquatSIMD const & p);
    132 
    133 	detail::fquatSIMD operator* (
    134 		detail::fquatSIMD const & q,
    135 		detail::fquatSIMD const & p);
    136 
    137 	detail::fvec4SIMD operator* (
    138 		detail::fquatSIMD const & q,
    139 		detail::fvec4SIMD const & v);
    140 
    141 	detail::fvec4SIMD operator* (
    142 		detail::fvec4SIMD const & v,
    143 		detail::fquatSIMD const & q);
    144 
    145 	detail::fquatSIMD operator* (
    146 		detail::fquatSIMD const & q,
    147 		float s);
    148 
    149 	detail::fquatSIMD operator* (
    150 		float s,
    151 		detail::fquatSIMD const & q);
    152 
    153 	detail::fquatSIMD operator/ (
    154 		detail::fquatSIMD const & q,
    155 		float s);
    156 
    157 }//namespace detail
    158 
    159 	typedef glm::detail::fquatSIMD simdQuat;
    160 
    161 	/// @addtogroup gtx_simd_quat
    162 	/// @{
    163 
    164     //! Convert a simdQuat to a quat.
    165 	//! (From GLM_GTX_simd_quat extension)
    166 	quat quat_cast(
    167 		detail::fquatSIMD const & x);
    168 
    169     //! Convert a simdMat4 to a simdQuat.
    170     //! (From GLM_GTX_simd_quat extension)
    171     detail::fquatSIMD quatSIMD_cast(
    172         detail::fmat4x4SIMD const & m);
    173 
    174     //! Converts a mat4 to a simdQuat.
    175     //! (From GLM_GTX_simd_quat extension)
    176     template <typename T, precision P>
    177     detail::fquatSIMD quatSIMD_cast(
    178         detail::tmat4x4<T, P> const & m);
    179 
    180     //! Converts a mat3 to a simdQuat.
    181     //! (From GLM_GTX_simd_quat extension)
    182     template <typename T, precision P>
    183     detail::fquatSIMD quatSIMD_cast(
    184         detail::tmat3x3<T, P> const & m);
    185 
    186     //! Convert a simdQuat to a simdMat4
    187     //! (From GLM_GTX_simd_quat extension)
    188     detail::fmat4x4SIMD mat4SIMD_cast(
    189         detail::fquatSIMD const & q);
    190 
    191     //! Converts a simdQuat to a standard mat4.
    192     //! (From GLM_GTX_simd_quat extension)
    193     mat4 mat4_cast(
    194         detail::fquatSIMD const & q);
    195 
    196 
    197 	/// Returns the length of the quaternion.
    198 	///
    199 	/// @see gtc_quaternion
    200 	float length(
    201 		detail::fquatSIMD const & x);
    202 
    203 	/// Returns the normalized quaternion.
    204 	///
    205 	/// @see gtc_quaternion
    206 	detail::fquatSIMD normalize(
    207 		detail::fquatSIMD const & x);
    208 
    209     /// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ...
    210 	///
    211 	/// @see gtc_quaternion
    212 	float dot(
    213 		detail::fquatSIMD const & q1,
    214 		detail::fquatSIMD const & q2);
    215 
    216     /// Spherical linear interpolation of two quaternions.
    217 	/// The interpolation is oriented and the rotation is performed at constant speed.
    218 	/// For short path spherical linear interpolation, use the slerp function.
    219 	///
    220 	/// @param x A quaternion
    221 	/// @param y A quaternion
    222 	/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
    223 	/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
    224 	/// @see gtc_quaternion
    225 	/// @see - slerp(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a)
    226 	detail::fquatSIMD mix(
    227 		detail::fquatSIMD const & x,
    228 		detail::fquatSIMD const & y,
    229 		float const & a);
    230 
    231     /// Linear interpolation of two quaternions.
    232 	/// The interpolation is oriented.
    233 	///
    234 	/// @param x A quaternion
    235 	/// @param y A quaternion
    236 	/// @param a Interpolation factor. The interpolation is defined in the range [0, 1].
    237 	/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
    238 	/// @see gtc_quaternion
    239 	detail::fquatSIMD lerp(
    240 		detail::fquatSIMD const & x,
    241 		detail::fquatSIMD const & y,
    242 		float const & a);
    243 
    244 	/// Spherical linear interpolation of two quaternions.
    245 	/// The interpolation always take the short path and the rotation is performed at constant speed.
    246 	///
    247 	/// @param x A quaternion
    248 	/// @param y A quaternion
    249 	/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
    250 	/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
    251 	/// @see gtc_quaternion
    252 	detail::fquatSIMD slerp(
    253 		detail::fquatSIMD const & x,
    254 		detail::fquatSIMD const & y,
    255 		float const & a);
    256 
    257 
    258     /// Faster spherical linear interpolation of two unit length quaternions.
    259     ///
    260     /// This is the same as mix(), except for two rules:
    261     ///   1) The two quaternions must be unit length.
    262     ///   2) The interpolation factor (a) must be in the range [0, 1].
    263     ///
    264     /// This will use the equivalent to fastAcos() and fastSin().
    265     ///
    266 	/// @see gtc_quaternion
    267 	/// @see - mix(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a)
    268 	detail::fquatSIMD fastMix(
    269 		detail::fquatSIMD const & x,
    270 		detail::fquatSIMD const & y,
    271 		float const & a);
    272 
    273     /// Identical to fastMix() except takes the shortest path.
    274     ///
    275     /// The same rules apply here as those in fastMix(). Both quaternions must be unit length and 'a' must be
    276     /// in the range [0, 1].
    277     ///
    278 	/// @see - fastMix(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a)
    279 	/// @see - slerp(detail::fquatSIMD const & x, detail::fquatSIMD const & y, T const & a)
    280     detail::fquatSIMD fastSlerp(
    281 		detail::fquatSIMD const & x,
    282 		detail::fquatSIMD const & y,
    283 		float const & a);
    284 
    285 
    286 	/// Returns the q conjugate.
    287 	///
    288 	/// @see gtc_quaternion
    289 	detail::fquatSIMD conjugate(
    290 		detail::fquatSIMD const & q);
    291 
    292 	/// Returns the q inverse.
    293 	///
    294 	/// @see gtc_quaternion
    295 	detail::fquatSIMD inverse(
    296 		detail::fquatSIMD const & q);
    297 
    298     /// Build a quaternion from an angle and a normalized axis.
    299 	///
    300 	/// @param angle Angle expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
    301 	/// @param axis Axis of the quaternion, must be normalized.
    302 	///
    303 	/// @see gtc_quaternion
    304 	detail::fquatSIMD angleAxisSIMD(
    305 		float const & angle,
    306 		vec3 const & axis);
    307 
    308     /// Build a quaternion from an angle and a normalized axis.
    309 	///
    310 	/// @param angle Angle expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
    311 	/// @param x x component of the x-axis, x, y, z must be a normalized axis
    312 	/// @param y y component of the y-axis, x, y, z must be a normalized axis
    313 	/// @param z z component of the z-axis, x, y, z must be a normalized axis
    314 	///
    315 	/// @see gtc_quaternion
    316 	detail::fquatSIMD angleAxisSIMD(
    317 		float const & angle,
    318 		float const & x,
    319 		float const & y,
    320 		float const & z);
    321 
    322 
    323     // TODO: Move this to somewhere more appropriate. Used with fastMix() and fastSlerp().
    324     /// Performs the equivalent of glm::fastSin() on each component of the given __m128.
    325     __m128 fastSin(__m128 x);
    326 
    327 
    328 	/// @}
    329 }//namespace glm
    330 
    331 #include "simd_quat.inl"
    332 
    333 
    334 #if (GLM_COMPILER & GLM_COMPILER_VC)
    335 #   pragma warning(pop)
    336 #endif
    337 
    338 
    339 #endif//(GLM_ARCH != GLM_ARCH_PURE)
    340 
    341 #endif//GLM_GTX_simd_quat
    342