1 /* 2 * Copyright 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18 #pragma once 19 20 #include <math.h> 21 #include <stdint.h> 22 #include <sys/types.h> 23 24 #include <iostream> 25 26 #include <math/vec3.h> 27 28 #define PURE __attribute__((pure)) 29 30 namespace android { 31 namespace details { 32 // ------------------------------------------------------------------------------------- 33 34 /* 35 * No user serviceable parts here. 36 * 37 * Don't use this file directly, instead include ui/quat.h 38 */ 39 40 41 /* 42 * TQuatProductOperators implements basic arithmetic and basic compound assignment 43 * operators on a quaternion of type BASE<T>. 44 * 45 * BASE only needs to implement operator[] and size(). 46 * By simply inheriting from TQuatProductOperators<BASE, T> BASE will automatically 47 * get all the functionality here. 48 */ 49 50 template <template<typename T> class QUATERNION, typename T> 51 class TQuatProductOperators { 52 public: 53 /* compound assignment from a another quaternion of the same size but different 54 * element type. 55 */ 56 template <typename OTHER> 57 QUATERNION<T>& operator *= (const QUATERNION<OTHER>& r) { 58 QUATERNION<T>& q = static_cast<QUATERNION<T>&>(*this); 59 q = q * r; 60 return q; 61 } 62 63 /* compound assignment products by a scalar 64 */ 65 QUATERNION<T>& operator *= (T v) { 66 QUATERNION<T>& lhs = static_cast<QUATERNION<T>&>(*this); 67 for (size_t i = 0; i < QUATERNION<T>::size(); i++) { 68 lhs[i] *= v; 69 } 70 return lhs; 71 } 72 QUATERNION<T>& operator /= (T v) { 73 QUATERNION<T>& lhs = static_cast<QUATERNION<T>&>(*this); 74 for (size_t i = 0; i < QUATERNION<T>::size(); i++) { 75 lhs[i] /= v; 76 } 77 return lhs; 78 } 79 80 /* 81 * NOTE: the functions below ARE NOT member methods. They are friend functions 82 * with they definition inlined with their declaration. This makes these 83 * template functions available to the compiler when (and only when) this class 84 * is instantiated, at which point they're only templated on the 2nd parameter 85 * (the first one, BASE<T> being known). 86 */ 87 88 /* The operators below handle operation between quaternion of the same size 89 * but of a different element type. 90 */ 91 template<typename RT> 92 friend inline 93 constexpr QUATERNION<T> PURE operator *(const QUATERNION<T>& q, const QUATERNION<RT>& r) { 94 // could be written as: 95 // return QUATERNION<T>( 96 // q.w*r.w - dot(q.xyz, r.xyz), 97 // q.w*r.xyz + r.w*q.xyz + cross(q.xyz, r.xyz)); 98 99 return QUATERNION<T>( 100 q.w*r.w - q.x*r.x - q.y*r.y - q.z*r.z, 101 q.w*r.x + q.x*r.w + q.y*r.z - q.z*r.y, 102 q.w*r.y - q.x*r.z + q.y*r.w + q.z*r.x, 103 q.w*r.z + q.x*r.y - q.y*r.x + q.z*r.w); 104 } 105 106 template<typename RT> 107 friend inline 108 constexpr TVec3<T> PURE operator *(const QUATERNION<T>& q, const TVec3<RT>& v) { 109 // note: if q is known to be a unit quaternion, then this simplifies to: 110 // TVec3<T> t = 2 * cross(q.xyz, v) 111 // return v + (q.w * t) + cross(q.xyz, t) 112 return imaginary(q * QUATERNION<T>(v, 0) * inverse(q)); 113 } 114 115 116 /* For quaternions, we use explicit "by a scalar" products because it's much faster 117 * than going (implicitly) through the quaternion multiplication. 118 * For reference: we could use the code below instead, but it would be a lot slower. 119 * friend inline 120 * constexpr BASE<T> PURE operator *(const BASE<T>& q, const BASE<T>& r) { 121 * return BASE<T>( 122 * q.w*r.w - q.x*r.x - q.y*r.y - q.z*r.z, 123 * q.w*r.x + q.x*r.w + q.y*r.z - q.z*r.y, 124 * q.w*r.y - q.x*r.z + q.y*r.w + q.z*r.x, 125 * q.w*r.z + q.x*r.y - q.y*r.x + q.z*r.w); 126 * 127 */ 128 friend inline 129 constexpr QUATERNION<T> PURE operator *(QUATERNION<T> q, T scalar) { 130 // don't pass q by reference because we need a copy anyways 131 return q *= scalar; 132 } 133 friend inline 134 constexpr QUATERNION<T> PURE operator *(T scalar, QUATERNION<T> q) { 135 // don't pass q by reference because we need a copy anyways 136 return q *= scalar; 137 } 138 139 friend inline 140 constexpr QUATERNION<T> PURE operator /(QUATERNION<T> q, T scalar) { 141 // don't pass q by reference because we need a copy anyways 142 return q /= scalar; 143 } 144 }; 145 146 147 /* 148 * TQuatFunctions implements functions on a quaternion of type BASE<T>. 149 * 150 * BASE only needs to implement operator[] and size(). 151 * By simply inheriting from TQuatFunctions<BASE, T> BASE will automatically 152 * get all the functionality here. 153 */ 154 template <template<typename T> class QUATERNION, typename T> 155 class TQuatFunctions { 156 public: 157 /* 158 * NOTE: the functions below ARE NOT member methods. They are friend functions 159 * with they definition inlined with their declaration. This makes these 160 * template functions available to the compiler when (and only when) this class 161 * is instantiated, at which point they're only templated on the 2nd parameter 162 * (the first one, BASE<T> being known). 163 */ 164 165 template<typename RT> 166 friend inline dot(const QUATERNION<T> & p,const QUATERNION<RT> & q)167 constexpr T PURE dot(const QUATERNION<T>& p, const QUATERNION<RT>& q) { 168 return p.x * q.x + 169 p.y * q.y + 170 p.z * q.z + 171 p.w * q.w; 172 } 173 174 friend inline norm(const QUATERNION<T> & q)175 constexpr T PURE norm(const QUATERNION<T>& q) { 176 return std::sqrt( dot(q, q) ); 177 } 178 179 friend inline length(const QUATERNION<T> & q)180 constexpr T PURE length(const QUATERNION<T>& q) { 181 return norm(q); 182 } 183 184 friend inline length2(const QUATERNION<T> & q)185 constexpr T PURE length2(const QUATERNION<T>& q) { 186 return dot(q, q); 187 } 188 189 friend inline normalize(const QUATERNION<T> & q)190 constexpr QUATERNION<T> PURE normalize(const QUATERNION<T>& q) { 191 return length(q) ? q / length(q) : QUATERNION<T>(1); 192 } 193 194 friend inline conj(const QUATERNION<T> & q)195 constexpr QUATERNION<T> PURE conj(const QUATERNION<T>& q) { 196 return QUATERNION<T>(q.w, -q.x, -q.y, -q.z); 197 } 198 199 friend inline inverse(const QUATERNION<T> & q)200 constexpr QUATERNION<T> PURE inverse(const QUATERNION<T>& q) { 201 return conj(q) * (1 / dot(q, q)); 202 } 203 204 friend inline real(const QUATERNION<T> & q)205 constexpr T PURE real(const QUATERNION<T>& q) { 206 return q.w; 207 } 208 209 friend inline imaginary(const QUATERNION<T> & q)210 constexpr TVec3<T> PURE imaginary(const QUATERNION<T>& q) { 211 return q.xyz; 212 } 213 214 friend inline unreal(const QUATERNION<T> & q)215 constexpr QUATERNION<T> PURE unreal(const QUATERNION<T>& q) { 216 return QUATERNION<T>(q.xyz, 0); 217 } 218 219 friend inline cross(const QUATERNION<T> & p,const QUATERNION<T> & q)220 constexpr QUATERNION<T> PURE cross(const QUATERNION<T>& p, const QUATERNION<T>& q) { 221 return unreal(p*q); 222 } 223 224 friend inline exp(const QUATERNION<T> & q)225 QUATERNION<T> PURE exp(const QUATERNION<T>& q) { 226 const T nq(norm(q.xyz)); 227 return std::exp(q.w)*QUATERNION<T>((sin(nq)/nq)*q.xyz, cos(nq)); 228 } 229 230 friend inline log(const QUATERNION<T> & q)231 QUATERNION<T> PURE log(const QUATERNION<T>& q) { 232 const T nq(norm(q)); 233 return QUATERNION<T>((std::acos(q.w/nq)/norm(q.xyz))*q.xyz, log(nq)); 234 } 235 236 friend inline pow(const QUATERNION<T> & q,T a)237 QUATERNION<T> PURE pow(const QUATERNION<T>& q, T a) { 238 // could also be computed as: exp(a*log(q)); 239 const T nq(norm(q)); 240 const T theta(a*std::acos(q.w / nq)); 241 return std::pow(nq, a) * QUATERNION<T>(normalize(q.xyz) * std::sin(theta), std::cos(theta)); 242 } 243 244 friend inline slerp(const QUATERNION<T> & p,const QUATERNION<T> & q,T t)245 QUATERNION<T> PURE slerp(const QUATERNION<T>& p, const QUATERNION<T>& q, T t) { 246 // could also be computed as: pow(q * inverse(p), t) * p; 247 const T d = dot(p, q); 248 const T npq = sqrt(dot(p, p) * dot(q, q)); // ||p|| * ||q|| 249 const T a = std::acos(std::abs(d) / npq); 250 const T a0 = a * (1 - t); 251 const T a1 = a * t; 252 const T isina = 1 / sin(a); 253 const T s0 = std::sin(a0) * isina; 254 const T s1 = std::sin(a1) * isina; 255 // ensure we're taking the "short" side 256 return normalize(s0 * p + ((d < 0) ? (-s1) : (s1)) * q); 257 } 258 259 friend inline lerp(const QUATERNION<T> & p,const QUATERNION<T> & q,T t)260 constexpr QUATERNION<T> PURE lerp(const QUATERNION<T>& p, const QUATERNION<T>& q, T t) { 261 return ((1 - t) * p) + (t * q); 262 } 263 264 friend inline nlerp(const QUATERNION<T> & p,const QUATERNION<T> & q,T t)265 constexpr QUATERNION<T> PURE nlerp(const QUATERNION<T>& p, const QUATERNION<T>& q, T t) { 266 return normalize(lerp(p, q, t)); 267 } 268 269 friend inline positive(const QUATERNION<T> & q)270 constexpr QUATERNION<T> PURE positive(const QUATERNION<T>& q) { 271 return q.w < 0 ? -q : q; 272 } 273 }; 274 275 /* 276 * TQuatDebug implements functions on a vector of type BASE<T>. 277 * 278 * BASE only needs to implement operator[] and size(). 279 * By simply inheriting from TQuatDebug<BASE, T> BASE will automatically 280 * get all the functionality here. 281 */ 282 template <template<typename T> class QUATERNION, typename T> 283 class TQuatDebug { 284 public: 285 /* 286 * NOTE: the functions below ARE NOT member methods. They are friend functions 287 * with they definition inlined with their declaration. This makes these 288 * template functions available to the compiler when (and only when) this class 289 * is instantiated, at which point they're only templated on the 2nd parameter 290 * (the first one, BASE<T> being known). 291 */ 292 friend std::ostream& operator<< (std::ostream& stream, const QUATERNION<T>& q) { 293 return stream << "< " << q.w << " + " << q.x << "i + " << q.y << "j + " << q.z << "k >"; 294 } 295 }; 296 #undef PURE 297 298 // ------------------------------------------------------------------------------------- 299 } // namespace details 300 } // namespace android 301