15d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/* 25d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Copyright 2013 The Android Open Source Project 35d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 45d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 55d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * you may not use this file except in compliance with the License. 65d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * You may obtain a copy of the License at 75d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 85d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 95d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * Unless required by applicable law or agreed to in writing, software 115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * See the License for the specific language governing permissions and 145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * limitations under the License. 155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 171d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#pragma once 185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 191d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#include <math/half.h> 201d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#include <math/TQuatHelpers.h> 211d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#include <math/vec3.h> 221d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#include <math/vec4.h> 235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <stdint.h> 255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <sys/types.h> 265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#ifndef PURE 285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#define PURE __attribute__((pure)) 295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#endif 305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 31caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#pragma clang diagnostic push 32caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#pragma clang diagnostic ignored "-Wgnu-anonymous-struct" 33caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#pragma clang diagnostic ignored "-Wnested-anon-types" 34caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy 355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guynamespace android { 365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ------------------------------------------------------------------------------------- 375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 385d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guynamespace details { 395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <typename T> 415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyclass TQuaternion : public TVecAddOperators<TQuaternion, T>, 425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TVecUnaryOperators<TQuaternion, T>, 435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TVecComparisonOperators<TQuaternion, T>, 445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TQuatProductOperators<TQuaternion, T>, 455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TQuatFunctions<TQuaternion, T>, 465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy public TQuatDebug<TQuaternion, T> { 475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guypublic: 485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy enum no_init { NO_INIT }; 495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef T value_type; 505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef T& reference; 515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef T const& const_reference; 525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy typedef size_t size_type; 535d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 545d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /* 555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * quaternion internals stored as: 565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * q = w + xi + yj + zk 585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 595d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * q[0] = x; 605d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * q[1] = y; 615d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * q[2] = z; 625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * q[3] = w; 635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy union { 665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy struct { T x, y, z, w; }; 675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy TVec4<T> xyzw; 685d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy TVec3<T> xyz; 695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy TVec2<T> xy; 705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy }; 715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy enum { SIZE = 4 }; 735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline constexpr static size_type size() { return SIZE; } 745d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // array access 765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline constexpr T const& operator[](size_t i) const { 775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#if __cplusplus >= 201402L 785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // only possible in C++0x14 with constexpr 795d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy assert(i < SIZE); 805d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#endif 815d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return (&x)[i]; 825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy inline T& operator[](size_t i) { 855d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy assert(i < SIZE); 865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return (&x)[i]; 875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // ----------------------------------------------------------------------- 905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // we want the compiler generated versions for these... 915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy TQuaternion(const TQuaternion&) = default; 925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy ~TQuaternion() = default; 935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy TQuaternion& operator = (const TQuaternion&) = default; 945d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // constructors 965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // leaves object uninitialized. use with caution. 985d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy explicit 995d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr TQuaternion(no_init) : xyzw(TVec4<T>::NO_INIT) {} 1005d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1015d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // default constructor. sets all values to zero. 1025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr TQuaternion() : x(0), y(0), z(0), w(0) { } 1035d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1045d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // handles implicit conversion to a tvec4. must not be explicit. 1055d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename A> 1065d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr TQuaternion(A w) : x(0), y(0), z(0), w(w) { 1075d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy static_assert(std::is_arithmetic<A>::value, "requires arithmetic type"); 1085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // initialize from 4 values to w + xi + yj + zk 1115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename A, typename B, typename C, typename D> 1125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr TQuaternion(A w, B x, C y, D z) : x(x), y(y), z(z), w(w) { } 1135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // initialize from a vec3 + a value to : v.xi + v.yj + v.zk + w 1155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename A, typename B> 1165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr TQuaternion(const TVec3<A>& v, B w) : x(v.x), y(v.y), z(v.z), w(w) { } 1175d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // initialize from a double4 1195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename A> 1205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr explicit TQuaternion(const TVec4<A>& v) : x(v.x), y(v.y), z(v.z), w(v.w) { } 1215d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // initialize from a quaternion of a different type 1235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename A> 1245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr explicit TQuaternion(const TQuaternion<A>& v) : x(v.x), y(v.y), z(v.z), w(v.w) { } 1255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // conjugate operator 1275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr TQuaternion operator~() const { 1285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return conj(*this); 1295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1315d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // constructs a quaternion from an axis and angle 1325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template <typename A, typename B> 1335d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr static TQuaternion PURE fromAxisAngle(const TVec3<A>& axis, B angle) { 1345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return TQuaternion(std::sin(angle*0.5) * normalize(axis), std::cos(angle*0.5)); 1355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 1365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy}; 1375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1385d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace details 1395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ---------------------------------------------------------------------------------------- 1415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytypedef details::TQuaternion<double> quatd; 1435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytypedef details::TQuaternion<float> quat; 1445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytypedef details::TQuaternion<float> quatf; 1455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytypedef details::TQuaternion<half> quath; 1465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quat operator"" _i(long double v) { 148caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quat(0, static_cast<float>(v), 0, 0); 1495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quat operator"" _j(long double v) { 151caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quat(0, 0, static_cast<float>(v), 0); 1525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1535d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quat operator"" _k(long double v) { 154caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quat(0, 0, 0, static_cast<float>(v)); 1555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quat operator"" _i(unsigned long long v) { // NOLINT 158caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quat(0, static_cast<float>(v), 0, 0); 1595d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1605d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quat operator"" _j(unsigned long long v) { // NOLINT 161caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quat(0, 0, static_cast<float>(v), 0); 1625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quat operator"" _k(unsigned long long v) { // NOLINT 164caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quat(0, 0, 0, static_cast<float>(v)); 1655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quatd operator"" _id(long double v) { 168caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quatd(0, static_cast<double>(v), 0, 0); 1695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quatd operator"" _jd(long double v) { 171caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quatd(0, 0, static_cast<double>(v), 0); 1725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quatd operator"" _kd(long double v) { 174caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quatd(0, 0, 0, static_cast<double>(v)); 1755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quatd operator"" _id(unsigned long long v) { // NOLINT 178caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quatd(0, static_cast<double>(v), 0, 0); 1795d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1805d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quatd operator"" _jd(unsigned long long v) { // NOLINT 181caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quatd(0, 0, static_cast<double>(v), 0); 1825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyconstexpr inline quatd operator"" _kd(unsigned long long v) { // NOLINT 184caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return quatd(0, 0, 0, static_cast<double>(v)); 1855d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} 1865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 1875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy// ---------------------------------------------------------------------------------------- 1885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace android 1895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 190caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#pragma clang diagnostic pop 191caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy 1925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#undef PURE 193