MAV'RIC
|
00001 /******************************************************************************* 00002 * Copyright (c) 2009-2016, MAV'RIC Development Team 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * 1. Redistributions of source code must retain the above copyright notice, 00009 * this list of conditions and the following disclaimer. 00010 * 00011 * 2. Redistributions in binary form must reproduce the above copyright notice, 00012 * this list of conditions and the following disclaimer in the documentation 00013 * and/or other materials provided with the distribution. 00014 * 00015 * 3. Neither the name of the copyright holder nor the names of its contributors 00016 * may be used to endorse or promote products derived from this software without 00017 * specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00029 * POSSIBILITY OF SUCH DAMAGE. 00030 ******************************************************************************/ 00031 00032 /******************************************************************************* 00033 * \file quaternions.h 00034 * 00035 * \author MAV'RIC Team 00036 * \author Felix Schill 00037 * \author Geraud L'Eplattenier 00038 * 00039 * \brief Useful functions for quaternions 00040 * 00041 ******************************************************************************/ 00042 00043 00044 #ifndef QUATERNIONS_H_ 00045 #define QUATERNIONS_H_ 00046 00047 #include <stdint.h> 00048 #include "util/maths.h" 00049 #include "util/vectors.h" 00050 00051 00057 typedef struct 00058 { 00059 float s; 00060 float v[3]; 00061 } quat_t; 00062 00063 00069 static inline quat_t quaternions_create(float s, float vx, float vy, float vz) 00070 { 00071 quat_t quat; 00072 quat.s = s; 00073 quat.v[0] = vx; 00074 quat.v[1] = vy; 00075 quat.v[2] = vz; 00076 00077 return quat; 00078 } 00079 00087 #define QI(q, out) \ 00088 out.s = q.s;\ 00089 out.v[0] = -q.v[0];\ 00090 out.v[1] = -q.v[1];\ 00091 out.v[2] = -q.v[2]; 00092 00093 00103 #define QUAT(q, s, v0, v1, v2) \ 00104 q.s = s;\ 00105 q.v[0] = v0;\ 00106 q.v[1] = v1;\ 00107 q.v[2] = v2; 00108 00109 00117 quat_t static inline quaternions_create_from_vector(float v[3]) 00118 { 00119 quat_t q; 00120 q.s = 0; 00121 q.v[0] = v[0]; 00122 q.v[1] = v[1]; 00123 q.v[2] = v[2]; 00124 return q; 00125 } 00126 00127 00135 #define QMUL(q1,q2,out) \ 00136 tmp[0] = q1.v[1] * q2.v[2] - q1.v[2] * q2.v[1];\ 00137 tmp[1] = q1.v[2] * q2.v[0] - q1.v[0] * q2.v[2];\ 00138 tmp[2] = q1.v[0] * q2.v[1] - q1.v[1] * q2.v[0];\ 00139 out.v[0] = q2.s* q1.v[0] + q1.s * q2.v[0] + tmp[0];\ 00140 out.v[1] = q2.s* q1.v[1] + q1.s * q2.v[1] + tmp[1];\ 00141 out.v[2] = q2.s* q1.v[2] + q1.s * q2.v[2] + tmp[2];\ 00142 out.s= q1.s * q2.s - SCP(q1.v, q2.v); 00143 00144 00153 quat_t static inline quaternions_multiply(const quat_t q1, const quat_t q2) 00154 { 00155 float tmp[3]; 00156 quat_t out; 00157 00158 tmp[0] = q1.v[1] * q2.v[2] - q1.v[2] * q2.v[1]; 00159 tmp[1] = q1.v[2] * q2.v[0] - q1.v[0] * q2.v[2]; 00160 tmp[2] = q1.v[0] * q2.v[1] - q1.v[1] * q2.v[0]; 00161 00162 out.v[0] = q2.s * q1.v[0] + q1.s * q2.v[0] + tmp[0]; 00163 out.v[1] = q2.s * q1.v[1] + q1.s * q2.v[1] + tmp[1]; 00164 out.v[2] = q2.s * q1.v[2] + q1.s * q2.v[2] + tmp[2]; 00165 out.s = q1.s * q2.s - vectors_scalar_product(q1.v, q2.v); 00166 00167 return out; 00168 } 00169 00170 00177 quat_t static inline quaternions_inverse(const quat_t q) 00178 { 00179 quat_t qinv; 00180 qinv.s = q.s; 00181 00182 for (int32_t i = 0; i < 3; i++) 00183 { 00184 qinv.v[i] = -q.v[i]; 00185 } 00186 00187 return qinv; 00188 } 00189 00190 00199 quat_t static inline quaternions_rotate(const quat_t qi, const quat_t qrot) 00200 { 00201 quat_t qinv, qtmp; 00202 00203 qinv = quaternions_inverse(qrot); 00204 qtmp = quaternions_multiply(qinv, qi); 00205 qtmp = quaternions_multiply(qtmp, qrot); 00206 00207 return qtmp; 00208 } 00209 00210 00221 quat_t static inline quaternions_global_to_local(const quat_t qe, const quat_t qvect) 00222 { 00223 quat_t qinv, qtmp; 00224 00225 qinv = quaternions_inverse(qe); 00226 qtmp = quaternions_multiply(qinv, qvect); 00227 qtmp = quaternions_multiply(qtmp, qe); 00228 00229 return qtmp; 00230 } 00231 00232 00243 quat_t static inline quaternions_local_to_global(const quat_t qe, const quat_t qvect) 00244 { 00245 quat_t qinv, qtmp; 00246 00247 qinv = quaternions_inverse(qe); 00248 qtmp = quaternions_multiply(qe, qvect); 00249 qtmp = quaternions_multiply(qtmp, qinv); 00250 00251 return qtmp; 00252 } 00253 00254 00266 void static inline quaternions_rotate_vector(const quat_t q, const float u[3], float v[3]) 00267 { 00268 float tmp1[3], tmp2[3]; 00269 00270 vectors_cross_product(q.v, u, tmp1); 00271 tmp1[0] = 2 * tmp1[0]; 00272 tmp1[1] = 2 * tmp1[1]; 00273 tmp1[2] = 2 * tmp1[2]; 00274 00275 vectors_cross_product(q.v, tmp1, tmp2); 00276 00277 v[0] = u[0] + q.s * tmp1[0] + tmp2[0]; 00278 v[1] = u[1] + q.s * tmp1[1] + tmp2[1]; 00279 v[2] = u[2] + q.s * tmp1[2] + tmp2[2]; 00280 } 00281 00282 00289 static inline quat_t quaternions_normalise(const quat_t q) 00290 { 00291 quat_t result; 00292 00293 float snorm = SQR(q.s) + SQR(q.v[0]) + SQR(q.v[1]) + SQR(q.v[2]); 00294 00295 if (snorm > 0.0000001f) 00296 { 00297 float norm = maths_fast_sqrt(snorm); 00298 result.s = q.s / norm; 00299 result.v[0] = q.v[0] / norm; 00300 result.v[1] = q.v[1] / norm; 00301 result.v[2] = q.v[2] / norm; 00302 } 00303 else 00304 { 00305 result.s = 1.0f; 00306 result.v[0] = 0.0f; 00307 result.v[1] = 0.0f; 00308 result.v[2] = 0.0f; 00309 } 00310 00311 return result; 00312 } 00313 00314 00315 #endif /* QUATERNIONS_H_ */